diff --git a/luni/src/main/java/java/util/zip/ZipEntry.java b/luni/src/main/java/java/util/zip/ZipEntry.java
index 563f6491c615df7b75f1cfe62948a4abf63bd4ec..c8c733df81dd4b2e7772ed6568b91113bc94b470 100644
--- a/luni/src/main/java/java/util/zip/ZipEntry.java
+++ b/luni/src/main/java/java/util/zip/ZipEntry.java
@@ -357,7 +357,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 172141c0161ce251424aff4a88b07c43030db53f..3e750f4ae3869845747e5b73d2f8e236c2ed8c6f 100644
--- a/luni/src/main/java/java/util/zip/ZipFile.java
+++ b/luni/src/main/java/java/util/zip/ZipFile.java
@@ -67,6 +67,12 @@ public class ZipFile implements ZipConstants {
      */
     static final int GPBF_UTF8_FLAG = 1 << 11;
 
+    /**
+     * 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.
      */
@@ -242,11 +248,19 @@ public class ZipFile implements ZipConstants {
         RandomAccessFile localRaf = raf;
         synchronized (localRaf) {
             // 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(localRaf, entry.localHeaderRelOffset + 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(localRaf, entry.localHeaderRelOffset + 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 97aa35023d3e70577d7931616cb056a11bb25c3b..0135e1e10795d0e923840b7cabfe2fb7cc3defa0 100644
--- a/luni/src/main/java/java/util/zip/ZipInputStream.java
+++ b/luni/src/main/java/java/util/zip/ZipInputStream.java
@@ -237,6 +237,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);