Browse Source

[zip] Bugfix on zipfiles not having data descriptor after filedata. (#11686)

* [zip] Bugfix on zipfiles not having data descriptor after filedata.
    (Zip files generated with 7zip tool on windows was corrupted when
    read with Haxe)

* add test

---------

Co-authored-by: Sébastien Bernery <[email protected]>
Co-authored-by: Simon Krajewski <[email protected]>
Sébastien Bernery 4 months ago
parent
commit
2fa55afd8b

+ 53 - 50
std/haxe/zip/Reader.hx

@@ -127,55 +127,59 @@ class Reader {
 			if (e == null)
 				break;
 			// do we have a data descriptor? (see readEntryHeader)
-			if (e.crc32 == null) {
-				if (e.compressed) {
-					#if neko
-					// enter progressive mode : we use a different input which has
-					// a temporary buffer, this is necessary since we have to uncompress
-					// progressively, and after that we might have pending read data
-					// that needs to be processed
-					var bufSize = 65536;
-					if (buf == null) {
-						buf = new haxe.io.BufferInput(i, haxe.io.Bytes.alloc(bufSize));
-						tmp = haxe.io.Bytes.alloc(bufSize);
-						i = buf;
-					}
-					var out = new haxe.io.BytesBuffer();
-					var z = new neko.zip.Uncompress(-15);
-					z.setFlushMode(neko.zip.Flush.SYNC);
-					while (true) {
-						if (buf.available == 0)
-							buf.refill();
-						var p = bufSize - buf.available;
-						if (p != buf.pos) {
-							// because of lack of "srcLen" in zip api, we need to always be stuck to the buffer end
-							buf.buf.blit(p, buf.buf, buf.pos, buf.available);
-							buf.pos = p;
-						}
-						var r = z.execute(buf.buf, buf.pos, tmp, 0);
-						out.addBytes(tmp, 0, r.write);
-						buf.pos += r.read;
-						buf.available -= r.read;
-						if (r.done)
-							break;
-					}
-					e.data = out.getBytes();
-					#else
-					var bufSize = 65536;
-					if (tmp == null)
-						tmp = haxe.io.Bytes.alloc(bufSize);
-					var out = new haxe.io.BytesBuffer();
-					var z = new InflateImpl(i, false, false);
-					while (true) {
-						var n = z.readBytes(tmp, 0, bufSize);
-						out.addBytes(tmp, 0, n);
-						if (n < bufSize)
-							break;
+			if (e.compressed) {
+				#if neko
+				// enter progressive mode : we use a different input which has
+				// a temporary buffer, this is necessary since we have to uncompress
+				// progressively, and after that we might have pending read data
+				// that needs to be processed
+				var bufSize = 65536;
+				if (buf == null) {
+					buf = new haxe.io.BufferInput(i, haxe.io.Bytes.alloc(bufSize));
+					tmp = haxe.io.Bytes.alloc(bufSize);
+					i = buf;
+				}
+				var out = new haxe.io.BytesBuffer();
+				var z = new neko.zip.Uncompress(-15);
+				z.setFlushMode(neko.zip.Flush.SYNC);
+				while (true) {
+					if (buf.available == 0)
+						buf.refill();
+					var p = bufSize - buf.available;
+					if (p != buf.pos) {
+						// because of lack of "srcLen" in zip api, we need to always be stuck to the buffer end
+						buf.buf.blit(p, buf.buf, buf.pos, buf.available);
+						buf.pos = p;
 					}
-					e.data = out.getBytes();
-					#end
-				} else
-					e.data = i.read(e.dataSize);
+					var r = z.execute(buf.buf, buf.pos, tmp, 0);
+					out.addBytes(tmp, 0, r.write);
+					buf.pos += r.read;
+					buf.available -= r.read;
+					if (r.done)
+						break;
+				}
+				e.data = out.getBytes();
+				e.compressed = false;
+				#else
+				var bufSize = 65536;
+				if (tmp == null)
+					tmp = haxe.io.Bytes.alloc(bufSize);
+				var out = new haxe.io.BytesBuffer();
+				var z = new InflateImpl(i, false, false);
+				while (true) {
+					var n = z.readBytes(tmp, 0, bufSize);
+					out.addBytes(tmp, 0, n);
+					if (n < bufSize)
+						break;
+				}
+				e.data = out.getBytes();
+				#end
+			} else
+				e.data = i.read(e.dataSize);
+
+			// If CRC32 is not defined in the header,
+			// it's defined in a data descriptor after the compressed data.
+			if (e.crc32 == null) {
 				e.crc32 = i.readInt32();
 				if (e.crc32 == 0x08074b50)
 					e.crc32 = i.readInt32();
@@ -184,8 +188,7 @@ class Reader {
 				// set data to uncompressed
 				e.dataSize = e.fileSize;
 				e.compressed = false;
-			} else
-				e.data = i.read(e.dataSize);
+			}
 			l.add(e);
 		}
 		return l;

+ 18 - 0
tests/misc/projects/Issue11686/Main.hx

@@ -0,0 +1,18 @@
+class Main {
+    static public function main() {
+        trace("Working archive");
+        var zipread = sys.io.File.read("./test_zip_roller.zip", true);
+        var zipfile_entries = haxe.zip.Reader.readZip(zipread);
+        for (entry in zipfile_entries) {
+            trace("[", entry.fileName, entry.fileSize, entry.crc32, "]");
+            trace("[", entry.data.toString(), "]");
+        }
+        trace("Broken archive");
+        var zipread = sys.io.File.read("./test_zip_7zip.zip", true);
+        var zipfile_entries = haxe.zip.Reader.readZip(zipread);
+        for (entry in zipfile_entries) {
+            trace("[", entry.fileName, entry.fileSize, entry.crc32, "]");
+            trace("[", entry.data.toString(), "]");
+        }
+    }
+}

+ 2 - 0
tests/misc/projects/Issue11686/compile.hxml

@@ -0,0 +1,2 @@
+--main Main
+--interp

+ 34 - 0
tests/misc/projects/Issue11686/compile.hxml.stdout

@@ -0,0 +1,34 @@
+Main.hx:3: Working archive
+Main.hx:7: [,test/,0,0,]
+Main.hx:8: [,,]
+Main.hx:7: [,test/moretext2.txt,68,-2888415,]
+Main.hx:8: [,MORETEXTMORETEXTMORETEXTMORETEXT
+MORETEXTMORETEXTMORETEXTMORETEXT
+,]
+Main.hx:7: [,test/salut.txt,4,-662733300,]
+Main.hx:8: [,test,]
+Main.hx:7: [,moretext.txt,30,55748892,]
+Main.hx:8: [,SECONDTEXTSECONDTEXTSECONDTEXT,]
+Main.hx:7: [,moretext2.txt,68,-2888415,]
+Main.hx:8: [,MORETEXTMORETEXTMORETEXTMORETEXT
+MORETEXTMORETEXTMORETEXTMORETEXT
+,]
+Main.hx:7: [,salut.txt,4,-662733300,]
+Main.hx:8: [,test,]
+Main.hx:10: Broken archive
+Main.hx:14: [,moretext.txt,30,55748892,]
+Main.hx:15: [,SECONDTEXTSECONDTEXTSECONDTEXT,]
+Main.hx:14: [,moretext2.txt,68,-2888415,]
+Main.hx:15: [,MORETEXTMORETEXTMORETEXTMORETEXT
+MORETEXTMORETEXTMORETEXTMORETEXT
+,]
+Main.hx:14: [,salut.txt,4,-662733300,]
+Main.hx:15: [,test,]
+Main.hx:14: [,test/,0,0,]
+Main.hx:15: [,,]
+Main.hx:14: [,test/moretext2.txt,68,-2888415,]
+Main.hx:15: [,MORETEXTMORETEXTMORETEXTMORETEXT
+MORETEXTMORETEXTMORETEXTMORETEXT
+,]
+Main.hx:14: [,test/salut.txt,4,-662733300,]
+Main.hx:15: [,test,]

BIN
tests/misc/projects/Issue11686/test_zip_7zip.zip


BIN
tests/misc/projects/Issue11686/test_zip_roller.zip