diff --git a/CHANGELOG.md b/CHANGELOG.md index 6045c1163..641c4c4ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ All notable changes to this project will be documented in this file. - [#2428] Default charset for SWFS v5 and lower is WINDOWS-1252 - [#2418] AS3 - initialization of class static vars in script initializer (Haxe) - [#2397] DefineScalingGrid - improper scaling on negative Xmin, Ymin +- [#2425] ZIP/SWC reading - "Only DEFLATED entries can have EXT descriptor" message ## [22.0.2] - 2025-01-17 ### Added @@ -3711,6 +3712,7 @@ Major version of SWF to XML export changed to 2. [#2428]: https://www.free-decompiler.com/flash/issues/2428 [#2418]: https://www.free-decompiler.com/flash/issues/2418 [#2397]: https://www.free-decompiler.com/flash/issues/2397 +[#2425]: https://www.free-decompiler.com/flash/issues/2425 [#2375]: https://www.free-decompiler.com/flash/issues/2375 [#2374]: https://www.free-decompiler.com/flash/issues/2374 [#2389]: https://www.free-decompiler.com/flash/issues/2389 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWC.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWC.java index 3e720395b..3d1899351 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWC.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWC.java @@ -18,9 +18,9 @@ package com.jpexs.decompiler.flash; import java.io.File; import java.io.IOException; -import java.io.InputStream; +import java.util.Enumeration; import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; +import java.util.zip.ZipFile; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; @@ -32,17 +32,7 @@ import org.xml.sax.helpers.DefaultHandler; * * @author JPEXS */ -public class SWC extends ZippedBundle { - - /** - * Constructs SWC from input stream. - * - * @param is Input stream - * @throws IOException On I/O error - */ - public SWC(InputStream is) throws IOException { - super(is); - } +public class SWC extends ZippedBundle { /** * Constructs SWC from file. @@ -57,19 +47,18 @@ public class SWC extends ZippedBundle { /** * Initializes SWC bundle. * - * @param is Input stream * @param filename File * @throws IOException On I/O error */ @Override - protected void initBundle(InputStream is, File filename) throws IOException { - super.initBundle(is, filename); + protected void initBundle(File filename) throws IOException { + super.initBundle(filename); keySet.clear(); - this.is.reset(); - ZipInputStream zip = new ZipInputStream(this.is); - ZipEntry entry; + ZipFile zipFile = new ZipFile(filename); + Enumeration entries = zipFile.entries(); - while ((entry = zip.getNextEntry()) != null) { + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); if (entry.getName().equals("catalog.xml")) { try { SAXParserFactory factory = SAXParserFactory.newInstance(); @@ -87,13 +76,14 @@ public class SWC extends ZippedBundle { } }; - saxParser.parse(zip, handler); + saxParser.parse(zipFile.getInputStream(entry), handler); } catch (Exception ex) { //ignored } return; } } + zipFile.close(); } /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index c8a180979..100569e88 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -795,7 +795,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { }*/ if (Configuration.getPlayerSWC() != null) { - SWC swc = new SWC(new FileInputStream(Configuration.getPlayerSWC())); + SWC swc = new SWC(Configuration.getPlayerSWC()); //set allowRenameIdentifiers parameter to FALSE otherwise there will be an infinite loop SWF swf = new SWF(swc.getOpenable("library.swf"), null, null, null, true, false, true, null, "WINDOWS-1252", false); playerGlobalAbcIndex = new AbcIndexing(swf); @@ -803,7 +803,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { } if (airGlobalAbcIndex == null) { if (Configuration.getAirSWC() != null) { - SWC swc = new SWC(new FileInputStream(Configuration.getAirSWC())); + SWC swc = new SWC(Configuration.getAirSWC()); //set allowRenameIdentifiers to FALSE SWF swf = new SWF(swc.getOpenable("library.swf"), null, null, null, true, false, true, null, "WINDOWS-1252", false); airGlobalAbcIndex = new AbcIndexing(swf); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ZippedBundle.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ZippedBundle.java index 03065901f..df3fcd01a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ZippedBundle.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ZippedBundle.java @@ -18,20 +18,19 @@ package com.jpexs.decompiler.flash; import com.jpexs.helpers.Helper; import com.jpexs.helpers.MemoryInputStream; -import com.jpexs.helpers.ReReadableInputStream; import com.jpexs.helpers.streams.SeekableInputStream; import java.io.ByteArrayInputStream; import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; +import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; /** @@ -44,33 +43,13 @@ public class ZippedBundle implements Bundle { /** * Key set */ - protected Set keySet = new HashSet<>(); - - /** - * File input stream for the ZIP file - */ - protected FileInputStream fis; - - /** - * Re-readable input stream for the ZIP file - */ - protected ReReadableInputStream is; + protected Set keySet = new HashSet<>(); /** * File name of the ZIP file */ - protected File filename; - - /** - * Constructs a new ZippedBundle from an input stream. - * - * @param is Input stream - * @throws IOException On I/O error - */ - public ZippedBundle(InputStream is) throws IOException { - this(is, null); - } - + protected File filename; + /** * Constructs a new ZippedBundle from a file. * @@ -78,18 +57,7 @@ public class ZippedBundle implements Bundle { * @throws IOException On I/O error */ public ZippedBundle(File filename) throws IOException { - this(null, filename); - } - - /** - * Constructs a new ZippedBundle from an input stream and a file. - * - * @param is Input stream - * @param filename File - * @throws IOException On I/O error - */ - protected ZippedBundle(InputStream is, File filename) throws IOException { - initBundle(is, filename); + initBundle(filename); } /** @@ -99,18 +67,15 @@ public class ZippedBundle implements Bundle { * @param filename File * @throws IOException On I/O error */ - protected void initBundle(InputStream is, File filename) throws IOException { - if (filename != null) { - fis = new FileInputStream(filename); - is = fis; - } + protected void initBundle(File filename) throws IOException { this.filename = filename; - this.is = new ReReadableInputStream(is); - ZipInputStream zip = new ZipInputStream(this.is); - ZipEntry entry; + ZipFile zipFile = new ZipFile(filename); keySet.clear(); + + Enumeration entries = zipFile.entries(); - while ((entry = zip.getNextEntry()) != null) { + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); if (entry.getName().toLowerCase().endsWith(".swf") || entry.getName().toLowerCase().endsWith(".spl") || entry.getName().toLowerCase().endsWith(".gfx") @@ -118,6 +83,7 @@ public class ZippedBundle implements Bundle { keySet.add(entry.getName()); } } + zipFile.close(); } @Override @@ -136,24 +102,13 @@ public class ZippedBundle implements Bundle { if (!keySet.contains(key)) { return null; } - //if (!cachedSWFs.containsKey(key)) { - SeekableInputStream ret = null; - this.is.reset(); - ZipInputStream zip = new ZipInputStream(this.is); - ZipEntry entry; - - while ((entry = zip.getNextEntry()) != null) { - if (entry.getName().equals(key)) { - MemoryInputStream mis = new MemoryInputStream(Helper.readStream(zip)); - ret = mis; - //cachedSWFs.put(key, mis); - break; - } - zip.closeEntry(); - } + ZipFile zipFile = new ZipFile(filename); + ZipEntry entry = zipFile.getEntry(key); + MemoryInputStream mis = new MemoryInputStream(Helper.readStream(zipFile.getInputStream(entry))); + SeekableInputStream ret = mis; + zipFile.close(); return ret; - //return cachedSWFs.get(key); } @Override @@ -186,46 +141,48 @@ public class ZippedBundle implements Bundle { if (!getKeys().contains(key)) { //replace only existing keys return false; } + + ZipFile zipFile = new ZipFile(filename); + //Write to temp file first File tempFile = new File((filename.getAbsolutePath()) + ".tmp"); try { ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(tempFile)); - this.is.reset(); - ZipInputStream zis = new ZipInputStream(this.is); ZipEntry entryIn; ZipEntry entryOut; byte[] swfData = Helper.readStream(swfIs); + + Enumeration entries = zipFile.entries(); try { - while ((entryIn = zis.getNextEntry()) != null) { + while (entries.hasMoreElements()) { InputStream src; + entryIn = entries.nextElement(); if (entryIn.getName().equals(key)) { entryOut = new ZipEntry(key); src = new ByteArrayInputStream(swfData); } else { - src = zis; + src = zipFile.getInputStream(entryIn); entryOut = entryIn; } zos.putNextEntry(entryOut); Helper.copyStream(src, zos, entryOut.getSize() == -1 ? Long.MAX_VALUE : entryOut.getSize()); zos.closeEntry(); - zis.closeEntry(); } + } finally { - zis.close(); zos.close(); - } - this.is.close(); - this.fis.close(); + zipFile.close(); + } } catch (IOException ex) { tempFile.delete(); throw ex; } filename.delete(); tempFile.renameTo(filename); - initBundle(null, filename); + initBundle(filename); return true; }