< prev index next >

src/java.base/share/classes/java/util/zip/ZipFile.java

Print this page
rev 59204 : imported patch jarf_signature

*** 43,52 **** --- 43,54 ---- import java.util.Collections; import java.util.Deque; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; + import java.util.List; + import java.util.Locale; import java.util.Objects; import java.util.NoSuchElementException; import java.util.Set; import java.util.Spliterator; import java.util.Spliterators;
*** 1008,1040 **** } } /** ! * Returns the names of all non-directory entries that begin with ! * "META-INF/" (case ignored). This method is used in JarFile, via ! * SharedSecrets, as an optimization when looking up manifest and ! * signature file entries. Returns null if no entries were found. */ ! private String[] getMetaInfEntryNames() { synchronized (this) { ensureOpen(); Source zsrc = res.zsrc; ! if (zsrc.metanames == null) { ! return null; } - String[] names = new String[zsrc.metanames.length]; - byte[] cen = zsrc.cen; - for (int i = 0; i < names.length; i++) { - int pos = zsrc.metanames[i]; - // This will only be invoked on JarFile, which is guaranteed - // to use (or be compatible with) UTF-8 encoding. - names[i] = new String(cen, pos + CENHDR, CENNAM(cen, pos), - UTF_8.INSTANCE); } ! return names; } } /** * Returns the versions for which there exists a non-directory * entry that begin with "META-INF/versions/" (case ignored). --- 1010,1062 ---- } } /** ! * Returns the names of the META-INF/MANIFEST.MF entry - if exists - ! * and any signature-related files under META-INF. This method is used in ! * JarFile, via SharedSecrets, as an optimization. */ ! private List<String> getManifestAndSignatureRelatedFiles() { synchronized (this) { ensureOpen(); Source zsrc = res.zsrc; ! int[] metanames = zsrc.signatureMetaNames; ! List<String> files = null; ! if (zsrc.manifestPos >= 0) { ! files = new ArrayList<>(); ! files.add(getEntryName(zsrc.manifestPos)); ! } ! if (metanames != null) { ! if (files == null) { ! files = new ArrayList<>(); ! } ! for (int i = 0; i < metanames.length; i++) { ! files.add(getEntryName(metanames[i])); ! } ! } ! return files == null ? List.of() : files; } } ! ! /** ! * Returns the name of the META-INF/MANIFEST.MF entry, ignoring ! * case. If {@code onlyIfSignatureRelatedFiles} is true, we only return the ! * manifest if there is also at least one signature-related file. ! * This method is used in JarFile, via SharedSecrets, as an optimization ! * when looking up the manifest file. ! */ ! private String getManifestName(boolean onlyIfSignatureRelatedFiles) { ! synchronized (this) { ! ensureOpen(); ! Source zsrc = res.zsrc; ! int pos = zsrc.manifestPos; ! if (pos >= 0 && (!onlyIfSignatureRelatedFiles || zsrc.signatureMetaNames != null)) { ! return getEntryName(pos); ! } } + return null; } /** * Returns the versions for which there exists a non-directory * entry that begin with "META-INF/versions/" (case ignored).
*** 1057,1068 **** @Override public boolean startsWithLocHeader(ZipFile zip) { return zip.res.zsrc.startsWithLoc; } @Override ! public String[] getMetaInfEntryNames(JarFile jar) { ! return ((ZipFile)jar).getMetaInfEntryNames(); } @Override public int[] getMetaInfVersions(JarFile jar) { return ((ZipFile)jar).getMetaInfVersions(); } --- 1079,1094 ---- @Override public boolean startsWithLocHeader(ZipFile zip) { return zip.res.zsrc.startsWithLoc; } @Override ! public List<String> getManifestAndSignatureRelatedFiles(JarFile jar) { ! return ((ZipFile)jar).getManifestAndSignatureRelatedFiles(); ! } ! @Override ! public String getManifestName(JarFile jar, boolean onlyIfHasSignatureRelatedFiles) { ! return ((ZipFile)jar).getManifestName(onlyIfHasSignatureRelatedFiles); } @Override public int[] getMetaInfVersions(JarFile jar) { return ((ZipFile)jar).getMetaInfVersions(); }
*** 1103,1113 **** private RandomAccessFile zfile; // zfile of the underlying zip file private byte[] cen; // CEN & ENDHDR private long locpos; // position of first LOC header (usually 0) private byte[] comment; // zip file comment // list of meta entries in META-INF dir ! private int[] metanames; private int[] metaVersions; // list of unique versions found in META-INF/versions/ private final boolean startsWithLoc; // true, if zip file starts with LOCSIG (usually true) // A Hashmap for all entries. // --- 1129,1140 ---- private RandomAccessFile zfile; // zfile of the underlying zip file private byte[] cen; // CEN & ENDHDR private long locpos; // position of first LOC header (usually 0) private byte[] comment; // zip file comment // list of meta entries in META-INF dir ! private int manifestPos = -1; // position of the META-INF/MANIFEST.MF, if exists ! private int[] signatureMetaNames; // positions of signature related entries, if such exist private int[] metaVersions; // list of unique versions found in META-INF/versions/ private final boolean startsWithLoc; // true, if zip file starts with LOCSIG (usually true) // A Hashmap for all entries. //
*** 1252,1262 **** zfile.close(); zfile = null; cen = null; entries = null; table = null; ! metanames = null; metaVersions = EMPTY_META_VERSIONS; } private static final int BUF_SIZE = 8192; private final int readFullyAt(byte[] buf, int off, int len, long pos) --- 1279,1290 ---- zfile.close(); zfile = null; cen = null; entries = null; table = null; ! manifestPos = -1; ! signatureMetaNames = null; metaVersions = EMPTY_META_VERSIONS; } private static final int BUF_SIZE = 8192; private final int readFullyAt(byte[] buf, int off, int len, long pos)
*** 1436,1446 **** int idx = 0; int hash; int next; // list for all meta entries ! ArrayList<Integer> metanamesList = null; // Set of all version numbers seen in META-INF/versions/ Set<Integer> metaVersionsSet = null; // Iterate through the entries in the central directory int i = 0; --- 1464,1474 ---- int idx = 0; int hash; int next; // list for all meta entries ! ArrayList<Integer> signatureNames = null; // Set of all version numbers seen in META-INF/versions/ Set<Integer> metaVersionsSet = null; // Iterate through the entries in the central directory int i = 0;
*** 1474,1486 **** next = table[hsh]; table[hsh] = idx; idx = addEntry(idx, hash, next, pos); // Adds name to metanames. if (isMetaName(cen, entryPos, nlen)) { ! if (metanamesList == null) ! metanamesList = new ArrayList<>(4); ! metanamesList.add(pos); // If this is a versioned entry, parse the version // and store it for later. This optimizes lookup // performance in multi-release jar files int version = getMetaVersion(cen, --- 1502,1520 ---- next = table[hsh]; table[hsh] = idx; idx = addEntry(idx, hash, next, pos); // Adds name to metanames. if (isMetaName(cen, entryPos, nlen)) { ! if (isManifestName(cen, entryPos + META_INF_LENGTH, ! nlen - META_INF_LENGTH)) { ! manifestPos = entryPos; ! } else { ! if (isSignatureRelated(cen, entryPos, nlen)) { ! if (signatureNames == null) ! signatureNames = new ArrayList<>(4); ! signatureNames.add(pos); ! } // If this is a versioned entry, parse the version // and store it for later. This optimizes lookup // performance in multi-release jar files int version = getMetaVersion(cen,
*** 1489,1508 **** if (metaVersionsSet == null) metaVersionsSet = new TreeSet<>(); metaVersionsSet.add(version); } } // skip ext and comment pos = entryPos + nlen + elen + clen; entryPos = pos + CENHDR; i++; } total = i; ! if (metanamesList != null) { ! metanames = new int[metanamesList.size()]; ! for (int j = 0, len = metanames.length; j < len; j++) { ! metanames[j] = metanamesList.get(j); } } if (metaVersionsSet != null) { metaVersions = new int[metaVersionsSet.size()]; int c = 0; --- 1523,1544 ---- if (metaVersionsSet == null) metaVersionsSet = new TreeSet<>(); metaVersionsSet.add(version); } } + } // skip ext and comment pos = entryPos + nlen + elen + clen; entryPos = pos + CENHDR; i++; } total = i; ! if (signatureNames != null) { ! int len = signatureNames.size(); ! signatureMetaNames = new int[len]; ! for (int j = 0; j < len; j++) { ! signatureMetaNames[j] = signatureNames.get(j); } } if (metaVersionsSet != null) { metaVersions = new int[metaVersionsSet.size()]; int c = 0;
*** 1593,1602 **** --- 1629,1677 ---- && (name[off++] | 0x20) == 'f' && (name[off] ) == '/'; } /* + * Check if the bytes represents a name equals to MANIFEST.MF + */ + private static boolean isManifestName(byte[] name, int off, int len) { + return (len == 11 // "MANIFEST.MF".length() + && (name[off++] | 0x20) == 'm' + && (name[off++] | 0x20) == 'a' + && (name[off++] | 0x20) == 'n' + && (name[off++] | 0x20) == 'i' + && (name[off++] | 0x20) == 'f' + && (name[off++] | 0x20) == 'e' + && (name[off++] | 0x20) == 's' + && (name[off++] | 0x20) == 't' + && (name[off++] | 0x20) == '.' + && (name[off++] | 0x20) == 'm' + && (name[off++] | 0x20) == 'f'); + } + + private boolean isSignatureRelated(byte[] cen, int start, int len) { + // Check if entry ends with .EC and .SF + if (cen[start + len - 3] == '.') { + int b1 = cen[start + len - 2] | 0x20; + int b2 = cen[start + len - 1] | 0x20; + if ((b1 == 'e' && b2 == 'c') || (b1 == 's' && b2 == 'f')) { + return true; + } + } + // Check if entry ends with .DSA and .RSA + if (cen[start + len - 4] == '.') { + int b1 = cen[start + len - 3] | 0x20; + int b2 = cen[start + len - 2] | 0x20; + int b3 = cen[start + len - 1] | 0x20; + if ((b1 == 'r' || b1 == 'd') && b2 == 's' && b3 == 'a') { + return true; + } + } + return false; + } + + /* * If the bytes represents a non-directory name beginning * with "versions/", continuing with a positive integer, * followed by a '/', then return that integer value. * Otherwise, return 0 */
< prev index next >