diff options
author | William Luh <williamluh@google.com> | 2013-04-02 10:07:27 -0700 |
---|---|---|
committer | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2013-07-12 00:14:37 +0100 |
commit | 63cd29402915755aa929f960d8f73ff0235999a9 (patch) | |
tree | 305fe247193040b738369989e97e065f8e5ab3e4 | |
parent | 53ce79b30131043ecb74833560fc05bf43900116 (diff) | |
download | libcore-63cd29402915755aa929f960d8f73ff0235999a9.zip libcore-63cd29402915755aa929f960d8f73ff0235999a9.tar.gz libcore-63cd29402915755aa929f960d8f73ff0235999a9.tar.bz2 |
Don't install APK files with unsupported General Purpose Bit Flag bits.
Bug: 8476102
Change-Id: I764c2aec944558129c8ac04ee0593fb3de82870e
Conflicts:
luni/src/main/java/java/util/zip/ZipFile.java
-rw-r--r-- | luni/src/main/java/java/util/zip/ZipEntry.java | 8 | ||||
-rw-r--r-- | luni/src/main/java/java/util/zip/ZipFile.java | 24 | ||||
-rw-r--r-- | luni/src/main/java/java/util/zip/ZipInputStream.java | 4 |
3 files changed, 30 insertions, 6 deletions
diff --git a/luni/src/main/java/java/util/zip/ZipEntry.java b/luni/src/main/java/java/util/zip/ZipEntry.java index c313666..6dd9839 100644 --- a/luni/src/main/java/java/util/zip/ZipEntry.java +++ b/luni/src/main/java/java/util/zip/ZipEntry.java @@ -365,7 +365,13 @@ public class ZipEntry implements ZipConstants, Cloneable { throw new ZipException("Central Directory Entry not found"); } - it.seek(10); + it.seek(8); + int gpbf = it.readShort(); + + if ((gpbf & ~ZipFile.GPBF_SUPPORTED_MASK) != 0) { + throw new ZipException("Invalid General Purpose Bit Flag: " + gpbf); + } + compressionMethod = it.readShort(); time = it.readShort(); modDate = it.readShort(); diff --git a/luni/src/main/java/java/util/zip/ZipFile.java b/luni/src/main/java/java/util/zip/ZipFile.java index 6e8b516..1a77e6c 100644 --- a/luni/src/main/java/java/util/zip/ZipFile.java +++ b/luni/src/main/java/java/util/zip/ZipFile.java @@ -69,7 +69,13 @@ public class ZipFile implements ZipConstants { static final int GPBF_UTF8_FLAG = 1 << 11; /** - * Open ZIP file for reading. + * Supported General Purpose Bit Flags Mask. + * Bit mask of supported GPBF bits. + */ + static final int GPBF_SUPPORTED_MASK = GPBF_DATA_DESCRIPTOR_FLAG | GPBF_UTF8_FLAG; + + /** + * Open zip file for reading. */ public static final int OPEN_READ = 1; @@ -243,11 +249,19 @@ public class ZipFile implements ZipConstants { RandomAccessFile raf = mRaf; synchronized (raf) { // 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 rafStream = new RAFStream(raf, entry.mLocalHeaderRelOffset + 28); + // position of the entry's local header. At position 6 we find the + // General Purpose Bit Flag. + // http://www.pkware.com/documents/casestudies/APPNOTE.TXT + RAFStream rafStream= new RAFStream(raf, entry.mLocalHeaderRelOffset + 6); DataInputStream is = new DataInputStream(rafStream); + int gpbf = Short.reverseBytes(is.readShort()); + if ((gpbf & ~ZipFile.GPBF_SUPPORTED_MASK) != 0) { + throw new ZipException("Invalid General Purpose Bit Flag: " + gpbf); + } + + // 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. + is.skipBytes(20); int localExtraLenOrWhatever = Short.reverseBytes(is.readShort()); is.close(); diff --git a/luni/src/main/java/java/util/zip/ZipInputStream.java b/luni/src/main/java/java/util/zip/ZipInputStream.java index 57d9034..319a0fa 100644 --- a/luni/src/main/java/java/util/zip/ZipInputStream.java +++ b/luni/src/main/java/java/util/zip/ZipInputStream.java @@ -240,6 +240,10 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants throw new ZipException("Cannot read local header version " + version); } int flags = peekShort(LOCFLG - LOCVER); + if ((flags & ~ZipFile.GPBF_SUPPORTED_MASK) != 0) { + throw new ZipException("Invalid General Purpose Bit Flag: " + flags); + } + hasDD = ((flags & ZipFile.GPBF_DATA_DESCRIPTOR_FLAG) != 0); int ceLastModifiedTime = peekShort(LOCTIM - LOCVER); int ceLastModifiedDate = peekShort(LOCTIM - LOCVER + 2); |