< prev index next >
src/java.base/share/classes/java/util/jar/JarFile.java
Print this page
rev 16859 : 8176709: JarFileSystem::isMultiReleaseJar is incorrect
Reviewed-by: mchung, psandoz, sherman
@@ -34,10 +34,11 @@
import java.util.zip.*;
import java.security.CodeSigner;
import java.security.cert.Certificate;
import java.security.CodeSource;
import jdk.internal.misc.SharedSecrets;
+import jdk.internal.util.jar.JarAttributes;
import sun.security.action.GetPropertyAction;
import sun.security.util.ManifestEntryVerifier;
import sun.security.util.SignatureFileVerifier;
/**
@@ -825,69 +826,10 @@
return ((JarFileEntry)ze).realEntry();
}
return (JarEntry)ze;
}
- // 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: "
- 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: 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;
- MULTIRELEASE_LASTOCC[(int)'S' - 32] = 12;
- MULTIRELEASE_LASTOCC[(int)':' - 32] = 14;
- 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
ZipEntry manEntry = super.getEntry(MANIFEST_NAME);
if (manEntry == null) {
@@ -917,43 +859,10 @@
boolean hasClassPathAttribute() throws IOException {
checkForSpecialAttributes();
return hasClassPathAttribute;
}
- /**
- * 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, byte[] optoSft) {
- int len = src.length;
- int last = b.length - len;
- int i = 0;
- next:
- while (i <= last) {
- for (int j = (len - 1); j >= 0; j--) {
- byte c = b[i + j];
- if (c >= ' ' && c <= 'z') {
- if (c >= 'a') c -= 32; // Canonicalize
-
- if (c != src[j]) {
- // no match
- int badShift = lastOcc[c - 32];
- i += Math.max(j + 1 - badShift, optoSft[j]);
- continue next;
- }
- } else {
- // no match, character not valid for name
- i += len;
- continue next;
- }
- }
- return i;
- }
- return -1;
- }
/**
* On first invocation, check if the JAR file has the Class-Path
* and the Multi-Release attribute. A no-op on subsequent calls.
*/
@@ -966,41 +875,14 @@
return;
}
JarEntry manEntry = getManEntry();
if (manEntry != null) {
byte[] b = getBytes(manEntry);
- hasClassPathAttribute = match(CLASSPATH_CHARS, b,
- CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT) != -1;
+ hasClassPathAttribute = JarAttributes.hasClassPathAttribute(b);
// is this a multi-release jar file
if (MULTI_RELEASE_ENABLED) {
- 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
- // and does not have a continuation
- if (c == '\n' &&
- (i == b.length || b[i] != ' ')) {
- isMultiRelease = true;
- } else if (c == '\r') {
- if (i == b.length) {
- isMultiRelease = true;
- } else {
- c = b[i++];
- if (c == '\n') {
- if (i == b.length || b[i] != ' ') {
- isMultiRelease = true;
- }
- } else if (c != ' ') {
- isMultiRelease = true;
- }
- }
- }
- }
- }
+ isMultiRelease = JarAttributes.isMultiRelease(b);
}
}
hasCheckedSpecialAttributes = true;
}
}
< prev index next >