44import org .junit .jupiter .params .ParameterizedTest ;
55import org .junit .jupiter .params .provider .ValueSource ;
66import software .coley .llzip .format .compression .ZipCompressions ;
7+ import software .coley .llzip .format .model .LocalFileHeader ;
78import software .coley .llzip .format .model .ZipArchive ;
9+ import software .coley .llzip .util .ByteDataUtil ;
810
11+ import java .io .ByteArrayOutputStream ;
912import java .io .IOException ;
13+ import java .io .InputStream ;
1014import java .nio .file .*;
1115import java .nio .file .attribute .BasicFileAttributes ;
1216import java .util .Enumeration ;
1317import java .util .zip .ZipEntry ;
1418import java .util .zip .ZipFile ;
1519import java .util .zip .ZipInputStream ;
1620
17- import static org .junit .jupiter .api .Assertions .fail ;
18-
1921/**
2022 * Showcase different behavior in handling tampered ZIP files between ZIP parsing techniques.
2123 *
@@ -31,33 +33,65 @@ public class ZipComparisonShowcaseTest {
3133 "hello-merged.jar" ,
3234 "hello-merged-junkheader.jar" ,
3335 "hello-merged-fake-empty.jar" ,
34- "hello-secret-0-length-locals.jar"
36+ "hello-secret-trailing-slash.jar" ,
37+ "hello-secret-trailing-slash-0-length-locals.jar" ,
38+ "hello-secret-0-length-locals.jar" ,
3539 })
3640 public void testConcatAndMerged (String name ) {
3741 Path path = Paths .get ("src/test/resources/" + name );
3842
3943 try {
4044 System .out .println ("==== LL-J-ZIP (jvm-strategy) ====" );
4145 ZipArchive zipJvm = ZipIO .readJvm (path );
42- zipJvm .getLocalFiles ().forEach (lfh -> {
43- System .out .println (lfh .getFileNameAsString ());
44- try {
45- ZipCompressions .decompress (lfh );
46- } catch (IOException e ) {
47- throw new RuntimeException (e );
48- }
49- });
46+ for (LocalFileHeader lfh : zipJvm .getLocalFiles ()) {
47+ String entryName = lfh .getFileNameAsString ();
48+ byte [] entryData = ByteDataUtil .toByteArray (ZipCompressions .decompress (lfh ));
49+ handle (entryName , entryData );
50+ }
51+ } catch (Exception ex ) {
52+ // fail(ex);
53+ }
54+
55+ try {
56+ System .out .println ("==== LL-J-ZIP (std-strategy) ====" );
57+ ZipArchive zipJvm = ZipIO .readStandard (path );
58+ for (LocalFileHeader lfh : zipJvm .getLocalFiles ()) {
59+ String entryName = lfh .getFileNameAsString ();
60+ byte [] entryData = ByteDataUtil .toByteArray (ZipCompressions .decompress (lfh ));
61+ handle (entryName , entryData );
62+ }
63+ } catch (Exception ex ) {
64+ // fail(ex);
65+ }
66+
67+ try {
68+ System .out .println ("==== LL-J-ZIP (naive-strategy) ====" );
69+ ZipArchive zipJvm = ZipIO .readNaive (path );
70+ for (LocalFileHeader lfh : zipJvm .getLocalFiles ()) {
71+ String entryName = lfh .getFileNameAsString ();
72+ byte [] entryData = ByteDataUtil .toByteArray (ZipCompressions .decompress (lfh ));
73+ handle (entryName , entryData );
74+ }
5075 } catch (Exception ex ) {
51- fail (ex );
76+ // fail(ex);
5277 }
5378
5479 try {
5580 System .out .println ("==== ZipInputStream ====" );
5681 ZipInputStream zipInputStream = new ZipInputStream (Files .newInputStream (path ));
5782 ZipEntry entry ;
5883 while ((entry = zipInputStream .getNextEntry ()) != null ) {
59- System .out .println (entry .getName ());
60- sink (entry .getName ());
84+ if (entry .isDirectory ())
85+ continue ;
86+ ByteArrayOutputStream dataOut = new ByteArrayOutputStream ();
87+ byte [] buffer = new byte [2048 ];
88+ int read ;
89+ while ((read = zipInputStream .read (buffer )) != -1 ) {
90+ dataOut .write (buffer , 0 , read );
91+ }
92+ String entryName = entry .getName ();
93+ byte [] entryData = dataOut .toByteArray ();
94+ handle (entryName , entryData );
6195 }
6296 zipInputStream .close ();
6397 } catch (Exception ex ) {
@@ -69,8 +103,20 @@ public void testConcatAndMerged(String name) {
69103 try (ZipFile zipFile = new ZipFile (path .toFile ())) {
70104 Enumeration <? extends ZipEntry > zipEntries = zipFile .entries ();
71105 while (zipEntries .hasMoreElements ()) {
72- String fileName = zipEntries .nextElement ().getName ();
73- System .out .println (fileName );
106+ ZipEntry entry = zipEntries .nextElement ();
107+ if (entry .isDirectory ())
108+ continue ;
109+ InputStream inputStream = zipFile .getInputStream (entry );
110+ ByteArrayOutputStream dataOut = new ByteArrayOutputStream ();
111+ byte [] buffer = new byte [2048 ];
112+ int read ;
113+ while ((read = inputStream .read (buffer )) != -1 ) {
114+ dataOut .write (buffer , 0 , read );
115+ }
116+
117+ String entryName = entry .getName ();
118+ byte [] entryData = dataOut .toByteArray ();
119+ handle (entryName , entryData );
74120 }
75121 }
76122 } catch (Exception ex ) {
@@ -85,7 +131,13 @@ public void testConcatAndMerged(String name) {
85131 Files .walkFileTree (root , new SimpleFileVisitor <Path >() {
86132 @ Override
87133 public FileVisitResult visitFile (Path file , BasicFileAttributes attrs ) {
88- System .out .println (file .toString ().substring (1 ));
134+ try {
135+ String entryName = file .toString ().substring (1 );
136+ byte [] entryData = Files .readAllBytes (file );
137+ handle (entryName , entryData );
138+ } catch (IOException ex ) {
139+ System .err .println ("Failed to read ZIP contents: " + file );
140+ }
89141 return FileVisitResult .CONTINUE ;
90142 }
91143 });
@@ -95,7 +147,10 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
95147 }
96148 }
97149
98- private static boolean hasFile (ZipArchive zip , String name ) {
99- return !zip .getNameFilteredLocalFiles (name ::equals ).isEmpty ();
150+ private void handle (String name , byte [] data ) {
151+ System .out .println (name );
152+ if (name .contains ("Hello" )) {
153+ System .out .println ("Has secret message: " + new String (data ).contains ("The secret code is: ROSE" ));
154+ }
100155 }
101156}
0 commit comments