summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Luh <williamluh@google.com>2013-04-02 10:07:27 -0700
committerRicardo Cerqueira <cyanogenmod@cerqueira.org>2013-07-12 00:14:37 +0100
commit63cd29402915755aa929f960d8f73ff0235999a9 (patch)
tree305fe247193040b738369989e97e065f8e5ab3e4
parent53ce79b30131043ecb74833560fc05bf43900116 (diff)
downloadlibcore-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.java8
-rw-r--r--luni/src/main/java/java/util/zip/ZipFile.java24
-rw-r--r--luni/src/main/java/java/util/zip/ZipInputStream.java4
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);