< 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 >