< prev index next >
src/java.base/share/classes/java/util/jar/JarFile.java
Print this page
rev 15578 : 8165723: JarFile::isMultiRelease() method returns false when it should return true
Reviewed-by: alanb
@@ -834,34 +834,46 @@
// Statics for hand-coded Boyer-Moore search
private static final byte[] CLASSPATH_CHARS =
{'C','L','A','S','S','-','P','A','T','H', ':', ' '};
- // The bad character shift for "class-path:"
+ // The bad character shift for "class-path: "
private static final byte[] CLASSPATH_LASTOCC;
+ // The good suffix shift for "class-path: "
+ private static final byte[] CLASSPATH_OPTOSFT;
+
private static final byte[] MULTIRELEASE_CHARS =
{'M','U','L','T','I','-','R','E','L','E', 'A', 'S', 'E', ':',
' ', 'T', 'R', 'U', 'E'};
- // The bad character shift for "multi-release: "
+ // The bad character shift for "multi-release: true"
private static final byte[] MULTIRELEASE_LASTOCC;
+ // The good suffix shift for "multi-release: true"
+ private static final byte[] MULTIRELEASE_OPTOSFT;
+
static {
CLASSPATH_LASTOCC = new byte[64];
+ CLASSPATH_OPTOSFT = new byte[12];
CLASSPATH_LASTOCC[(int)'C' - 32] = 1;
CLASSPATH_LASTOCC[(int)'L' - 32] = 2;
CLASSPATH_LASTOCC[(int)'S' - 32] = 5;
CLASSPATH_LASTOCC[(int)'-' - 32] = 6;
CLASSPATH_LASTOCC[(int)'P' - 32] = 7;
CLASSPATH_LASTOCC[(int)'A' - 32] = 8;
CLASSPATH_LASTOCC[(int)'T' - 32] = 9;
CLASSPATH_LASTOCC[(int)'H' - 32] = 10;
CLASSPATH_LASTOCC[(int)':' - 32] = 11;
CLASSPATH_LASTOCC[(int)' ' - 32] = 12;
+ for (int i = 0; i < 11; i++) {
+ CLASSPATH_OPTOSFT[i] = 12;
+ }
+ CLASSPATH_OPTOSFT[11] = 1;
MULTIRELEASE_LASTOCC = new byte[64];
+ MULTIRELEASE_OPTOSFT = new byte[19];
MULTIRELEASE_LASTOCC[(int)'M' - 32] = 1;
MULTIRELEASE_LASTOCC[(int)'I' - 32] = 5;
MULTIRELEASE_LASTOCC[(int)'-' - 32] = 6;
MULTIRELEASE_LASTOCC[(int)'L' - 32] = 9;
MULTIRELEASE_LASTOCC[(int)'A' - 32] = 11;
@@ -870,10 +882,15 @@
MULTIRELEASE_LASTOCC[(int)' ' - 32] = 15;
MULTIRELEASE_LASTOCC[(int)'T' - 32] = 16;
MULTIRELEASE_LASTOCC[(int)'R' - 32] = 17;
MULTIRELEASE_LASTOCC[(int)'U' - 32] = 18;
MULTIRELEASE_LASTOCC[(int)'E' - 32] = 19;
+ for (int i = 0; i < 17; i++) {
+ MULTIRELEASE_OPTOSFT[i] = 19;
+ }
+ MULTIRELEASE_OPTOSFT[17] = 6;
+ MULTIRELEASE_OPTOSFT[18] = 1;
}
private JarEntry getManEntry() {
if (manEntry == null) {
// First look up manifest entry using standard name
@@ -911,11 +928,11 @@
* Returns true if the pattern {@code src} is found in {@code b}.
* The {@code lastOcc} array is the precomputed bad character shifts.
* Since there are no repeated substring in our search strings,
* the good suffix shifts can be replaced with a comparison.
*/
- private int match(byte[] src, byte[] b, byte[] lastOcc) {
+ private int match(byte[] src, byte[] b, byte[] lastOcc, byte[] optoSft) {
int len = src.length;
int last = b.length - len;
int i = 0;
next:
while (i <= last) {
@@ -924,13 +941,12 @@
if (c >= ' ' && c <= 'z') {
if (c >= 'a') c -= 32; // Canonicalize
if (c != src[j]) {
// no match
- int goodShift = (j < len - 1) ? len : 1;
int badShift = lastOcc[c - 32];
- i += Math.max(j + 1 - badShift, goodShift);
+ i += Math.max(j + 1 - badShift, optoSft[j]);
continue next;
}
} else {
// no match, character not valid for name
i += len;
@@ -956,14 +972,15 @@
}
JarEntry manEntry = getManEntry();
if (manEntry != null) {
byte[] b = getBytes(manEntry);
hasClassPathAttribute = match(CLASSPATH_CHARS, b,
- CLASSPATH_LASTOCC) != -1;
+ CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT) != -1;
// is this a multi-release jar file
if (MULTI_RELEASE_ENABLED) {
- int i = match(MULTIRELEASE_CHARS, b, MULTIRELEASE_LASTOCC);
+ int i = match(MULTIRELEASE_CHARS, b, MULTIRELEASE_LASTOCC,
+ MULTIRELEASE_OPTOSFT);
if (i != -1) {
i += MULTIRELEASE_CHARS.length;
if (i < b.length) {
byte c = b[i++];
// Check that the value is followed by a newline
< prev index next >