Skip to content

Commit

Permalink
classlib: fix issue in ZipFile
Browse files Browse the repository at this point in the history
Fix #954
  • Loading branch information
konsoletyper committed Oct 22, 2024
1 parent 17b110d commit abf4034
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import org.teavm.classlib.java.util.zip.TZipEntry.LittleEndianReader;

Expand Down Expand Up @@ -62,11 +61,6 @@ public TZipFile(String name) throws IOException {
this(new File(name), OPEN_READ);
}

@Override
protected void finalize() throws IOException {
close();
}

public void close() throws IOException {
RandomAccessFile raf = mRaf;

Expand All @@ -89,9 +83,9 @@ private void checkNotClosed() {

public Enumeration<? extends TZipEntry> entries() {
checkNotClosed();
final Iterator<TZipEntry> iterator = mEntries.values().iterator();
var iterator = mEntries.values().iterator();

return new Enumeration<TZipEntry>() {
return new Enumeration<>() {
@Override
public boolean hasMoreElements() {
checkNotClosed();
Expand Down Expand Up @@ -263,7 +257,7 @@ static class RAFStream extends InputStream {
long mOffset;
long mLength;

public RAFStream(RandomAccessFile raf, long pos) throws IOException {
RAFStream(RandomAccessFile raf, long pos) throws IOException {
mSharedRaf = raf;
mOffset = pos;
mLength = raf.length();
Expand Down Expand Up @@ -321,7 +315,7 @@ static class ZipInflaterInputStream extends TInflaterInputStream {
TZipEntry entry;
long bytesRead;

public ZipInflaterInputStream(InputStream is, TInflater inf, int bsize, TZipEntry entry) {
ZipInflaterInputStream(InputStream is, TInflater inf, int bsize, TZipEntry entry) {
super(is, inf, bsize);
this.entry = entry;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.nio.charset.StandardCharsets;

public class TZipInputStream extends TInflaterInputStream implements TZipConstants {
static final int DEFLATED = 8;
Expand Down Expand Up @@ -204,7 +205,7 @@ public TZipEntry getNextEntry() throws IOException {
throw new EOFException();
}
}
currentEntry = createZipEntry(new String(nameBuf, 0, flen, "UTF-8"));
currentEntry = createZipEntry(new String(nameBuf, 0, flen, StandardCharsets.UTF_8));
currentEntry.time = cetime;
currentEntry.modDate = cemodDate;
currentEntry.setMethod(cecompressionMethod);
Expand Down Expand Up @@ -255,7 +256,7 @@ public int read(byte[] buffer, int start, int length) throws IOException {
}
entryIn += len;
}
int toRead = length > len - lastRead ? len - lastRead : length;
int toRead = Math.min(length, len - lastRead);
if ((csize - inRead) < toRead) {
toRead = csize - inRead;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.teavm.classlib.java.util.zip.ZipTestUtil.readHex;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
Expand Down Expand Up @@ -58,9 +59,8 @@ public void zipInputWorks() throws IOException {
ZipInputStream input = new ZipInputStream(new ByteArrayInputStream(data));
ZipEntry entry = input.getNextEntry();
assertEquals("test.txt", entry.getName());
byte[] uncompressed = new byte[500];
int length = readFully(input, uncompressed);
assertEquals("hello\n", new String(uncompressed, 0, length));
var uncompressed = input.readAllBytes();
assertEquals("hello\n", new String(uncompressed));
assertNull(input.getNextEntry());
}

Expand All @@ -76,9 +76,8 @@ public void zipOutputWorks() throws IOException {
ZipInputStream input = new ZipInputStream(new ByteArrayInputStream(data));
ZipEntry entry = input.getNextEntry();
assertEquals("test.txt", entry.getName());
byte[] uncompressed = new byte[5000];
int length = readFully(input, uncompressed);
assertEquals(longString, new String(uncompressed, 0, length, StandardCharsets.UTF_8));
var uncompressed = input.readAllBytes();
assertEquals(longString, new String(uncompressed, StandardCharsets.UTF_8));
assertNull(input.getNextEntry());
}

Expand All @@ -94,13 +93,4 @@ private static int readFully(InputStream input, byte[] target) throws IOExceptio
return offset;
}

private static byte[] readHex(String hex) {
byte[] data = new byte[hex.length() / 2];
for (int i = 0; i < data.length; ++i) {
int h = Character.digit(hex.charAt(i * 2), 16);
int l = Character.digit(hex.charAt(i * 2 + 1), 16);
data[i] = (byte) ((h << 4) | l);
}
return data;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2024 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.util.zip;

import static org.teavm.classlib.java.util.zip.ZipTestUtil.writeHex;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.teavm.junit.TeaVMTestRunner;

@RunWith(TeaVMTestRunner.class)
public class ZipFileTest {
private static final String DATA1 = "504b030414000808080036a25659000000000000000000000000070000006578616d706c65e"
+ "dc1310d000000c3a0d4bfe9d9d801140000f06e504b07086a6536d214000000b80b0000504b0102140014000808080036a256"
+ "596a6536d214000000b80b00000700000000000000000000000000000000006578616d706c65504b050600000000010001003"
+ "5000000490000000000";

@BeforeClass
public void initAll() {

}

@Test
public void readEntry() throws IOException {
var file = new File("test.zip");

try (var input = new FileInputStream(file)) {
var bytes = input.readAllBytes();
System.out.println(writeHex(bytes));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2024 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.util.zip;

final class ZipTestUtil {
private ZipTestUtil() {
}

static byte[] readHex(String hex) {
byte[] data = new byte[hex.length() / 2];
for (int i = 0; i < data.length; ++i) {
int h = Character.digit(hex.charAt(i * 2), 16);
int l = Character.digit(hex.charAt(i * 2 + 1), 16);
data[i] = (byte) ((h << 4) | l);
}
return data;
}

static String writeHex(byte[] data) {
var hex = new char[data.length * 2];
for (int i = 0; i < data.length; ++i) {
var b = data[i];
var h = Character.forDigit((b & 255) / 16, 16);
var l = Character.forDigit((b & 255) % 16, 16);
hex[i * 2] = h;
hex[i * 2 + 1] = l;
}
return new String(hex);
}
}

0 comments on commit abf4034

Please sign in to comment.