diff options
author | Jesse Wilson <jessewilson@google.com> | 2009-12-09 18:24:19 -0800 |
---|---|---|
committer | Jesse Wilson <jessewilson@google.com> | 2009-12-09 18:24:19 -0800 |
commit | f7c6911047d63bc76292f55ce538da32818dd931 (patch) | |
tree | 94bbbb14440a7bac234c15631ab5f6a6524b82f9 /archive | |
parent | a1e5d8a2c1594f7a6ed8aca6e82b106ec8ce79d6 (diff) | |
download | libcore-f7c6911047d63bc76292f55ce538da32818dd931.zip libcore-f7c6911047d63bc76292f55ce538da32818dd931.tar.gz libcore-f7c6911047d63bc76292f55ce538da32818dd931.tar.bz2 |
Merge branch 'archive_888752' into archive_dalvik
Conflicts:
libcore/archive/build.xml
libcore/archive/src/main/java/java/util/jar/JarFile.java
libcore/archive/src/main/java/java/util/zip/GZIPInputStream.java
libcore/archive/src/main/java/java/util/zip/Inflater.java
libcore/archive/src/main/java/java/util/zip/InflaterInputStream.java
libcore/archive/src/main/java/java/util/zip/ZipEntry.java
libcore/archive/src/main/java/java/util/zip/ZipFile.java
libcore/archive/src/main/java/java/util/zip/ZipInputStream.java
libcore/archive/src/main/java/org/apache/harmony/archive/internal/nls/Messages.java
libcore/archive/src/main/java/org/apache/harmony/archive/internal/nls/messages.properties
libcore/archive/src/main/native/archive/unix/exports.txt
libcore/archive/src/main/native/archive/unix/makefile
libcore/archive/src/main/native/archive/windows/makefile
libcore/archive/src/main/native/archive_copyright.c
libcore/archive/src/main/native/jarfile.c
libcore/archive/src/main/native/java_util_zip_Deflater.c
libcore/archive/src/main/native/zip.c
libcore/archive/src/main/native/zipcache.c
libcore/archive/src/main/native/zlib/unix/makefile
libcore/archive/src/main/native/zlib/windows/makefile
libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/AllTests.java
libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarFileTest.java
libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarInputStreamTest.java
libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarOutputStreamTest.java
libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ManifestTest.java
libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200Test.java
libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DeflaterOutputStreamTest.java
libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterInputStreamTest.java
libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterTest.java
libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipEntryTest.java
libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java
libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipInputStreamTest.java
Diffstat (limited to 'archive')
34 files changed, 593 insertions, 886 deletions
diff --git a/archive/src/main/java/java/util/jar/Attributes.java b/archive/src/main/java/java/util/jar/Attributes.java index 159a0cd..adc598d 100644 --- a/archive/src/main/java/java/util/jar/Attributes.java +++ b/archive/src/main/java/java/util/jar/Attributes.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -164,7 +164,7 @@ public class Attributes implements Cloneable, Map<Object, Object> { public static final Name IMPLEMENTATION_URL = new Name( "Implementation-URL"); //$NON-NLS-1$ - static final Name NAME = new Name("Name"); + static final Name NAME = new Name("Name"); //$NON-NLS-1$ /** * A String which must satisfy the following EBNF grammar to specify an @@ -218,14 +218,14 @@ public class Attributes implements Cloneable, Map<Object, Object> { @Override public String toString() { try { - return new String(name, "ISO-8859-1"); + return new String(name, "ISO-8859-1"); //$NON-NLS-1$ } catch (UnsupportedEncodingException iee) { throw new InternalError(iee.getLocalizedMessage()); } } /** - * returns whether the argument provided is the same as the attribute + * Returns whether the argument provided is the same as the attribute * name. * * @return if the attribute names correspond. @@ -239,7 +239,7 @@ public class Attributes implements Cloneable, Map<Object, Object> { return false; } - return Util.equalsIgnoreCase(name, ((Name) object).name); + return Util.asciiEqualsIgnoreCase(name, ((Name) object).name); } /** diff --git a/archive/src/main/java/java/util/jar/InitManifest.java b/archive/src/main/java/java/util/jar/InitManifest.java index bf9c397..22baaf5 100644 --- a/archive/src/main/java/java/util/jar/InitManifest.java +++ b/archive/src/main/java/java/util/jar/InitManifest.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/archive/src/main/java/java/util/jar/JarEntry.java b/archive/src/main/java/java/util/jar/JarEntry.java index 869e4b4..29d64a9 100644 --- a/archive/src/main/java/java/util/jar/JarEntry.java +++ b/archive/src/main/java/java/util/jar/JarEntry.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -51,7 +51,7 @@ public class JarEntry extends ZipEntry { /** * Creates a new {@code JarEntry} named name. - * + * * @param name * The name of the new {@code JarEntry}. */ @@ -61,7 +61,7 @@ public class JarEntry extends ZipEntry { /** * Creates a new {@code JarEntry} using the values obtained from entry. - * + * * @param entry * The ZipEntry to obtain values from. */ @@ -72,7 +72,7 @@ public class JarEntry extends ZipEntry { /** * Returns the {@code Attributes} object associated with this entry or * {@code null} if none exists. - * + * * @return the {@code Attributes} for this entry. * @exception IOException * If an error occurs obtaining the {@code Attributes}. @@ -94,7 +94,7 @@ public class JarEntry extends ZipEntry { * entry or {@code null} if none exists. Make sure that the everything is * read from the input stream before calling this method, or else the method * returns {@code null}. - * + * * @return the certificate for this entry. * @see java.security.cert.Certificate */ @@ -116,7 +116,7 @@ public class JarEntry extends ZipEntry { /** * Create a new {@code JarEntry} using the values obtained from the * argument. - * + * * @param je * The {@code JarEntry} to obtain values from. */ @@ -132,7 +132,7 @@ public class JarEntry extends ZipEntry { * JAR file. If there is no such code signer, it returns {@code null}. Make * sure that the everything is read from the input stream before calling * this method, or else the method returns {@code null}. - * + * * @return the code signers for the JAR entry. * @see CodeSigner */ diff --git a/archive/src/main/java/java/util/jar/JarException.java b/archive/src/main/java/java/util/jar/JarException.java index d6943c4..92f61f3 100644 --- a/archive/src/main/java/java/util/jar/JarException.java +++ b/archive/src/main/java/java/util/jar/JarException.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/archive/src/main/java/java/util/jar/JarFile.java b/archive/src/main/java/java/util/jar/JarFile.java index 6f4eb83..bebc82e 100644 --- a/archive/src/main/java/java/util/jar/JarFile.java +++ b/archive/src/main/java/java/util/jar/JarFile.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,23 +17,19 @@ package java.util.jar; -// BEGIN android-removed -// import java.io.ByteArrayInputStream; -// END android-removed -// BEGIN android-added -import java.io.ByteArrayOutputStream; -import java.util.List; -import java.util.ArrayList; -// END android-added import java.io.File; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Enumeration; +import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; +import org.apache.harmony.archive.internal.nls.Messages; import org.apache.harmony.archive.util.Util; +import org.apache.harmony.luni.util.InputStreamHelper; /** * {@code JarFile} is used to read jar entries and their associated data from @@ -49,17 +45,18 @@ public class JarFile extends ZipFile { */ public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF"; //$NON-NLS-1$ + // The directory containing the manifest. static final String META_DIR = "META-INF/"; //$NON-NLS-1$ + // The manifest after it has been read from the JAR. private Manifest manifest; + // The entry for the MANIFEST.MF file before it is read. private ZipEntry manifestEntry; JarVerifier verifier; - // BEGIN android-added private boolean closed = false; - // END android-added static final class JarFileInputStream extends FilterInputStream { private long count; @@ -68,9 +65,7 @@ public class JarFile extends ZipFile { private JarVerifier.VerifierEntry entry; - // BEGIN android-added private boolean done = false; - // END android-added JarFileInputStream(InputStream is, ZipEntry ze, JarVerifier.VerifierEntry e) { @@ -82,7 +77,6 @@ public class JarFile extends ZipFile { @Override public int read() throws IOException { - // BEGIN android-changed if (done) { return -1; } @@ -104,12 +98,10 @@ public class JarFile extends ZipFile { entry.verify(); return -1; } - // END android-changed } @Override public int read(byte[] buf, int off, int nbytes) throws IOException { - // BEGIN android-changed if (done) { return -1; } @@ -135,10 +127,8 @@ public class JarFile extends ZipFile { entry.verify(); return -1; } - // END android-changed } - // BEGIN android-added @Override public int available() throws IOException { if (done) { @@ -146,12 +136,11 @@ public class JarFile extends ZipFile { } return super.available(); } - // END android-added @Override public long skip(long nbytes) throws IOException { long cnt = 0, rem = 0; - byte[] buf = new byte[4096]; + byte[] buf = new byte[(int)Math.min(nbytes, 2048L)]; while (cnt < nbytes) { int x = read(buf, 0, (rem = nbytes - cnt) > buf.length ? buf.length @@ -227,7 +216,6 @@ public class JarFile extends ZipFile { */ public JarFile(String filename) throws IOException { this(filename, true); - } /** @@ -294,25 +282,6 @@ public class JarFile extends ZipFile { return (JarEntry) getEntry(name); } - - // BEGIN android-added - private byte[] getAllBytesFromStreamAndClose(InputStream is) throws IOException { - ByteArrayOutputStream bs = new ByteArrayOutputStream(); - try { - byte[] buf = new byte[666]; - int iRead; int off; - while (is.available() > 0) { - iRead = is.read(buf, 0, buf.length); - if (iRead > 0) - bs.write(buf, 0, iRead); - } - } finally { - is.close(); - } - return bs.toByteArray(); - } - // END android-added - /** * Returns the {@code Manifest} object associated with this {@code JarFile} * or {@code null} if no MANIFEST entry exists. @@ -325,69 +294,76 @@ public class JarFile extends ZipFile { * @see Manifest */ public Manifest getManifest() throws IOException { - // BEGIN android-added if (closed) { - throw new IllegalStateException("JarFile has been closed."); + // archive.35=JarFile has been closed + throw new IllegalStateException(Messages.getString("archive.35")); //$NON-NLS-1$ } - // END android-added if (manifest != null) { return manifest; } try { - // BEGIN android-modified InputStream is = super.getInputStream(manifestEntry); if (verifier != null) { - verifier.addMetaEntry(manifestEntry.getName(), getAllBytesFromStreamAndClose(is)); + verifier.addMetaEntry(manifestEntry.getName(), + InputStreamHelper.readFullyAndClose(is)); is = super.getInputStream(manifestEntry); } - // END android-modified try { manifest = new Manifest(is, verifier != null); } finally { is.close(); } - manifestEntry = null; - } catch(NullPointerException e) { + manifestEntry = null; // Can discard the entry now. + } catch (NullPointerException e) { manifestEntry = null; } return manifest; } + /** + * Called by the JarFile constructors, this method reads the contents of the + * file's META-INF/ directory and picks out the MANIFEST.MF file and + * verifier signature files if they exist. Any signature files found are + * registered with the verifier. + * + * @throws IOException + * if there is a problem reading the jar file entries. + */ private void readMetaEntries() throws IOException { - ZipEntry[] metaEntries = getMetaEntriesImpl(null); - int dirLength = META_DIR.length(); + // Get all meta directory entries + ZipEntry[] metaEntries = getMetaEntriesImpl(); + if (metaEntries == null) { + verifier = null; + return; + } boolean signed = false; - if (null != metaEntries) { - for (ZipEntry entry : metaEntries) { - String entryName = entry.getName(); - if (manifestEntry == null - && manifest == null - && Util.ASCIIIgnoreCaseRegionMatches(entryName, - dirLength, MANIFEST_NAME, dirLength, - MANIFEST_NAME.length() - dirLength)) { - manifestEntry = entry; - if (verifier == null) { - break; - } - } else if (verifier != null - && entryName.length() > dirLength - && (Util.ASCIIIgnoreCaseRegionMatches(entryName, - entryName.length() - 3, ".SF", 0, 3) //$NON-NLS-1$ - || Util.ASCIIIgnoreCaseRegionMatches(entryName, - entryName.length() - 4, ".DSA", 0, 4) //$NON-NLS-1$ - || Util.ASCIIIgnoreCaseRegionMatches(entryName, - entryName.length() - 4, ".RSA", 0, 4))) { //$NON-NLS-1$ + for (ZipEntry entry : metaEntries) { + String entryName = entry.getName(); + // Is this the entry for META-INF/MANIFEST.MF ? + if (manifestEntry == null + && Util.asciiEqualsIgnoreCase(MANIFEST_NAME, entryName)) { + manifestEntry = entry; + // If there is no verifier then we don't need to look any further. + if (verifier == null) { + break; + } + } else { + // Is this an entry that the verifier needs? + if (verifier != null + && (Util.asciiEndsWithIgnoreCase(entryName, ".SF") + || Util.asciiEndsWithIgnoreCase(entryName, ".DSA") + || Util.asciiEndsWithIgnoreCase(entryName, ".RSA"))) { signed = true; InputStream is = super.getInputStream(entry); - // BEGIN android-modified - byte[] buf = getAllBytesFromStreamAndClose(is); - // END android-modified + byte[] buf = InputStreamHelper.readFullyAndClose(is); verifier.addMetaEntry(entryName, buf); } } } + + // If there were no signature files, then no verifier work to do. if (!signed) { verifier = null; } @@ -456,31 +432,30 @@ public class JarFile extends ZipFile { return je; } - // BEGIN android-modified - private ZipEntry[] getMetaEntriesImpl(byte[] buf) { - int n = 0; - - List<ZipEntry> list = new ArrayList<ZipEntry>(); - + /** + * Returns all the ZipEntry's that relate to files in the + * JAR's META-INF directory. + * + * @return the list of ZipEntry's or {@code null} if there are none. + */ + private ZipEntry[] getMetaEntriesImpl() { + List<ZipEntry> list = new ArrayList<ZipEntry>(8); Enumeration<? extends ZipEntry> allEntries = entries(); while (allEntries.hasMoreElements()) { ZipEntry ze = allEntries.nextElement(); - if (ze.getName().startsWith("META-INF/") && ze.getName().length() > 9) { + if (ze.getName().startsWith(META_DIR) + && ze.getName().length() > META_DIR.length()) { list.add(ze); } } - if (list.size() != 0) { - ZipEntry[] result = new ZipEntry[list.size()]; - list.toArray(result); - return result; - } - else { + if (list.size() == 0) { return null; } + ZipEntry[] result = new ZipEntry[list.size()]; + list.toArray(result); + return result; } - // END android-modified - // BEGIN android-added /** * Closes this {@code JarFile}. * @@ -492,6 +467,4 @@ public class JarFile extends ZipFile { super.close(); closed = true; } - // END android-added - } diff --git a/archive/src/main/java/java/util/jar/JarInputStream.java b/archive/src/main/java/java/util/jar/JarInputStream.java index c803183..952f3f8 100644 --- a/archive/src/main/java/java/util/jar/JarInputStream.java +++ b/archive/src/main/java/java/util/jar/JarInputStream.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -115,7 +115,7 @@ public class JarInputStream extends ZipInputStream { /** * Returns the {@code Manifest} object associated with this {@code * JarInputStream} or {@code null} if no manifest entry exists. - * + * * @return the MANIFEST specifying the contents of the JAR file. */ public Manifest getManifest() { @@ -125,7 +125,7 @@ public class JarInputStream extends ZipInputStream { /** * Returns the next {@code JarEntry} contained in this stream or {@code * null} if no more entries are present. - * + * * @return the next JAR entry. * @throws IOException * if an error occurs while reading the entry. @@ -182,7 +182,7 @@ public class JarInputStream extends ZipInputStream { /** * Returns the next {@code ZipEntry} contained in this stream or {@code * null} if no more entries are present. - * + * * @return the next extracted ZIP entry. * @throws IOException * if an error occurs while reading the entry. diff --git a/archive/src/main/java/java/util/jar/JarOutputStream.java b/archive/src/main/java/java/util/jar/JarOutputStream.java index e901d87..78e3aa5 100644 --- a/archive/src/main/java/java/util/jar/JarOutputStream.java +++ b/archive/src/main/java/java/util/jar/JarOutputStream.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -34,7 +34,7 @@ public class JarOutputStream extends ZipOutputStream { * Constructs a new {@code JarOutputStream} using an output stream. The * content of the {@code Manifest} must match the JAR entry information * written subsequently to the stream. - * + * * @param os * the {@code OutputStream} to write to * @param mf @@ -57,13 +57,12 @@ public class JarOutputStream extends ZipOutputStream { /** * Constructs a new {@code JarOutputStream} using an arbitrary output * stream. - * + * * @param os * the {@code OutputStream} to write to. * @throws IOException * if an error occurs creating the {@code JarOutputStream}. */ - @SuppressWarnings("unused") public JarOutputStream(OutputStream os) throws IOException { super(os); } @@ -71,7 +70,7 @@ public class JarOutputStream extends ZipOutputStream { /** * Writes the specified ZIP entry to the underlying stream. The previous * entry is closed if it is still open. - * + * * @param ze * the {@code ZipEntry} to write to. * @throws IOException diff --git a/archive/src/main/java/java/util/jar/JarVerifier.java b/archive/src/main/java/java/util/jar/JarVerifier.java index 6c1ee93..519b1e1 100644 --- a/archive/src/main/java/java/util/jar/JarVerifier.java +++ b/archive/src/main/java/java/util/jar/JarVerifier.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -122,7 +122,6 @@ class JarVerifier { * if the digest value stored in the manifest does <i>not</i> * agree with the decrypted digest as recovered from the * <code>.SF</code> file. - * @see #initEntry(String) */ void verify() { byte[] d = digest.digest(); diff --git a/archive/src/main/java/java/util/jar/Manifest.java b/archive/src/main/java/java/util/jar/Manifest.java index b28f3fb..48dc8c8 100644 --- a/archive/src/main/java/java/util/jar/Manifest.java +++ b/archive/src/main/java/java/util/jar/Manifest.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -30,7 +30,7 @@ import java.util.Iterator; import java.util.Map; import org.apache.harmony.archive.internal.nls.Messages; -import org.apache.harmony.luni.util.InputStreamExposer; +import org.apache.harmony.luni.util.InputStreamHelper; import org.apache.harmony.luni.util.ThreadLocalCache; /** @@ -209,7 +209,7 @@ public class Manifest implements Cloneable { byte[] buf; // Try to read get a reference to the bytes directly try { - buf = InputStreamExposer.expose(is); + buf = InputStreamHelper.expose(is); } catch (UnsupportedOperationException uoe) { buf = readFully(is); } @@ -242,20 +242,34 @@ public class Manifest implements Cloneable { * have a line feed within a reasonable number of characters. */ private byte[] readFully(InputStream is) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buffer = new byte[8192]; + // Initial read + byte[] buffer = new byte[4096]; + int count = is.read(buffer); + int nextByte = is.read(); + + // Did we get it all in one read? + if (nextByte == -1) { + byte[] dest = new byte[count]; + System.arraycopy(buffer, 0, dest, 0, count); + return dest; + } + + // Does it look like a manifest? + if (!containsLine(buffer, count)) { + // archive.2E=Manifest is too long + throw new IOException(Messages.getString("archive.2E")); //$NON-NLS-1$ + } + // Requires additional reads + ByteArrayOutputStream baos = new ByteArrayOutputStream(count * 2); + baos.write(buffer, 0, count); + baos.write(nextByte); while (true) { - int count = is.read(buffer); + count = is.read(buffer); if (count == -1) { - // TODO: Do we need to copy this, or can we live with junk at the end? return baos.toByteArray(); } baos.write(buffer, 0, count); - - if (!containsLine(buffer, count)) { - throw new IOException(Messages.getString("archive.2E")); //$NON-NLS-1$ - } } } diff --git a/archive/src/main/java/java/util/jar/Pack200.java b/archive/src/main/java/java/util/jar/Pack200.java index 3e7081d..9cb045e 100644 --- a/archive/src/main/java/java/util/jar/Pack200.java +++ b/archive/src/main/java/java/util/jar/Pack200.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -48,7 +48,7 @@ public abstract class Pack200 { * {@code 'java.util.jar.Pack200.Packer'}. If this system property is * defined an instance of the specified class is returned, otherwise the * system's default implementation is returned. - * + * * @return an instance of {@code Packer} */ public static Pack200.Packer newPacker() { @@ -78,7 +78,7 @@ public abstract class Pack200 { * property {@code 'java.util.jar.Pack200.Unpacker'}. If this system * property is defined an instance of the specified class is returned, * otherwise the system's default implementation is returned. - * + * * @return a instance of {@code Unpacker}. */ public static Pack200.Unpacker newUnpacker() { @@ -209,7 +209,7 @@ public abstract class Pack200 { /** * Pack the specified JAR file to the specified output stream. - * + * * @param in * JAR file to be compressed. * @param out @@ -222,7 +222,7 @@ public abstract class Pack200 { /** * Pack the data from the specified jar input stream to the specified * output stream. - * + * * @param in * stream of uncompressed JAR data. * @param out @@ -234,7 +234,7 @@ public abstract class Pack200 { /** * add a listener for PropertyChange events - * + * * @param listener * the listener to listen if PropertyChange events occurs */ @@ -242,7 +242,7 @@ public abstract class Pack200 { /** * remove a listener - * + * * @param listener * listener to remove */ @@ -290,7 +290,7 @@ public abstract class Pack200 { /** * Unpack the specified stream to the specified JAR output stream. - * + * * @param in * stream to uncompressed. * @param out @@ -303,7 +303,7 @@ public abstract class Pack200 { /** * Unpack the contents of the specified {@code File} to the specified * JAR output stream. - * + * * @param in * file to be uncompressed. * @param out @@ -315,7 +315,7 @@ public abstract class Pack200 { /** * add a listener for {@code PropertyChange} events. - * + * * @param listener * the listener to listen if {@code PropertyChange} events * occurs. @@ -324,7 +324,7 @@ public abstract class Pack200 { /** * remove a listener. - * + * * @param listener * listener to remove. */ diff --git a/archive/src/main/java/java/util/zip/Adler32.java b/archive/src/main/java/java/util/zip/Adler32.java index a5f77d7..ebdc996 100644 --- a/archive/src/main/java/java/util/zip/Adler32.java +++ b/archive/src/main/java/java/util/zip/Adler32.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -30,7 +30,7 @@ public class Adler32 implements java.util.zip.Checksum { /** * Returns the {@code Adler32} checksum for all input received. - * + * * @return The checksum for this instance. */ public long getValue() { @@ -47,7 +47,7 @@ public class Adler32 implements java.util.zip.Checksum { /** * Update this {@code Adler32} checksum with the single byte provided as * argument. - * + * * @param i * the byte to update checksum with. */ @@ -57,7 +57,7 @@ public class Adler32 implements java.util.zip.Checksum { /** * Update this {@code Adler32} checksum using the contents of {@code buf}. - * + * * @param buf * bytes to update checksum with. */ @@ -68,7 +68,7 @@ public class Adler32 implements java.util.zip.Checksum { /** * Update this {@code Adler32} checksum with the contents of {@code buf}, * starting from the offset provided and reading n bytes of data. - * + * * @param buf * buffer to obtain data from. * @param off diff --git a/archive/src/main/java/java/util/zip/CRC32.java b/archive/src/main/java/java/util/zip/CRC32.java index 59e8f81..8fc6bb7 100644 --- a/archive/src/main/java/java/util/zip/CRC32.java +++ b/archive/src/main/java/java/util/zip/CRC32.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -29,7 +29,7 @@ public class CRC32 implements java.util.zip.Checksum { /** * Returns the CRC32 checksum for all input received. - * + * * @return The checksum for this instance. */ public long getValue() { @@ -56,7 +56,7 @@ public class CRC32 implements java.util.zip.Checksum { /** * Updates this checksum with the bytes contained in buffer {@code buf}. - * + * * @param buf * the buffer holding the data to update the checksum with. */ @@ -67,7 +67,7 @@ public class CRC32 implements java.util.zip.Checksum { /** * Updates this checksum with n bytes of data obtained from buffer {@code * buf}, starting at offset {@code off}. - * + * * @param buf * the buffer to update the checksum. * @param off diff --git a/archive/src/main/java/java/util/zip/CheckedInputStream.java b/archive/src/main/java/java/util/zip/CheckedInputStream.java index 6513e66..4805ef7 100644 --- a/archive/src/main/java/java/util/zip/CheckedInputStream.java +++ b/archive/src/main/java/java/util/zip/CheckedInputStream.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -34,7 +34,7 @@ public class CheckedInputStream extends java.io.FilterInputStream { * Constructs a new {@code CheckedInputStream} on {@code InputStream} * {@code is}. The checksum will be calculated using the algorithm * implemented by {@code csum}. - * + * * @param is * the input stream to calculate checksum from. * @param csum @@ -48,7 +48,7 @@ public class CheckedInputStream extends java.io.FilterInputStream { /** * Reads one byte of data from the underlying input stream and updates the * checksum with the byte data. - * + * * @return {@code -1} at the end of the stream, a single byte value * otherwise. * @throws IOException @@ -67,7 +67,7 @@ public class CheckedInputStream extends java.io.FilterInputStream { * Reads up to n bytes of data from the underlying input stream, storing it * into {@code buf}, starting at offset {@code off}. The checksum is * updated with the bytes read. - * + * * @param buf * the byte array in which to store the bytes read. * @param off @@ -91,7 +91,7 @@ public class CheckedInputStream extends java.io.FilterInputStream { /** * Returns the checksum calculated on the stream read so far. - * + * * @return the updated checksum. */ public Checksum getChecksum() { @@ -101,7 +101,7 @@ public class CheckedInputStream extends java.io.FilterInputStream { /** * Skip up to n bytes of data on the underlying input stream. Any skipped * bytes are added to the running checksum value. - * + * * @param nbytes * the number of bytes to skip. * @throws IOException @@ -114,7 +114,7 @@ public class CheckedInputStream extends java.io.FilterInputStream { return 0; } long skipped = 0; - byte[] b = new byte[2048]; + byte[] b = new byte[(int)Math.min(nbytes, 2048L)]; int x, v; while (skipped != nbytes) { x = in.read(b, 0, diff --git a/archive/src/main/java/java/util/zip/CheckedOutputStream.java b/archive/src/main/java/java/util/zip/CheckedOutputStream.java index 08fe799..3c19726 100644 --- a/archive/src/main/java/java/util/zip/CheckedOutputStream.java +++ b/archive/src/main/java/java/util/zip/CheckedOutputStream.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -34,7 +34,7 @@ public class CheckedOutputStream extends java.io.FilterOutputStream { * Constructs a new {@code CheckedOutputStream} on {@code OutputStream} * {@code os}. The checksum is calculated using the algorithm implemented * by {@code csum}. - * + * * @param os * the output stream to calculate checksum for. * @param cs @@ -47,7 +47,7 @@ public class CheckedOutputStream extends java.io.FilterOutputStream { /** * Returns the checksum calculated on the stream read so far. - * + * * @return the updated checksum. */ public Checksum getChecksum() { @@ -57,7 +57,7 @@ public class CheckedOutputStream extends java.io.FilterOutputStream { /** * Writes the specified byte to the underlying stream. The checksum is * updated with {@code val}. - * + * * @param val * the data value to written to the output stream. * @throws IOException @@ -72,7 +72,7 @@ public class CheckedOutputStream extends java.io.FilterOutputStream { /** * Writes n bytes of data from {@code buf} starting at offset {@code off} to * the underlying stream. The checksum is updated with the bytes written. - * + * * @param buf * data written to the output stream. * @param off diff --git a/archive/src/main/java/java/util/zip/Checksum.java b/archive/src/main/java/java/util/zip/Checksum.java index 901ff7a..fac7e4e 100644 --- a/archive/src/main/java/java/util/zip/Checksum.java +++ b/archive/src/main/java/java/util/zip/Checksum.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -25,7 +25,7 @@ public interface Checksum { /** * Returns the current calculated checksum value. - * + * * @return the checksum. */ public long getValue(); @@ -50,7 +50,7 @@ public interface Checksum { /** * Updates the checksum value with the given byte. - * + * * @param val * the byte to update the checksum with. */ diff --git a/archive/src/main/java/java/util/zip/DataFormatException.java b/archive/src/main/java/java/util/zip/DataFormatException.java index 1e9c5a2..ec4e867 100644 --- a/archive/src/main/java/java/util/zip/DataFormatException.java +++ b/archive/src/main/java/java/util/zip/DataFormatException.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/archive/src/main/java/java/util/zip/Deflater.java b/archive/src/main/java/java/util/zip/Deflater.java index 48ae479..eb49f12 100644 --- a/archive/src/main/java/java/util/zip/Deflater.java +++ b/archive/src/main/java/java/util/zip/Deflater.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -121,7 +121,7 @@ public class Deflater { * level. The strategy can be specified with {@code setStrategy}, only. A * header is added to the output by default; use * {@code Deflater(level, boolean)} if you need to omit the header. - * + * * @param level * the compression level in the range between 0 and 9. */ @@ -134,7 +134,7 @@ public class Deflater { * level. If noHeader is passed as true no ZLib header is added to the * output. In a ZIP archive every entry (compressed file) comes with such a * header. The strategy can be specified with the setStrategy method, only. - * + * * @param level * the compression level in the range between 0 and 9. * @param noHeader @@ -152,7 +152,7 @@ public class Deflater { /** * Deflates the data (previously passed to {@code setInput}) into the * supplied buffer. - * + * * @param buf * buffer to write compressed data to. * @return number of bytes of compressed data written to {@code buf}. @@ -165,7 +165,7 @@ public class Deflater { /** * Deflates data (previously passed to {@code setInput}) into a specific * region within the supplied buffer. - * + * * @param buf * the buffer to write compressed data to. * @param off @@ -225,7 +225,7 @@ public class Deflater { /** * Indicates to the {@code Deflater} that all uncompressed input has been provided * to it. - * + * * @see #finished */ public synchronized void finish() { @@ -235,7 +235,7 @@ public class Deflater { /** * Returns whether or not all provided data has been successfully * compressed. - * + * * @return true if all data has been compressed, false otherwise. */ public synchronized boolean finished() { @@ -246,7 +246,7 @@ public class Deflater { * Returns the Adler32 checksum of uncompressed data currently read. If a * preset dictionary is used getAdler() will return the Adler32 checksum of * the dictionary used. - * + * * @return the Adler32 checksum of uncompressed data or preset dictionary if * used. * @see #setDictionary(byte[]) @@ -264,7 +264,7 @@ public class Deflater { /** * Returns the total number of bytes of input consumed by the {@code Deflater}. - * + * * @return number of bytes of input read. */ public synchronized int getTotalIn() { @@ -279,7 +279,7 @@ public class Deflater { /** * Returns the total number of compressed bytes output by this {@code Deflater}. - * + * * @return number of compressed bytes output. */ public synchronized int getTotalOut() { @@ -298,7 +298,7 @@ public class Deflater { * returns true setInput() must be called before deflation can continue. If * all bytes of uncompressed data have been provided to the {@code Deflater} * finish() must be called to ensure the compressed data is output. - * + * * @return {@code true} if input is required for deflation to continue, * {@code false} otherwise. * @see #finished() @@ -317,7 +317,7 @@ public class Deflater { * previously made settings for the compression strategy or level. This * operation <i>must</i> be called after {@code finished()} returns * {@code true} if the {@code Deflater} is to be reused. - * + * * @see #finished */ public synchronized void reset() { @@ -338,7 +338,7 @@ public class Deflater { * setDictionary() can only be called if this {@code Deflater} supports the writing * of ZLIB headers. This is the default behaviour but can be overridden * using {@code Deflater(int, boolean)}. - * + * * @param buf * the buffer containing the dictionary data bytes. * @see Deflater#Deflater(int, boolean) @@ -380,7 +380,7 @@ public class Deflater { /** * Sets the input buffer the {@code Deflater} will use to extract uncompressed bytes * for later compression. - * + * * @param buf * the buffer. */ @@ -392,7 +392,7 @@ public class Deflater { * Sets the input buffer the {@code Deflater} will use to extract uncompressed bytes * for later compression. Input will be taken from the buffer region * starting at off and ending at nbytes - 1. - * + * * @param buf * the buffer containing the input data bytes. * @param off @@ -429,7 +429,7 @@ public class Deflater { * Sets the compression level to be used when compressing data. The * compression level must be a value between 0 and 9. This value must be set * prior to calling setInput(). - * + * * @param level * compression level to use * @exception IllegalArgumentException @@ -449,7 +449,7 @@ public class Deflater { * Sets the compression strategy to be used. The strategy must be one of * FILTERED, HUFFMAN_ONLY or DEFAULT_STRATEGY.This value must be set prior * to calling setInput(). - * + * * @param strategy * compression strategy to use * @exception IllegalArgumentException @@ -470,7 +470,7 @@ public class Deflater { * Returns a long int of total number of bytes read by the {@code Deflater}. This * method performs the same as {@code getTotalIn} except it returns a long value * instead of an integer - * + * * @see #getTotalIn() * @return total number of bytes read by {@code Deflater}. */ @@ -486,7 +486,7 @@ public class Deflater { * Returns a long int of total number of bytes of read by the {@code Deflater}. This * method performs the same as {@code getTotalOut} except it returns a long * value instead of an integer - * + * * @see #getTotalOut() * @return bytes exactly write by {@code Deflater} */ diff --git a/archive/src/main/java/java/util/zip/DeflaterOutputStream.java b/archive/src/main/java/java/util/zip/DeflaterOutputStream.java index 03769fb..197426f 100644 --- a/archive/src/main/java/java/util/zip/DeflaterOutputStream.java +++ b/archive/src/main/java/java/util/zip/DeflaterOutputStream.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -48,7 +48,7 @@ public class DeflaterOutputStream extends FilterOutputStream { /** * This constructor lets you pass the {@code Deflater} specifying the * compression algorithm. - * + * * @param os * is the {@code OutputStream} where to write the compressed data * to. @@ -66,7 +66,7 @@ public class DeflaterOutputStream extends FilterOutputStream { * default settings for the {@code Deflater} and internal buffer are used. * In particular the {@code Deflater} produces a ZLIB header in the output * stream. - * + * * @param os * is the OutputStream where to write the compressed data to. */ @@ -77,7 +77,7 @@ public class DeflaterOutputStream extends FilterOutputStream { /** * This constructor lets you specify both the compression algorithm as well * as the internal buffer size to be used. - * + * * @param os * is the {@code OutputStream} where to write the compressed data * to. @@ -102,7 +102,7 @@ public class DeflaterOutputStream extends FilterOutputStream { /** * Compress the data in the input buffer and write it to the underlying * stream. - * + * * @throws IOException * If an error occurs during deflation. */ @@ -118,7 +118,7 @@ public class DeflaterOutputStream extends FilterOutputStream { * Writes any unwritten compressed data to the underlying stream, the closes * all underlying streams. This stream can no longer be used after close() * has been called. - * + * * @throws IOException * If an error occurs while closing the data compression * process. @@ -135,7 +135,7 @@ public class DeflaterOutputStream extends FilterOutputStream { /** * Writes any unwritten data to the underlying stream. Does not close the * stream. - * + * * @throws IOException * If an error occurs. */ @@ -165,7 +165,7 @@ public class DeflaterOutputStream extends FilterOutputStream { /** * Compresses {@code nbytes} of data from {@code buf} starting at * {@code off} and writes it to the underlying stream. - * + * * @param buffer * the buffer of data to compress. * @param off diff --git a/archive/src/main/java/java/util/zip/GZIPInputStream.java b/archive/src/main/java/java/util/zip/GZIPInputStream.java index cc7a019..dd0da9b 100644 --- a/archive/src/main/java/java/util/zip/GZIPInputStream.java +++ b/archive/src/main/java/java/util/zip/GZIPInputStream.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -69,7 +69,7 @@ public class GZIPInputStream extends InflaterInputStream { /** * Construct a {@code GZIPInputStream} to read from GZIP data from the * underlying stream. Set the internal buffer size to {@code size}. - * + * * @param is * the {@code InputStream} to read data from. * @param size @@ -161,7 +161,6 @@ public class GZIPInputStream extends InflaterInputStream { if (closed) { throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$ } - // BEGIN android-changed if (eos) { return -1; } @@ -187,10 +186,8 @@ public class GZIPInputStream extends InflaterInputStream { } return bytesRead; - // END android-changed } - // BEGIN android-added private void verifyCrc() throws IOException { // Get non-compressed bytes read by fill int size = inf.getRemaining(); @@ -208,7 +205,6 @@ public class GZIPInputStream extends InflaterInputStream { throw new IOException(Messages.getString("archive.21")); //$NON-NLS-1$ } } - // END android-added private void readFully(byte[] buffer, int offset, int length) throws IOException { diff --git a/archive/src/main/java/java/util/zip/GZIPOutputStream.java b/archive/src/main/java/java/util/zip/GZIPOutputStream.java index f146da1..02510db 100644 --- a/archive/src/main/java/java/util/zip/GZIPOutputStream.java +++ b/archive/src/main/java/java/util/zip/GZIPOutputStream.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -34,7 +34,7 @@ public class GZIPOutputStream extends DeflaterOutputStream { /** * Construct a new {@code GZIPOutputStream} to write data in GZIP format to * the underlying stream. - * + * * @param os * the {@code OutputStream} to write data to. * @throws IOException @@ -48,7 +48,7 @@ public class GZIPOutputStream extends DeflaterOutputStream { * Construct a new {@code GZIPOutputStream} to write data in GZIP format to * the underlying stream. Set the internal compression buffer to size * {@code size}. - * + * * @param os * the {@code OutputStream} to write to. * @param size diff --git a/archive/src/main/java/java/util/zip/Inflater.java b/archive/src/main/java/java/util/zip/Inflater.java index 048d959..4921d3d 100644 --- a/archive/src/main/java/java/util/zip/Inflater.java +++ b/archive/src/main/java/java/util/zip/Inflater.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,9 +19,7 @@ package java.util.zip; import org.apache.harmony.archive.internal.nls.Messages; -// BEGIN android-added -import java.io.FileDescriptor; -// END android-added +import java.io.FileDescriptor; // android-only /** * This class uncompresses data that was compressed using the <i>DEFLATE</i> @@ -40,8 +38,6 @@ import java.io.FileDescriptor; */ public class Inflater { - private static final byte MAGIC_NUMBER = 120; - static { oneTimeInitialization(); } @@ -51,20 +47,12 @@ public class Inflater { private boolean finished; // Set by the inflateImpl native - // BEGIN android-removed - // private boolean gotFirstHeaderByte; - // END android-removed - int inLength; int inRead; private boolean needsDictionary; // Set by the inflateImpl native - // BEGIN android-removed - // private boolean pass_magic_number_check = true; - // END android-removed - private long streamHandle = -1; /** @@ -86,9 +74,6 @@ public class Inflater { */ public Inflater(boolean noHeader) { streamHandle = createStream(noHeader); - // BEGIN android-removed - // gotFirstHeaderByte = noHeader; - // END android-removed } private native long createStream(boolean noHeader1); @@ -248,34 +233,32 @@ public class Inflater { public synchronized int inflate(byte[] buf, int off, int nbytes) throws DataFormatException { // avoid int overflow, check null buf - if (off <= buf.length && nbytes >= 0 && off >= 0 - && buf.length - off >= nbytes) { - if (nbytes == 0) - return 0; - - if (streamHandle == -1) { - throw new IllegalStateException(); - } - - // BEGIN android-removed - // if (!pass_magic_number_check) { - // throw new DataFormatException(); - // } - // END android-removed - - if (needsInput()) { - return 0; - } - - boolean neededDict = needsDictionary; - needsDictionary = false; - int result = inflateImpl(buf, off, nbytes, streamHandle); - if (needsDictionary && neededDict) { - throw new DataFormatException(Messages.getString("archive.27")); //$NON-NLS-1$ - } - return result; + if (off > buf.length || nbytes < 0 || off < 0 + || buf.length - off < nbytes) { + throw new ArrayIndexOutOfBoundsException(); + } + + if (nbytes == 0) { + return 0; + } + + if (streamHandle == -1) { + throw new IllegalStateException(); } - throw new ArrayIndexOutOfBoundsException(); + + if (needsInput()) { + return 0; + } + + boolean neededDict = needsDictionary; + needsDictionary = false; + int result = inflateImpl(buf, off, nbytes, streamHandle); + if (needsDictionary && neededDict) { + throw new DataFormatException( + Messages.getString("archive.27")); //$NON-NLS-1$ + } + + return result; } private native synchronized int inflateImpl(byte[] buf, int off, @@ -407,21 +390,14 @@ public class Inflater { } else { throw new ArrayIndexOutOfBoundsException(); } - - // BEGIN android-removed - // if (!gotFirstHeaderByte && nbytes > 0) { - // pass_magic_number_check = (buf[off] == MAGIC_NUMBER); - // gotFirstHeaderByte = true; - //} - // END android-removed } - // BEGIN android-added + // BEGIN android-only /** * Sets the current input to the region within a file starting at {@code * off} and ending at {@code nbytes - 1}. This method should only be called * if {@code needsInput()} returns {@code true}. - * + * * @param fd * the input file. * @param off @@ -438,13 +414,13 @@ public class Inflater { inLength = setFileInputImpl(fd, off, nbytes, streamHandle); return inLength; } - // END android-added + // END android-only private native synchronized void setInputImpl(byte[] buf, int off, int nbytes, long handle); - // BEGIN android-added + // BEGIN android-only private native synchronized int setFileInputImpl(FileDescriptor fd, long off, int nbytes, long handle); - // END android-added + // END android-only } diff --git a/archive/src/main/java/java/util/zip/InflaterInputStream.java b/archive/src/main/java/java/util/zip/InflaterInputStream.java index 8a7c86b..d239a8a 100644 --- a/archive/src/main/java/java/util/zip/InflaterInputStream.java +++ b/archive/src/main/java/java/util/zip/InflaterInputStream.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -62,9 +62,7 @@ public class InflaterInputStream extends FilterInputStream { static final int BUF_SIZE = 512; - // BEGIN android-added - int nativeEndBufSize = 0; - // END android-added + int nativeEndBufSize = 0; // android-only /** * This is the most basic constructor. You only need to pass the {@code @@ -112,13 +110,13 @@ public class InflaterInputStream extends FilterInputStream { throw new IllegalArgumentException(); } this.inf = inf; - // BEGIN android-changed + // BEGIN android-only if (is instanceof ZipFile.RAFStream) { nativeEndBufSize = bsize; } else { buf = new byte[bsize]; } - // END android-changed + // END android-only } /** @@ -170,7 +168,6 @@ public class InflaterInputStream extends FilterInputStream { return 0; } - // BEGIN android-changed if (eof) { return -1; } @@ -210,7 +207,6 @@ public class InflaterInputStream extends FilterInputStream { throw (IOException) (new IOException().initCause(e)); } } while (true); - // END android-changed } /** @@ -223,7 +219,7 @@ public class InflaterInputStream extends FilterInputStream { if (closed) { throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$ } - // BEGIN android-changed + // BEGIN android-only if (nativeEndBufSize > 0) { ZipFile.RAFStream is = (ZipFile.RAFStream)in; synchronized (is.mSharedRaf) { @@ -237,7 +233,7 @@ public class InflaterInputStream extends FilterInputStream { inf.setInput(buf, 0, len); } } - // END android-changed + // END android-only } /** @@ -252,20 +248,15 @@ public class InflaterInputStream extends FilterInputStream { @Override public long skip(long nbytes) throws IOException { if (nbytes >= 0) { - // BEGIN android-changed if (buf == null) { - buf = new byte[BUF_SIZE]; + buf = new byte[(int)Math.min(nbytes, BUF_SIZE)]; } - // END android-changed long count = 0, rem = 0; while (count < nbytes) { int x = read(buf, 0, (rem = nbytes - count) > buf.length ? buf.length : (int) rem); if (x == -1) { - // BEGIN android-removed - // eof = true; - // END android-removed return count; } count += x; diff --git a/archive/src/main/java/java/util/zip/ZipConstants.java b/archive/src/main/java/java/util/zip/ZipConstants.java index d00adc9..9fbce06 100644 --- a/archive/src/main/java/java/util/zip/ZipConstants.java +++ b/archive/src/main/java/java/util/zip/ZipConstants.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/archive/src/main/java/java/util/zip/ZipEntry.java b/archive/src/main/java/java/util/zip/ZipEntry.java index 9774b6a..75466ce 100644 --- a/archive/src/main/java/java/util/zip/ZipEntry.java +++ b/archive/src/main/java/java/util/zip/ZipEntry.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,14 +17,11 @@ package java.util.zip; -// BEGIN android-added import java.io.EOFException; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.io.RandomAccessFile; import java.io.UnsupportedEncodingException; -// END android-added import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; @@ -44,52 +41,13 @@ public class ZipEntry implements ZipConstants, Cloneable { String name, comment; long compressedSize = -1, crc = -1, size = -1; - // BEGIN android-removed - // long dataOffset = -1; - // END android-removed int compressionMethod = -1, time = -1, modDate = -1; byte[] extra; - // BEGIN android-added - /* - * Fields, present in the Central Directory Entry and Local File Entry. - * - * Not all of these are part of the interface, but we need them if we - * want to be able to copy entries from one archive to another without - * losing any meta-data. - * - * We use over-sized fields so we can indicate whether a field has been - * initialized or not. - */ - private int mVersionMadeBy; // CDE - private int mVersionToExtract; // CDE, LFE - private int mGPBitFlag; // CDE, LFE - // private int mCompressionMethod; // CDE, LFE = compressionMethod - // private int mLastModFileTime; // CDE, LFE = time - // private int mLastModFileDate; // CDE, LFE = modDate - // private long mCRC32; // CDE, LFE = crc - // private long mCompressedSize; // CDE, LFE = compressedSize - // private long mUncompressedSize; // CDE, LFE = size - int nameLen, extraLen, commentLen; - //private int mFileNameLength; // CDE, LFE - //private int mExtraFieldLength; // CDE, LFE - //private int mFileCommentLength; // CDE - private int mDiskNumberStart; // CDE - private int mInternalAttrs; // CDE - private long mExternalAttrs; // CDE - long mLocalHeaderRelOffset; // CDE ? dataOffset - // private String mFileName; // CDE, LFE = name - // private byte[] mExtraField; // CDE, LFE = extra - // private String mFileComment; // CDE = comment - - - // GPBitFlag 3: uses a Data Descriptor block (need for deflated data) - /*package*/ static final int USES_DATA_DESCR = 0x0008; - - // private static Calendar mCalendar = Calendar.getInstance(); - // END android-added + int nameLen = -1; + long mLocalHeaderRelOffset = -1; /** * Zip entry state: Deflated. @@ -117,26 +75,6 @@ public class ZipEntry implements ZipConstants, Cloneable { throw new IllegalArgumentException(); } this.name = name; - - // BEGIN android-added - mVersionMadeBy = 0x0317; // 03=UNIX, 17=spec v2.3 - mVersionToExtract = 20; // need deflate, not much else - mGPBitFlag = 0; - compressionMethod = -1; - time = -1; - modDate = -1; - crc = -1L; - compressedSize = -1L; - size = -1L; - extraLen = -1; - nameLen = -1; - mDiskNumberStart = 0; - mInternalAttrs = 0; - mExternalAttrs = 0x81b60020L; // matches WinZip - mLocalHeaderRelOffset = -1; - extra = null; - comment = null; - // END android-added } /** @@ -358,23 +296,6 @@ public class ZipEntry implements ZipConstants, Cloneable { return name; } - // BEGIN android-removed - // ZipEntry(String name, String comment, byte[] extra, long modTime, - // long size, long compressedSize, long crc, int compressionMethod, - // long modDate, long offset) { - // this.name = name; - // this.comment = comment; - // this.extra = extra; - // time = (int) modTime; - // this.size = size; - // this.compressedSize = compressedSize; - // this.crc = crc; - // this.compressionMethod = compressionMethod; - // this.modDate = (int) modDate; - // dataOffset = offset; - // } - // END android-removed - /** * Constructs a new {@code ZipEntry} using the values obtained from {@code * ze}. @@ -392,20 +313,8 @@ public class ZipEntry implements ZipConstants, Cloneable { compressionMethod = ze.compressionMethod; modDate = ze.modDate; extra = ze.extra; - // BEGIN android-removed - // dataOffset = ze.dataOffset; - // END android-removed - // BEGIN android-added - mVersionMadeBy = ze.mVersionMadeBy; - mVersionToExtract = ze.mVersionToExtract; - mGPBitFlag = ze.mGPBitFlag; - extraLen = ze.extraLen; nameLen = ze.nameLen; - mDiskNumberStart = ze.mDiskNumberStart; - mInternalAttrs = ze.mInternalAttrs; - mExternalAttrs = ze.mExternalAttrs; mLocalHeaderRelOffset = ze.mLocalHeaderRelOffset; - // END android-added } /** @@ -428,9 +337,6 @@ public class ZipEntry implements ZipConstants, Cloneable { return name.hashCode(); } - // BEGIN android-added - // readShortLE is not used. - // readIntLE is used only once in ZipFile. /* * Internal constructor. Creates a new ZipEntry by reading the * Central Directory Entry from "in", which must be positioned at @@ -438,7 +344,7 @@ public class ZipEntry implements ZipConstants, Cloneable { * * On exit, "in" will be positioned at the start of the next entry. */ - /*package*/ ZipEntry(LittleEndianReader ler, InputStream in) throws IOException { + ZipEntry(LittleEndianReader ler, InputStream in) throws IOException { /* * We're seeing performance issues when we call readShortLE and @@ -456,12 +362,10 @@ public class ZipEntry implements ZipConstants, Cloneable { long sig = (hdrBuf[0] & 0xff) | ((hdrBuf[1] & 0xff) << 8) | ((hdrBuf[2] & 0xff) << 16) | ((hdrBuf[3] << 24) & 0xffffffffL); - if (sig != CENSIG) + if (sig != CENSIG) { throw new ZipException("Central Directory Entry not found"); + } - mVersionMadeBy = (hdrBuf[4] & 0xff) | ((hdrBuf[5] & 0xff) << 8); - mVersionToExtract = (hdrBuf[6] & 0xff) | ((hdrBuf[7] & 0xff) << 8); - mGPBitFlag = (hdrBuf[8] & 0xff) | ((hdrBuf[9] & 0xff) << 8); compressionMethod = (hdrBuf[10] & 0xff) | ((hdrBuf[11] & 0xff) << 8); time = (hdrBuf[12] & 0xff) | ((hdrBuf[13] & 0xff) << 8); modDate = (hdrBuf[14] & 0xff) | ((hdrBuf[15] & 0xff) << 8); @@ -475,13 +379,8 @@ public class ZipEntry implements ZipConstants, Cloneable { | ((hdrBuf[26] & 0xff) << 16) | ((hdrBuf[27] << 24) & 0xffffffffL); nameLen = (hdrBuf[28] & 0xff) | ((hdrBuf[29] & 0xff) << 8); - extraLen = (hdrBuf[30] & 0xff) | ((hdrBuf[31] & 0xff) << 8); - commentLen = (hdrBuf[32] & 0xff) | ((hdrBuf[33] & 0xff) << 8); - mDiskNumberStart = (hdrBuf[34] & 0xff) | ((hdrBuf[35] & 0xff) << 8); - mInternalAttrs = (hdrBuf[36] & 0xff) | ((hdrBuf[37] & 0xff) << 8); - mExternalAttrs = (hdrBuf[38] & 0xff) | ((hdrBuf[39] & 0xff) << 8) - | ((hdrBuf[40] & 0xff) << 16) - | ((hdrBuf[41] << 24) & 0xffffffffL); + int extraLen = (hdrBuf[30] & 0xff) | ((hdrBuf[31] & 0xff) << 8); + int commentLen = (hdrBuf[32] & 0xff) | ((hdrBuf[33] & 0xff) << 8); mLocalHeaderRelOffset = (hdrBuf[42] & 0xff) | ((hdrBuf[43] & 0xff) << 8) | ((hdrBuf[44] & 0xff) << 16) | ((hdrBuf[45] << 24) & 0xffffffffL); @@ -510,82 +409,42 @@ public class ZipEntry implements ZipConstants, Cloneable { * TODO: add correct UTF-8 support. */ name = new String(nameBytes, "ISO-8859-1"); - if (commentBytes != null) + if (commentBytes != null) { comment = new String(commentBytes, "ISO-8859-1"); - else + } else { comment = null; - } - catch (UnsupportedEncodingException uee) { + } + } catch (UnsupportedEncodingException uee) { throw new InternalError(uee.getMessage()); } } + private void myReadFully(InputStream in, byte[] b) throws IOException { - int count; int len = b.length; int off = 0; while (len > 0) { - count = in.read(b, off, len); - if (count <= 0) + int count = in.read(b, off, len); + if (count <= 0) { throw new EOFException(); + } off += count; len -= count; } } - /*package*/ void setVersionToExtract(int version) { - mVersionToExtract = version; - } - - /*package*/ int getGPBitFlag() { - return mGPBitFlag; - } - /*package*/ void setGPBitFlag(int flags) { - mGPBitFlag = flags; - } - - /*package*/ long getLocalHeaderRelOffset() { - return mLocalHeaderRelOffset; - } - /*package*/ void setLocalHeaderRelOffset(long offset) { - mLocalHeaderRelOffset = offset; - } - - /*package*/ void setDateTime(int lastModFileDate, int lastModFileTime) { - time = lastModFileTime; - modDate = lastModFileDate; - } - - /* - * Read a two-byte short in little-endian order. - * - * The DataInput interface, which RandomAccessFile implements, provides - * a readInt() function. Unfortunately, it's defined to use big-endian. - */ - /*package*/ static int readShortLE(RandomAccessFile raf) throws IOException - { - int b0, b1; - - b0 = raf.read(); - b1 = raf.read(); - if (b1 < 0) - throw new EOFException("in ZipEntry.readShortLE(RandomAccessFile)"); - return b0 | (b1 << 8); - } - /* * Read a four-byte int in little-endian order. */ - /*package*/ static long readIntLE(RandomAccessFile raf) throws IOException - { - int b0, b1, b2, b3; - - b0 = raf.read(); - b1 = raf.read(); - b2 = raf.read(); - b3 = raf.read(); - if (b3 < 0) + static long readIntLE(RandomAccessFile raf) throws IOException { + int b0 = raf.read(); + int b1 = raf.read(); + int b2 = raf.read(); + int b3 = raf.read(); + + if (b3 < 0) { throw new EOFException("in ZipEntry.readIntLE(RandomAccessFile)"); + } return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24); // ATTENTION: DOES SIGN EXTENSION: IS THIS WANTED? } @@ -619,137 +478,4 @@ public class ZipEntry implements ZipConstants, Cloneable { } } } - - /* - * Write a two-byte short in little-endian order. - */ - /*package*/ static void writeShortLE(OutputStream out, int val) - throws IOException - { - out.write(val & 0xff); - out.write((val >> 8) & 0xff); - } - - /* - * Write a 4-byte int in little-endian order. This takes a long because - * all of our 4-byte values are stored locally in longs. - */ - /*package*/ static void writeIntLE(OutputStream out, long val) - throws IOException - { - if (val < 0) - throw new InternalError(); - out.write((int) val & 0xff); - out.write(((int) val >> 8) & 0xff); - out.write(((int) val >> 16) & 0xff); - out.write(((int) val >> 24) & 0xff); - } - - /* - * Write the Local File Header for this entry to the specified stream. - * - * Returns the #of bytes written. - */ - /*package*/ int writeLFH(OutputStream out) throws IOException { - if (compressionMethod < 0 || - time < 0 || - modDate < 0 || - crc < 0 || - compressedSize < 0 || - size < 0) - throw new InternalError(); - - writeIntLE(out, LOCSIG); - writeShortLE(out, mVersionToExtract); - writeShortLE(out, mGPBitFlag); - writeShortLE(out, compressionMethod); - writeShortLE(out, time); - writeShortLE(out, modDate); - writeIntLE(out, crc); - writeIntLE(out, compressedSize); - writeIntLE(out, size); - - byte[] nameBytes; - try { - nameBytes = name.getBytes("ISO-8859-1"); - } - catch (UnsupportedEncodingException uee) { - throw new InternalError(uee.getMessage()); - } - - int extraLen = 0; - if (extra != null) - extraLen = extra.length; - - writeShortLE(out, nameBytes.length); - writeShortLE(out, extraLen); - out.write(nameBytes); - if (extra != null) - out.write(extra); - - return LOCHDR + nameBytes.length + extraLen; - } - - /* - * Write the Data Descriptor for this entry to the specified stream. - * - * Returns the #of bytes written. - */ - /*package*/ int writeDD(OutputStream out) throws IOException { - writeIntLE(out, EXTSIG); - writeIntLE(out, crc); - writeIntLE(out, compressedSize); - writeIntLE(out, size); - return EXTHDR; - } - - /* - * Write the Central Directory Entry for this entry. - * - * Returns the #of bytes written. - */ - /*package*/ int writeCDE(OutputStream out) throws IOException { - writeIntLE(out, CENSIG); - writeShortLE(out, mVersionMadeBy); - writeShortLE(out, mVersionToExtract); - writeShortLE(out, mGPBitFlag); - writeShortLE(out, compressionMethod); - writeShortLE(out, time); - writeShortLE(out, modDate); - writeIntLE(out, crc); - writeIntLE(out, compressedSize); - writeIntLE(out, size); - - byte[] nameBytes = null, commentBytes = null; - try { - nameBytes = name.getBytes("ISO-8859-1"); - if (comment != null) - commentBytes = comment.getBytes("ISO-8859-1"); - } - catch (UnsupportedEncodingException uee) { - throw new InternalError(uee.getMessage()); - } - - int extraLen = 0, commentLen = 0; - if (extra != null) - extraLen = extra.length; - if (commentBytes != null) - commentLen = commentBytes.length; - - writeShortLE(out, nameBytes.length); - writeShortLE(out, extraLen); - writeShortLE(out, commentLen); - writeShortLE(out, mDiskNumberStart); - writeShortLE(out, mInternalAttrs); - writeIntLE(out, mExternalAttrs); - writeIntLE(out, mLocalHeaderRelOffset); - out.write(nameBytes); - if (extra != null) - out.write(extra); - if (commentBytes != null) - out.write(commentBytes); - - return CENHDR + nameBytes.length + extraLen + commentLen; - } - // END android-added } diff --git a/archive/src/main/java/java/util/zip/ZipException.java b/archive/src/main/java/java/util/zip/ZipException.java index 6dab26f..ad68714 100644 --- a/archive/src/main/java/java/util/zip/ZipException.java +++ b/archive/src/main/java/java/util/zip/ZipException.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -22,7 +22,7 @@ import java.io.IOException; /** * This runtime exception is thrown by {@code ZipFile} and {@code * ZipInputStream} when the file or stream is not a valid ZIP file. - * + * * @see ZipFile * @see ZipInputStream */ diff --git a/archive/src/main/java/java/util/zip/ZipFile.java b/archive/src/main/java/java/util/zip/ZipFile.java index b5f3678..48541e1 100644 --- a/archive/src/main/java/java/util/zip/ZipFile.java +++ b/archive/src/main/java/java/util/zip/ZipFile.java @@ -1,6 +1,4 @@ /* - * Copyright (C) 2007 The Android Open Source Project - * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. @@ -8,7 +6,7 @@ * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -26,10 +24,9 @@ import java.io.InputStream; import java.io.RandomAccessFile; import java.security.AccessController; import java.security.PrivilegedAction; -import java.util.ArrayList; import java.util.Enumeration; -import java.util.HashMap; -import java.util.NoSuchElementException; +import java.util.LinkedHashMap; +import java.util.Iterator; /** * This class provides random read access to a <i>ZIP-archive</i> file. @@ -47,10 +44,6 @@ import java.util.NoSuchElementException; */ public class ZipFile implements ZipConstants { - String fileName; - - File fileToDeleteOnClose; - /** * Open ZIP file for read. */ @@ -61,6 +54,17 @@ public class ZipFile implements ZipConstants { */ public static final int OPEN_DELETE = 4; + private final String fileName; + + private File fileToDeleteOnClose; + + private RandomAccessFile mRaf; + + private final ZipEntry.LittleEndianReader ler = new ZipEntry.LittleEndianReader(); + + private final LinkedHashMap<String, ZipEntry> mEntries + = new LinkedHashMap<String, ZipEntry>(); + /** * Constructs a new {@code ZipFile} with the specified file. * @@ -89,37 +93,26 @@ public class ZipFile implements ZipConstants { */ public ZipFile(File file, int mode) throws IOException { fileName = file.getPath(); - if (mode == OPEN_READ || mode == (OPEN_READ | OPEN_DELETE)) { - SecurityManager security = System.getSecurityManager(); + if (mode != OPEN_READ && mode != (OPEN_READ | OPEN_DELETE)) { + throw new IllegalArgumentException(); + } + + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkRead(fileName); + } + if ((mode & OPEN_DELETE) != 0) { if (security != null) { - security.checkRead(fileName); - } - if ((mode & OPEN_DELETE) != 0) { - if (security != null) { - security.checkDelete(fileName); - } - fileToDeleteOnClose = file; // file.deleteOnExit(); + security.checkDelete(fileName); } + fileToDeleteOnClose = file; // file.deleteOnExit(); } else { - throw new IllegalArgumentException(); + fileToDeleteOnClose = null; } mRaf = new RandomAccessFile(fileName, "r"); - mEntryList = new ArrayList<ZipEntry>(); - readCentralDir(); - - /* - * No LinkedHashMap yet, so optimize lookup-by-name by creating - * a parallel data structure. - */ - mFastLookup = new HashMap<String, ZipEntry>(mEntryList.size() * 2); - for (int i = 0; i < mEntryList.size(); i++) { - ZipEntry entry = mEntryList.get(i); - - mFastLookup.put(entry.getName(), entry); - } } /** @@ -181,20 +174,17 @@ public class ZipFile implements ZipConstants { */ public Enumeration<? extends ZipEntry> entries() { checkNotClosed(); + final Iterator<ZipEntry> iterator = mEntries.values().iterator(); return new Enumeration<ZipEntry>() { - private int i = 0; - public boolean hasMoreElements() { checkNotClosed(); - return i < mEntryList.size(); + return iterator.hasNext(); } public ZipEntry nextElement() { checkNotClosed(); - if (i >= mEntryList.size()) - throw new NoSuchElementException(); - return (ZipEntry) mEntryList.get(i++); + return iterator.next(); } }; } @@ -210,12 +200,15 @@ public class ZipFile implements ZipConstants { */ public ZipEntry getEntry(String entryName) { checkNotClosed(); - if (entryName != null) { - ZipEntry ze = mFastLookup.get(entryName); - if (ze == null) ze = mFastLookup.get(entryName + "/"); - return ze; + if (entryName == null) { + throw new NullPointerException(); + } + + ZipEntry ze = mEntries.get(entryName); + if (ze == null) { + ze = mEntries.get(entryName + "/"); } - throw new NullPointerException(); + return ze; } /** @@ -234,28 +227,28 @@ public class ZipFile implements ZipConstants { * the name lookup. */ entry = getEntry(entry.getName()); - if (entry == null) + if (entry == null) { return null; + } /* * Create a ZipInputStream at the right part of the file. */ RandomAccessFile raf = mRaf; synchronized (raf) { - // Unfortunately we don't know the entry data's start position. - // All we have is the position of the entry's local header. - // At position 28 we find the length of the extra data. - // In some cases this length differs from the one coming in - // the central header!!! + // We don't know the entry data's start position. All we have is the + // position of the entry's local header. At position 28 we find the + // length of the extra data. In some cases this length differs from + // the one coming in the central header. RAFStream rafstrm = new RAFStream(raf, entry.mLocalHeaderRelOffset + 28); int localExtraLenOrWhatever = ler.readShortLE(rafstrm); - // Now we need to skip the name - // and this "extra" data or whatever it is: + // Skip the name and this "extra" data or whatever it is: rafstrm.skip(entry.nameLen + localExtraLenOrWhatever); rafstrm.mLength = rafstrm.mOffset + entry.compressedSize; if (entry.compressionMethod == ZipEntry.DEFLATED) { - return new InflaterInputStream(rafstrm, new Inflater(true)); + int bufSize = Math.max(1024, (int)Math.min(entry.getSize(), 65535L)); + return new ZipInflaterInputStream(rafstrm, new Inflater(true), bufSize, entry); } else { return rafstrm; } @@ -279,26 +272,23 @@ public class ZipFile implements ZipConstants { */ public int size() { checkNotClosed(); - return mEntryList.size(); + return mEntries.size(); } - /* + /** * Find the central directory and read the contents. * - * The central directory can be followed by a variable-length comment + * <p>The central directory can be followed by a variable-length comment * field, so we have to scan through it backwards. The comment is at * most 64K, plus we have 18 bytes for the end-of-central-dir stuff * itself, plus apparently sometimes people throw random junk on the end * just for the fun of it. - * - * This is all a little wobbly. If the wrong value ends up in the EOCD - * area, we're hosed. This appears to be the way that everbody handles - * it though, so we're in pretty good company if this fails. + * + * <p>This is all a little wobbly. If the wrong value ends up in the EOCD + * area, we're hosed. This appears to be the way that everybody handles + * it though, so we're in good company if this fails. */ private void readCentralDir() throws IOException { - long scanOffset, stopOffset; - long sig; - /* * Scan back, looking for the End Of Central Directory field. If * the archive doesn't have a comment, we'll hit it on the first @@ -307,23 +297,26 @@ public class ZipFile implements ZipConstants { * No need to synchronize mRaf here -- we only do this when we * first open the Zip file. */ - scanOffset = mRaf.length() - ENDHDR; - if (scanOffset < 0) + long scanOffset = mRaf.length() - ENDHDR; + if (scanOffset < 0) { throw new ZipException("too short to be Zip"); + } - stopOffset = scanOffset - 65536; - if (stopOffset < 0) + long stopOffset = scanOffset - 65536; + if (stopOffset < 0) { stopOffset = 0; + } while (true) { mRaf.seek(scanOffset); - if (ZipEntry.readIntLE(mRaf) == 101010256L) + if (ZipEntry.readIntLE(mRaf) == 101010256L) { break; + } - //System.out.println("not found at " + scanOffset); scanOffset--; - if (scanOffset < stopOffset) + if (scanOffset < stopOffset) { throw new ZipException("EOCD not found; not a Zip archive?"); + } } /* @@ -336,23 +329,20 @@ public class ZipFile implements ZipConstants { */ RAFStream rafs = new RAFStream(mRaf, mRaf.getFilePointer()); BufferedInputStream bin = new BufferedInputStream(rafs, ENDHDR); - int diskNumber, diskWithCentralDir, numEntries, totalNumEntries; - //long centralDirSize; - long centralDirOffset; - //int commentLen; - - diskNumber = ler.readShortLE(bin); - diskWithCentralDir = ler.readShortLE(bin); - numEntries = ler.readShortLE(bin); - totalNumEntries = ler.readShortLE(bin); + + int diskNumber = ler.readShortLE(bin); + int diskWithCentralDir = ler.readShortLE(bin); + int numEntries = ler.readShortLE(bin); + int totalNumEntries = ler.readShortLE(bin); /*centralDirSize =*/ ler.readIntLE(bin); - centralDirOffset = ler.readIntLE(bin); + long centralDirOffset = ler.readIntLE(bin); /*commentLen =*/ ler.readShortLE(bin); if (numEntries != totalNumEntries || diskNumber != 0 || - diskWithCentralDir != 0) + diskWithCentralDir != 0) { throw new ZipException("spanned archives not supported"); + } /* * Seek to the first CDE and read all entries. @@ -360,38 +350,25 @@ public class ZipFile implements ZipConstants { rafs = new RAFStream(mRaf, centralDirOffset); bin = new BufferedInputStream(rafs, 4096); for (int i = 0; i < numEntries; i++) { - ZipEntry newEntry; - - newEntry = new ZipEntry(ler, bin); - mEntryList.add(newEntry); + ZipEntry newEntry = new ZipEntry(ler, bin); + mEntries.put(newEntry.getName(), newEntry); } } - /* - * Local data items. - */ - private RandomAccessFile mRaf; - - ZipEntry.LittleEndianReader ler = new ZipEntry.LittleEndianReader(); - - /* - * What we really want here is a LinkedHashMap, because we want fast - * lookups by name, but we want to preserve the ordering of the archive - * entries. Unfortunately we don't yet have a LinkedHashMap - * implementation. - */ - private ArrayList<ZipEntry> mEntryList; - private HashMap<String, ZipEntry> mFastLookup; - - /* - * Wrap a stream around a RandomAccessFile. The RandomAccessFile - * is shared among all streams returned by getInputStream(), so we - * have to synchronize access to it. (We can optimize this by - * adding buffering here to reduce collisions.) + /** + * Wrap a stream around a RandomAccessFile. The RandomAccessFile is shared + * among all streams returned by getInputStream(), so we have to synchronize + * access to it. (We can optimize this by adding buffering here to reduce + * collisions.) * - * We could support mark/reset, but we don't currently need them. + * <p>We could support mark/reset, but we don't currently need them. */ static class RAFStream extends InputStream { + + RandomAccessFile mSharedRaf; + long mOffset; + long mLength; + public RAFStream(RandomAccessFile raf, long pos) throws IOException { mSharedRaf = raf; mOffset = pos; @@ -403,36 +380,65 @@ public class ZipFile implements ZipConstants { return (mOffset < mLength ? 1 : 0); } + @Override public int read() throws IOException { - if (read(singleByteBuf, 0, 1) == 1) return singleByteBuf[0] & 0XFF; - else return -1; + byte[] singleByteBuf = new byte[1]; + if (read(singleByteBuf, 0, 1) == 1) { + return singleByteBuf[0] & 0XFF; + } else { + return -1; + } } + @Override public int read(byte[] b, int off, int len) throws IOException { - int count; synchronized (mSharedRaf) { mSharedRaf.seek(mOffset); - if (mOffset + len > mLength) len = (int) (mLength - mOffset); - count = mSharedRaf.read(b, off, len); + if (len > mLength - mOffset) { + len = (int) (mLength - mOffset); + } + int count = mSharedRaf.read(b, off, len); if (count > 0) { mOffset += count; + return count; + } else { + return -1; } - else return -1; } - return count; } @Override public long skip(long n) throws IOException { - if (mOffset + n > mLength) + if (n > mLength - mOffset) { n = mLength - mOffset; + } mOffset += n; return n; } + } + + static class ZipInflaterInputStream extends InflaterInputStream { - RandomAccessFile mSharedRaf; - long mOffset; - long mLength; - private byte[] singleByteBuf = new byte[1]; + ZipEntry entry; + long bytesRead = 0; + + public ZipInflaterInputStream(InputStream is, Inflater inf, int bsize, ZipEntry entry) { + super(is, inf, bsize); + this.entry = entry; + } + + @Override + public int read(byte[] buffer, int off, int nbytes) throws IOException { + int i = super.read(buffer, off, nbytes); + if (i != -1) { + bytesRead += i; + } + return i; + } + + @Override + public int available() throws IOException { + return super.available() == 0 ? 0 : (int) (entry.getSize() - bytesRead); + } } } diff --git a/archive/src/main/java/java/util/zip/ZipInputStream.java b/archive/src/main/java/java/util/zip/ZipInputStream.java index f86cbe0..554f5d5 100644 --- a/archive/src/main/java/java/util/zip/ZipInputStream.java +++ b/archive/src/main/java/java/util/zip/ZipInputStream.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -53,10 +53,6 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants static final int ZIPLocalHeaderVersionNeeded = 20; - // BEGIN android-removed - // private boolean zipClosed = false; - // END android-removed - private boolean entriesEnd = false; private boolean hasDD = false; @@ -96,12 +92,10 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants */ @Override public void close() throws IOException { - // BEGIN android-changed - if (closed != true) { + if (!closed) { closeEntry(); // Close the current entry super.close(); } - // END android-changed } /** @@ -111,11 +105,9 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants * if an {@code IOException} occurs. */ public void closeEntry() throws IOException { - // BEGIN android-changed if (closed) { throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$ } - // END android-changed if (currentEntry == null) { return; } @@ -311,7 +303,6 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants */ @Override public int read(byte[] buffer, int start, int length) throws IOException { - // BEGIN android-changed if (closed) { throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$ } @@ -364,7 +355,6 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants } crc.update(buffer, start, read); return read; - // END android-changed } /** @@ -378,20 +368,21 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants */ @Override public long skip(long value) throws IOException { - if (value >= 0) { - long skipped = 0; - byte[] b = new byte[1024]; - while (skipped != value) { - long rem = value - skipped; - int x = read(b, 0, (int) (b.length > rem ? rem : b.length)); - if (x == -1) { - return skipped; - } - skipped += x; + if (value < 0) { + throw new IllegalArgumentException(); + } + + long skipped = 0; + byte[] b = new byte[(int)Math.min(value, 2048L)]; + while (skipped != value) { + long rem = value - skipped; + int x = read(b, 0, (int) (b.length > rem ? rem : b.length)); + if (x == -1) { + return skipped; } - return skipped; + skipped += x; } - throw new IllegalArgumentException(); + return skipped; } /** @@ -403,12 +394,10 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants */ @Override public int available() throws IOException { - // BEGIN android-changed if (closed) { throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$ } return (currentEntry == null || inRead < currentEntry.size) ? 1 : 0; - // END android-changed } /** diff --git a/archive/src/main/java/java/util/zip/ZipOutputStream.java b/archive/src/main/java/java/util/zip/ZipOutputStream.java index 58e781f..21b4221 100644 --- a/archive/src/main/java/java/util/zip/ZipOutputStream.java +++ b/archive/src/main/java/java/util/zip/ZipOutputStream.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -79,7 +79,7 @@ public class ZipOutputStream extends DeflaterOutputStream implements /** * Constructs a new {@code ZipOutputStream} with the specified output * stream. - * + * * @param p1 * the {@code OutputStream} to write the data to. */ @@ -90,7 +90,7 @@ public class ZipOutputStream extends DeflaterOutputStream implements /** * Closes the current {@code ZipEntry}, if any, and the underlying output * stream. If the stream is already closed this method does nothing. - * + * * @throws IOException * If an error occurs closing the stream. */ @@ -106,7 +106,7 @@ public class ZipOutputStream extends DeflaterOutputStream implements /** * Closes the current {@code ZipEntry}. Any entry terminal data is written * to the underlying stream. - * + * * @throws IOException * If an error occurs closing the entry. */ @@ -191,7 +191,7 @@ public class ZipOutputStream extends DeflaterOutputStream implements /** * Indicates that all entries have been written to the stream. Any terminal * information is written to the underlying stream. - * + * * @throws IOException * if an error occurs while terminating the stream. */ @@ -235,7 +235,7 @@ public class ZipOutputStream extends DeflaterOutputStream implements * the entry can then be written using {@code write()}. After data is * written {@code closeEntry()} must be called to complete the writing of * the entry to the underlying stream. - * + * * @param ze * the {@code ZipEntry} to store. * @throws IOException @@ -323,7 +323,7 @@ public class ZipOutputStream extends DeflaterOutputStream implements /** * Sets the {@code ZipFile} comment associated with the file being written. - * + * * @param comment * the comment associated with the file. */ @@ -338,7 +338,7 @@ public class ZipOutputStream extends DeflaterOutputStream implements * Sets the compression level to be used for writing entry data. This level * may be set on a per entry basis. The level must have a value between -1 * and 8 according to the {@code Deflater} compression level bounds. - * + * * @param level * the compression level (ranging from -1 to 8). * @see Deflater @@ -355,7 +355,7 @@ public class ZipOutputStream extends DeflaterOutputStream implements * Sets the compression method to be used when compressing entry data. * method must be one of {@code STORED} (for no compression) or {@code * DEFLATED}. - * + * * @param method * the compression method to use. */ @@ -385,7 +385,7 @@ public class ZipOutputStream extends DeflaterOutputStream implements /** * Writes data for the current entry to the underlying stream. - * + * * @exception IOException * If an error occurs writing to the stream */ diff --git a/archive/src/main/java/org/apache/harmony/archive/internal/nls/Messages.java b/archive/src/main/java/org/apache/harmony/archive/internal/nls/Messages.java index 3ba50fa..f4f32e1 100644 --- a/archive/src/main/java/org/apache/harmony/archive/internal/nls/Messages.java +++ b/archive/src/main/java/org/apache/harmony/archive/internal/nls/Messages.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,7 +17,7 @@ /* * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL. - * All changes made to this file manually will be overwritten + * All changes made to this file manually will be overwritten * if this tool runs again. Better make changes in the template file. */ diff --git a/archive/src/main/java/org/apache/harmony/archive/internal/nls/messages.properties b/archive/src/main/java/org/apache/harmony/archive/internal/nls/messages.properties index e909af0..631101f 100644 --- a/archive/src/main/java/org/apache/harmony/archive/internal/nls/messages.properties +++ b/archive/src/main/java/org/apache/harmony/archive/internal/nls/messages.properties @@ -68,3 +68,4 @@ archive.31={0} failed verification of {1} archive.32={0} has invalid digest for {1} in {2} archive.33=A length of the encoded header name "{1}" exceeded maximum length {2} archive.34=A jar verifier does not support more than one entry with the same name +archive.35=JarFile has been closed diff --git a/archive/src/main/java/org/apache/harmony/archive/util/Util.java b/archive/src/main/java/org/apache/harmony/archive/util/Util.java index b15108a..2ac4e90 100644 --- a/archive/src/main/java/org/apache/harmony/archive/util/Util.java +++ b/archive/src/main/java/org/apache/harmony/archive/util/Util.java @@ -1,13 +1,13 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,62 +17,113 @@ package org.apache.harmony.archive.util; +/** + * Helpers for the archive module. + */ public class Util { - public static boolean ASCIIIgnoreCaseRegionMatches(String s1, int start1, - String s2, int start2, int length) { - - if (s1 != null && s2 != null) { - if (start1 < 0 || length > s1.length() - start1) { - return false; - } - if (start2 < 0 || length > s2.length() - start2) { + /** + * Returns whether the given source string ends with the suffix, ignoring + * case and assuming that the strings are ascii encoded. + * + * @param source + * the string to match. + * @param suffix + * the suffix to test. + * @return {@code true} if the source does end with the given suffix, or + * {@code false} if not. + */ + public static boolean asciiEndsWithIgnoreCase(String source, String suffix) { + int length = suffix.length(); + if (length > source.length()) { + return false; + } + int offset = source.length() - length; + for (int i = 0; i < length; i++) { + char c1 = source.charAt(i + offset); + char c2 = suffix.charAt(i); + if (c1 != c2 && toASCIIUpperCase(c1) != toASCIIUpperCase(c2)) { return false; } - - char c1, c2; - for (int i = 0; i < length; i++) { - if ((c1 = s1.charAt(start1++)) != (c2 = s2.charAt(start2++)) - && toASCIIUpperCase(c1) != toASCIIUpperCase(c2)) { - return false; - } - } - return true; } - throw new NullPointerException(); + return true; } - public static final boolean equalsIgnoreCase(byte[] buf1, byte[] buf2) { + /** + * Compares the given byte arrays and returns whether they are equal, + * ignoring case differences and assuming they are ascii-encoded strings. + * + * @param buf1 + * first byte array to compare. + * @param buf2 + * second byte array to compare. + * @return the result of the comparison. + */ + public static boolean asciiEqualsIgnoreCase(byte[] buf1, byte[] buf2) { + if (buf1 == null || buf2 == null) { + return false; + } if (buf1 == buf2) { return true; } - - if (buf1 == null || buf2 == null || buf1.length != buf2.length) { + if (buf1.length != buf2.length) { return false; } - byte b1, b2; - for (int i = 0; i < buf1.length; i++) { - if ((b1 = buf1[i]) != (b2 = buf2[i]) - && toASCIIUpperCase(b1) != toASCIIUpperCase(b2)) { + byte b1 = buf1[i]; + byte b2 = buf2[i]; + if (b1 != b2 && toASCIIUpperCase(b1) != toASCIIUpperCase(b2)) { return false; } } return true; } - static final char toASCIIUpperCase(char c) { - if ('a' <= c && c <= 'z') { - return (char) (c - ('a' - 'A')); + /** + * Compares the given strings and returns whether they are equal, ignoring + * case differences and assuming they are ascii-encoded strings. + * + * @param s1 + * first string to compare. + * @param s2 + * second string to compare. + * @return the result of the comparison. + */ + public static boolean asciiEqualsIgnoreCase(String s1, String s2) { + if (s1 == null || s2 == null) { + return false; } - return c; + if (s1 == s2) { + return true; + } + + int length = s1.length(); + if (length != s2.length()) { + return false; + } + + for (int i = 0; i < length; i++) { + char c1 = s1.charAt(i); + char c2 = s2.charAt(i); + if (c1 != c2 && toASCIIUpperCase(c1) != toASCIIUpperCase(c2)) { + return false; + } + } + return true; } - static final byte toASCIIUpperCase(byte b) { + private static final byte toASCIIUpperCase(byte b) { if ('a' <= b && b <= 'z') { return (byte) (b - ('a' - 'A')); } return b; } + + private static final char toASCIIUpperCase(char c) { + if ('a' <= c && c <= 'z') { + return (char) (c - ('a' - 'A')); + } + return c; + } } diff --git a/archive/src/main/native/java_util_zip_Inflater.c b/archive/src/main/native/java_util_zip_Inflater.c index c04a223..ba89ce8 100644 --- a/archive/src/main/native/java_util_zip_Inflater.c +++ b/archive/src/main/native/java_util_zip_Inflater.c @@ -81,7 +81,10 @@ Java_java_util_zip_Inflater_createStream (JNIEnv * env, jobject recv, jstream->inaddr = NULL; jstream->inCap = 0; - /*Unable to find official doc that this is the way to avoid zlib header use. However doc in zipsup.c claims it is so. */ + /* + * In the range 8..15 for checked, or -8..-15 for unchecked inflate. Unchecked + * is appropriate for formats like zip that do their own validity checking. + */ if (noHeader) wbits = wbits / -1; err = inflateInit2 (stream, wbits); /*Window bits to use. 15 is fastest but consumes the most memory */ diff --git a/archive/src/main/native/zipsup.c b/archive/src/main/native/zipsup.c index 22ea7e9..d6d07da 100644 --- a/archive/src/main/native/zipsup.c +++ b/archive/src/main/native/zipsup.c @@ -380,13 +380,13 @@ scanForCentralEnd (HyPortLibrary * portLib, HyZipFile * zipFile, { /* Found it. Read the data from the end-of-central-dir record. */ current = buffer + i + 4; - ZIP_NEXT_U16 (endEntry->diskNumber, current); - ZIP_NEXT_U16 (endEntry->dirStartDisk, current); - ZIP_NEXT_U16 (endEntry->thisDiskEntries, current); - ZIP_NEXT_U16 (endEntry->totalEntries, current); - ZIP_NEXT_U32 (endEntry->dirSize, current); - ZIP_NEXT_U32 (endEntry->dirOffset, current); - ZIP_NEXT_U16 (endEntry->commentLength, current); + (void) ZIP_NEXT_U16 (endEntry->diskNumber, current); + (void) ZIP_NEXT_U16 (endEntry->dirStartDisk, current); + (void) ZIP_NEXT_U16 (endEntry->thisDiskEntries, current); + (void) ZIP_NEXT_U16 (endEntry->totalEntries, current); + (void) ZIP_NEXT_U32 (endEntry->dirSize, current); + (void) ZIP_NEXT_U32 (endEntry->dirOffset, current); + (void) ZIP_NEXT_U16 (endEntry->commentLength, current); /* Quick test to ensure that the header isn't invalid. Current dataSize is the number of bytes of data scanned, up to the ^H in the stream. */ @@ -528,9 +528,9 @@ scanForDataDescriptor (HyPortLibrary * portLib, HyZipFile * zipFile, } /* Read the data from the descriptor. */ - ZIP_NEXT_U32 (zipEntry->crc32, current); - ZIP_NEXT_U32 (zipEntry->compressedSize, current); - ZIP_NEXT_U32 (zipEntry->uncompressedSize, current); + (void) ZIP_NEXT_U32 (zipEntry->crc32, current); + (void) ZIP_NEXT_U32 (zipEntry->compressedSize, current); + (void) ZIP_NEXT_U32 (zipEntry->uncompressedSize, current); /* Quick test to ensure that the header isn't invalid. Current dataSize is the number of bytes of data scanned, up to the ^H in the stream. */ @@ -680,7 +680,7 @@ zip_populateCache (HyPortLibrary * portLib, HyZipFile * zipFile) zipFile->pointer + (current - (buffer + bufferedSize)); sig = 0; - ZIP_NEXT_U32 (sig, current); + (void) ZIP_NEXT_U32 (sig, current); if (sig == ZIP_CentralEnd) { /* We're done here. */ @@ -695,22 +695,22 @@ zip_populateCache (HyPortLibrary * portLib, HyZipFile * zipFile) } /* Read ZIP_CentralHeader entry */ - ZIP_NEXT_U16 (entry.versionCreated, current); - ZIP_NEXT_U16 (entry.versionNeeded, current); - ZIP_NEXT_U16 (entry.flags, current); - ZIP_NEXT_U16 (entry.compressionMethod, current); - ZIP_NEXT_U16 (entry.lastModTime, current); - ZIP_NEXT_U16 (entry.lastModDate, current); - ZIP_NEXT_U32 (entry.crc32, current); - ZIP_NEXT_U32 (entry.compressedSize, current); - ZIP_NEXT_U32 (entry.uncompressedSize, current); - ZIP_NEXT_U16 (entry.filenameLength, current); - ZIP_NEXT_U16 (entry.extraFieldLength, current); - ZIP_NEXT_U16 (entry.fileCommentLength, current); + (void) ZIP_NEXT_U16 (entry.versionCreated, current); + (void) ZIP_NEXT_U16 (entry.versionNeeded, current); + (void) ZIP_NEXT_U16 (entry.flags, current); + (void) ZIP_NEXT_U16 (entry.compressionMethod, current); + (void) ZIP_NEXT_U16 (entry.lastModTime, current); + (void) ZIP_NEXT_U16 (entry.lastModDate, current); + (void) ZIP_NEXT_U32 (entry.crc32, current); + (void) ZIP_NEXT_U32 (entry.compressedSize, current); + (void) ZIP_NEXT_U32 (entry.uncompressedSize, current); + (void) ZIP_NEXT_U16 (entry.filenameLength, current); + (void) ZIP_NEXT_U16 (entry.extraFieldLength, current); + (void) ZIP_NEXT_U16 (entry.fileCommentLength, current); current += sizeof (U_16); /* skip disk number field */ - ZIP_NEXT_U16 (entry.internalAttributes, current); + (void) ZIP_NEXT_U16 (entry.internalAttributes, current); current += sizeof (U_32); /* skip external attributes field */ - ZIP_NEXT_U32 (localHeaderOffset, current); + (void) ZIP_NEXT_U32 (localHeaderOffset, current); /* Increase filename buffer size if necessary. */ if (filenameSize < entry.filenameLength + 1) @@ -909,7 +909,7 @@ retry: } zipFile->pointer += result; readLength = result; /* If it's not enough, we'll catch that later */ - ZIP_NEXT_U32 (sig, current); + (void) ZIP_NEXT_U32 (sig, current); if (enumerationPointer) { @@ -968,23 +968,23 @@ retry: { current += 2; /* skip versionCreated field */ } - ZIP_NEXT_U16 (zipEntry->versionNeeded, current); - ZIP_NEXT_U16 (zipEntry->flags, current); - ZIP_NEXT_U16 (zipEntry->compressionMethod, current); - ZIP_NEXT_U16 (zipEntry->lastModTime, current); - ZIP_NEXT_U16 (zipEntry->lastModDate, current); - ZIP_NEXT_U32 (zipEntry->crc32, current); - ZIP_NEXT_U32 (zipEntry->compressedSize, current); - ZIP_NEXT_U32 (zipEntry->uncompressedSize, current); - ZIP_NEXT_U16 (zipEntry->filenameLength, current); - ZIP_NEXT_U16 (zipEntry->extraFieldLength, current); + (void) ZIP_NEXT_U16 (zipEntry->versionNeeded, current); + (void) ZIP_NEXT_U16 (zipEntry->flags, current); + (void) ZIP_NEXT_U16 (zipEntry->compressionMethod, current); + (void) ZIP_NEXT_U16 (zipEntry->lastModTime, current); + (void) ZIP_NEXT_U16 (zipEntry->lastModDate, current); + (void) ZIP_NEXT_U32 (zipEntry->crc32, current); + (void) ZIP_NEXT_U32 (zipEntry->compressedSize, current); + (void) ZIP_NEXT_U32 (zipEntry->uncompressedSize, current); + (void) ZIP_NEXT_U16 (zipEntry->filenameLength, current); + (void) ZIP_NEXT_U16 (zipEntry->extraFieldLength, current); zipEntry->fileCommentLength = 0; if (sig == ZIP_CentralHeader) { - ZIP_NEXT_U16 (zipEntry->fileCommentLength, current); + (void) ZIP_NEXT_U16 (zipEntry->fileCommentLength, current); current += 8; /* skip disk number start + internal attrs + external attrs */ - ZIP_NEXT_U32 (localEntryPointer, current); + (void) ZIP_NEXT_U32 (localEntryPointer, current); } if (filename) @@ -1081,7 +1081,7 @@ retry: { if (hyfile_read (zipFile->fd, buf, 2) == 2) { - ZIP_NEXT_U16 (lost, buf2); + (void) ZIP_NEXT_U16 (lost, buf2); zipEntry->dataPointer = zipEntry->extraFieldPointer + lost; zipFile->pointer = localEntryPointer + 30; } diff --git a/archive/src/test/java-internal/org/apache/harmony/archive/util/UtilTest.java b/archive/src/test/java-internal/org/apache/harmony/archive/util/UtilTest.java index 9c28dc2..7e1c4bd 100644 --- a/archive/src/test/java-internal/org/apache/harmony/archive/util/UtilTest.java +++ b/archive/src/test/java-internal/org/apache/harmony/archive/util/UtilTest.java @@ -43,44 +43,27 @@ public class UtilTest extends TestCase { } } - public void testASCIIIgnoreCaseRegionMatches() { + public void testasciiEndsWithIgnoreCase() { final String s1 = ASCII_ALPHABET_LC; final String s2 = ASCII_ALPHABET_UC; - for (int i = 0; i < s1.length(); i++) { - assertTrue(Util.ASCIIIgnoreCaseRegionMatches(s1, i, s2, i, s1 - .length() - - i)); - } + assertTrue(Util.asciiEndsWithIgnoreCase(s1, s2)); + assertTrue(Util.asciiEndsWithIgnoreCase(s2, s1)); + assertTrue(Util.asciiEndsWithIgnoreCase(s1, "wxyz")); } - public void testToASCIIUpperCaseByte() { - for (int i = 0; i < ASCII_ALPHABET_LC_BYTES.length; i++) { - assertEquals(ASCII_ALPHABET_UC_BYTES[i], Util - .toASCIIUpperCase(ASCII_ALPHABET_LC_BYTES[i])); - } - for (int i = 0; i < ASCII_ALPHABET_UC_BYTES.length; i++) { - assertEquals(ASCII_ALPHABET_UC_BYTES[i], Util - .toASCIIUpperCase(ASCII_ALPHABET_UC_BYTES[i])); - } - } - - public void testToASCIIUpperCaseChar() { - for (int i = 0; i < ASCII_ALPHABET_LC.length(); i++) { - assertEquals(ASCII_ALPHABET_UC.charAt(i), Util - .toASCIIUpperCase(ASCII_ALPHABET_LC.charAt(i))); - } - for (int i = 0; i < ASCII_ALPHABET_UC.length(); i++) { - assertEquals(ASCII_ALPHABET_UC.charAt(i), Util - .toASCIIUpperCase(ASCII_ALPHABET_UC.charAt(i))); - } + public void testasciiEqualsIgnoreCase() { + final String s1 = ASCII_ALPHABET_LC; + final String s2 = ASCII_ALPHABET_UC; + assertTrue(Util.asciiEqualsIgnoreCase(s1, s2)); + assertTrue(Util.asciiEqualsIgnoreCase(s2, s1)); } public void testEqualsIgnoreCaseByteArrayByteArray() { - assertTrue(Util.equalsIgnoreCase(ASCII_ALPHABET_LC_BYTES, + assertTrue(Util.asciiEqualsIgnoreCase(ASCII_ALPHABET_LC_BYTES, ASCII_ALPHABET_LC_BYTES)); - assertTrue(Util.equalsIgnoreCase(ASCII_ALPHABET_LC_BYTES, + assertTrue(Util.asciiEqualsIgnoreCase(ASCII_ALPHABET_LC_BYTES, ASCII_ALPHABET_UC_BYTES)); - assertTrue(Util.equalsIgnoreCase(ASCII_ALPHABET_UC_BYTES, + assertTrue(Util.asciiEqualsIgnoreCase(ASCII_ALPHABET_UC_BYTES, ASCII_ALPHABET_UC_BYTES)); } |