summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/java/util/jar
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-09 19:58:05 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-09 19:58:05 +0000
commit65bf3316cf384588453604be6b4f0ed3751a8b0f (patch)
tree996a5f57d4a68c53473382e45cb22f574cb3e4db /libjava/classpath/java/util/jar
parent8fc56618a84446beccd45b80381cdfe0e94050df (diff)
downloadppe42-gcc-65bf3316cf384588453604be6b4f0ed3751a8b0f.tar.gz
ppe42-gcc-65bf3316cf384588453604be6b4f0ed3751a8b0f.zip
Merged gcj-eclipse branch to trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120621 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/java/util/jar')
-rw-r--r--libjava/classpath/java/util/jar/Attributes.java14
-rw-r--r--libjava/classpath/java/util/jar/JarEntry.java29
-rw-r--r--libjava/classpath/java/util/jar/JarFile.java212
-rw-r--r--libjava/classpath/java/util/jar/Manifest.java10
4 files changed, 92 insertions, 173 deletions
diff --git a/libjava/classpath/java/util/jar/Attributes.java b/libjava/classpath/java/util/jar/Attributes.java
index 92d29cf49b9..329fe6323b7 100644
--- a/libjava/classpath/java/util/jar/Attributes.java
+++ b/libjava/classpath/java/util/jar/Attributes.java
@@ -67,8 +67,8 @@ import java.util.Set;
* @see java.util.jar.Attributes.Name
* @author Mark Wielaard (mark@klomp.org)
*/
-public class Attributes
- implements Cloneable, java.util.Map // Fully qualified for jikes 1.22
+public class Attributes
+ implements Cloneable, Map<Object, Object>
{
// Fields
@@ -78,7 +78,7 @@ public class Attributes
* implementation it is actually a Hashtable, but that can be different in
* other implementations.
*/
- protected Map map;
+ protected Map<Object, Object> map;
// Inner class
@@ -492,7 +492,7 @@ public class Attributes
*
* @return a set of attribute name value pairs
*/
- public Set entrySet()
+ public Set<Map.Entry<Object, Object>> entrySet()
{
return map.entrySet();
}
@@ -558,7 +558,7 @@ public class Attributes
/**
* Gives a Set of all the values of defined attribute names.
*/
- public Set keySet()
+ public Set<Object> keySet()
{
return map.keySet();
}
@@ -587,7 +587,7 @@ public class Attributes
* @exception ClassCastException if the supplied map is not an instance of
* Attributes
*/
- public void putAll(Map attr)
+ public void putAll(Map<?, ?> attr)
{
if (!(attr instanceof Attributes))
{
@@ -622,7 +622,7 @@ public class Attributes
* Returns all the values of the defined attribute name/value pairs as a
* Collection.
*/
- public Collection values()
+ public Collection<Object> values()
{
return map.values();
}
diff --git a/libjava/classpath/java/util/jar/JarEntry.java b/libjava/classpath/java/util/jar/JarEntry.java
index 722a283bba3..515b45fa9b4 100644
--- a/libjava/classpath/java/util/jar/JarEntry.java
+++ b/libjava/classpath/java/util/jar/JarEntry.java
@@ -1,5 +1,5 @@
/* JarEntry.java - Represents an entry in a jar file
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,6 +39,7 @@ package java.util.jar;
import java.io.IOException;
import java.security.cert.Certificate;
+import java.util.Set;
import java.util.zip.ZipEntry;
/**
@@ -60,7 +61,7 @@ public class JarEntry extends ZipEntry
// (Package local) fields
Attributes attr;
- Certificate certs[];
+ JarFile jarfile;
// Constructors
@@ -79,7 +80,7 @@ public class JarEntry extends ZipEntry
{
super(name);
attr = null;
- certs = null;
+ jarfile = null;
}
/**
@@ -93,7 +94,7 @@ public class JarEntry extends ZipEntry
{
super(entry);
attr = null;
- certs = null;
+ jarfile = null;
}
/**
@@ -112,7 +113,7 @@ public class JarEntry extends ZipEntry
catch (IOException _)
{
}
- certs = entry.getCertificates();
+ jarfile = entry.jarfile;
}
// Methods
@@ -153,13 +154,19 @@ public class JarEntry extends ZipEntry
*/
public Certificate[] getCertificates()
{
- if (certs != null)
+ if (jarfile != null)
{
- return (Certificate[])certs.clone();
- }
- else
- {
- return null;
+ synchronized (jarfile)
+ {
+ if (jarfile.entryCerts != null)
+ {
+ Set certs = (Set) jarfile.entryCerts.get(getName());
+ if (certs != null
+ && jarfile.verified.get(getName()) == Boolean.TRUE)
+ return (Certificate[]) certs.toArray(new Certificate[certs.size()]);
+ }
+ }
}
+ return null;
}
}
diff --git a/libjava/classpath/java/util/jar/JarFile.java b/libjava/classpath/java/util/jar/JarFile.java
index 88814f1d6bf..6807736590a 100644
--- a/libjava/classpath/java/util/jar/JarFile.java
+++ b/libjava/classpath/java/util/jar/JarFile.java
@@ -68,6 +68,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
@@ -149,6 +151,12 @@ public class JarFile extends ZipFile
*/
HashMap entryCerts;
+ /**
+ * A {@link Map} of message digest algorithm names to their implementation.
+ * Used to reduce object (algorithm implementation) instantiation.
+ */
+ private HashMap digestAlgorithms = new HashMap();
+
static boolean DEBUG = false;
static void debug(Object msg)
{
@@ -313,7 +321,7 @@ public class JarFile extends ZipFile
*
* @exception IllegalStateException when the JarFile is already closed
*/
- public Enumeration entries() throws IllegalStateException
+ public Enumeration<JarEntry> entries() throws IllegalStateException
{
return new JarEnumeration(super.entries(), this);
}
@@ -322,13 +330,13 @@ public class JarFile extends ZipFile
* Wraps a given Zip Entries Enumeration. For every zip entry a
* JarEntry is created and the corresponding Attributes are looked up.
*/
- private static class JarEnumeration implements Enumeration
+ private static class JarEnumeration implements Enumeration<JarEntry>
{
- private final Enumeration entries;
+ private final Enumeration<? extends ZipEntry> entries;
private final JarFile jarfile;
- JarEnumeration(Enumeration e, JarFile f)
+ JarEnumeration(Enumeration<? extends ZipEntry> e, JarFile f)
{
entries = e;
jarfile = f;
@@ -339,7 +347,7 @@ public class JarFile extends ZipFile
return entries.hasMoreElements();
}
- public Object nextElement()
+ public JarEntry nextElement()
{
ZipEntry zip = (ZipEntry) entries.nextElement();
JarEntry jar = new JarEntry(zip);
@@ -374,19 +382,8 @@ public class JarFile extends ZipFile
}
jarfile.signaturesRead = true; // fudge it.
}
-
- // Include the certificates only if we have asserted that the
- // signatures are valid. This means the certificates will not be
- // available if the entry hasn't been read yet.
- if (jarfile.entryCerts != null
- && jarfile.verified.get(zip.getName()) == Boolean.TRUE)
- {
- Set certs = (Set) jarfile.entryCerts.get(jar.getName());
- if (certs != null)
- jar.certs = (Certificate[])
- certs.toArray(new Certificate[certs.size()]);
- }
}
+ jar.jarfile = jarfile;
return jar;
}
}
@@ -431,18 +428,7 @@ public class JarFile extends ZipFile
}
signaturesRead = true;
}
- // See the comments in the JarEnumeration for why we do this
- // check.
- if (DEBUG)
- debug("entryCerts=" + entryCerts + " verified " + name
- + " ? " + verified.get(name));
- if (entryCerts != null && verified.get(name) == Boolean.TRUE)
- {
- Set certs = (Set) entryCerts.get(name);
- if (certs != null)
- jarEntry.certs = (Certificate[])
- certs.toArray(new Certificate[certs.size()]);
- }
+ jarEntry.jarfile = this;
return jarEntry;
}
return null;
@@ -599,6 +585,31 @@ public class JarFile extends ZipFile
validCerts.clear();
}
+ // Read the manifest into a HashMap (String fileName, String entry)
+ // The fileName might be split into multiple lines in the manifest.
+ // Such additional lines will start with a space.
+ InputStream in = super.getInputStream(super.getEntry(MANIFEST_NAME));
+ ByteArrayOutputStream baStream = new ByteArrayOutputStream();
+ byte[] ba = new byte[1024];
+ while (true)
+ {
+ int len = in.read(ba);
+ if (len < 0)
+ break;
+ baStream.write(ba, 0, len);
+ }
+ in.close();
+
+ HashMap hmManifestEntries = new HashMap();
+ Pattern p = Pattern.compile("Name: (.+?\r?\n(?: .+?\r?\n)*)"
+ + ".+?-Digest: .+?\r?\n\r?\n");
+ Matcher m = p.matcher(baStream.toString());
+ while (m.find())
+ {
+ String fileName = m.group(1).replaceAll("\r?\n ?", "");
+ hmManifestEntries.put(fileName, m.group());
+ }
+
// Phase 3: verify the signature file signatures against the manifest,
// mapping the entry name to the target certificates.
this.entryCerts = new HashMap();
@@ -614,7 +625,7 @@ public class JarFile extends ZipFile
Map.Entry e2 = (Map.Entry) it2.next();
String entryname = String.valueOf(e2.getKey());
Attributes attr = (Attributes) e2.getValue();
- if (verifyHashes(entryname, attr))
+ if (verifyHashes(entryname, attr, hmManifestEntries))
{
if (DEBUG)
debug("entry " + entryname + " has certificates " + certificates);
@@ -721,39 +732,29 @@ public class JarFile extends ZipFile
}
/**
- * Verifies that the digest(s) in a signature file were, in fact, made
- * over the manifest entry for ENTRY.
- *
+ * Verifies that the digest(s) in a signature file were, in fact, made over
+ * the manifest entry for ENTRY.
+ *
* @param entry The entry name.
* @param attr The attributes from the signature file to verify.
+ * @param hmManifestEntries Mappings of Jar file entry names to their manifest
+ * entry text; i.e. the base-64 encoding of their
*/
- private boolean verifyHashes(String entry, Attributes attr)
+ private boolean verifyHashes(String entry, Attributes attr,
+ HashMap hmManifestEntries)
{
int verified = 0;
- // The bytes for ENTRY's manifest entry, which are signed in the
- // signature file.
- byte[] entryBytes = null;
- try
- {
- ZipEntry e = super.getEntry(entry);
- if (e == null)
- {
- if (DEBUG)
- debug("verifyHashes: no entry '" + entry + "'");
- return false;
- }
- entryBytes = readManifestEntry(e);
- }
- catch (IOException ioe)
+ String stringEntry = (String) hmManifestEntries.get(entry);
+ if (stringEntry == null)
{
if (DEBUG)
- {
- debug(ioe);
- ioe.printStackTrace();
- }
+ debug("could not find " + entry + " in manifest");
return false;
}
+ // The bytes for ENTRY's manifest entry, which are signed in the
+ // signature file.
+ byte[] entryBytes = stringEntry.getBytes();
for (Iterator it = attr.entrySet().iterator(); it.hasNext(); )
{
@@ -765,9 +766,14 @@ public class JarFile extends ZipFile
try
{
byte[] hash = Base64InputStream.decode((String) e.getValue());
- MessageDigest md = MessageDigest.getInstance(alg, provider);
- md.update(entryBytes);
- byte[] hash2 = md.digest();
+ MessageDigest md = (MessageDigest) digestAlgorithms.get(alg);
+ if (md == null)
+ {
+ md = MessageDigest.getInstance(alg, provider);
+ digestAlgorithms.put(alg, md);
+ }
+ md.reset();
+ byte[] hash2 = md.digest(entryBytes);
if (DEBUG)
debug("verifying SF entry " + entry + " alg: " + md.getAlgorithm()
+ " expect=" + new java.math.BigInteger(hash).toString(16)
@@ -801,100 +807,6 @@ public class JarFile extends ZipFile
}
/**
- * Read the raw bytes that comprise a manifest entry. We can't use the
- * Manifest object itself, because that loses information (such as line
- * endings, and order of entries).
- */
- private byte[] readManifestEntry(ZipEntry entry) throws IOException
- {
- InputStream in = super.getInputStream(super.getEntry(MANIFEST_NAME));
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- byte[] target = ("Name: " + entry.getName()).getBytes();
- int t = 0, c, prev = -1, state = 0, l = -1;
-
- while ((c = in.read()) != -1)
- {
-// if (DEBUG)
-// debug("read "
-// + (c == '\n' ? "\\n" : (c == '\r' ? "\\r" : String.valueOf((char) c)))
-// + " state=" + state + " prev="
-// + (prev == '\n' ? "\\n" : (prev == '\r' ? "\\r" : String.valueOf((char) prev)))
-// + " t=" + t + (t < target.length ? (" target[t]=" + (char) target[t]) : "")
-// + " l=" + l);
- switch (state)
- {
-
- // Step 1: read until we find the "target" bytes: the start
- // of the entry we need to read.
- case 0:
- if (((byte) c) != target[t])
- t = 0;
- else
- {
- t++;
- if (t == target.length)
- {
- out.write(target);
- state = 1;
- }
- }
- break;
-
- // Step 2: assert that there is a newline character after
- // the "target" bytes.
- case 1:
- if (c != '\n' && c != '\r')
- {
- out.reset();
- t = 0;
- state = 0;
- }
- else
- {
- out.write(c);
- state = 2;
- }
- break;
-
- // Step 3: read this whole entry, until we reach an empty
- // line.
- case 2:
- if (c == '\n')
- {
- out.write(c);
- // NL always terminates a line.
- if (l == 0 || (l == 1 && prev == '\r'))
- return out.toByteArray();
- l = 0;
- }
- else
- {
- // Here we see a blank line terminated by a CR,
- // followed by the next entry. Technically, `c' should
- // always be 'N' at this point.
- if (l == 1 && prev == '\r')
- return out.toByteArray();
- out.write(c);
- l++;
- }
- prev = c;
- break;
-
- default:
- throw new RuntimeException("this statement should be unreachable");
- }
- }
-
- // The last entry, with a single CR terminating the line.
- if (state == 2 && prev == '\r' && l == 0)
- return out.toByteArray();
-
- // We should not reach this point, we didn't find the entry (or, possibly,
- // it is the last entry and is malformed).
- throw new IOException("could not find " + entry + " in manifest");
- }
-
- /**
* A utility class that verifies jar entries as they are read.
*/
private static class EntryInputStream extends FilterInputStream
diff --git a/libjava/classpath/java/util/jar/Manifest.java b/libjava/classpath/java/util/jar/Manifest.java
index 64a0c476a91..8effc2878ce 100644
--- a/libjava/classpath/java/util/jar/Manifest.java
+++ b/libjava/classpath/java/util/jar/Manifest.java
@@ -38,7 +38,7 @@ exception statement from your version. */
package java.util.jar;
import gnu.java.util.jar.JarUtils;
-
+
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -60,7 +60,7 @@ public class Manifest implements Cloneable
private final Attributes mainAttr;
/** A map of atrributes for all entries described in this Manifest. */
- private final Map entries;
+ private final Map<String, Attributes> entries;
// Constructors
@@ -70,7 +70,7 @@ public class Manifest implements Cloneable
public Manifest()
{
mainAttr = new Attributes();
- entries = new Hashtable();
+ entries = new Hashtable<String, Attributes>();
}
/**
@@ -104,7 +104,7 @@ public class Manifest implements Cloneable
public Manifest(Manifest man)
{
mainAttr = new Attributes(man.getMainAttributes());
- entries = new Hashtable(man.getEntries());
+ entries = new Hashtable<String, Attributes>(man.getEntries());
}
// Methods
@@ -122,7 +122,7 @@ public class Manifest implements Cloneable
* in this manifest. Adding, changing or removing from this entries map
* changes the entries of this manifest.
*/
- public Map getEntries()
+ public Map<String, Attributes> getEntries()
{
return entries;
}
OpenPOWER on IntegriCloud