修复中文AndroidZipFile不能读取非ASCII字符文件名

This commit is contained in:
ag2s20150909 2023-01-09 08:08:21 +08:00
parent ff11cbe780
commit 973d7c6534
4 changed files with 35 additions and 11 deletions

View File

@ -8,6 +8,10 @@
*/
package io.legado.app.lib.icu4j;
import android.os.ParcelFileDescriptor;
import android.system.OsConstants;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.IOException;
@ -88,13 +92,25 @@ public class CharsetDetector {
* @return This CharsetDetector
* @stable ICU 3.4
*/
public CharsetDetector setText(byte[] in) {
public CharsetDetector setText(@NonNull byte[] in) {
fRawInput = in;
fRawLength = in.length;
return this;
}
public CharsetDetector setText(@NonNull ParcelFileDescriptor pfd) {
fRawInput = new byte[kBufSize];
try {
android.system.Os.lseek(pfd.getFileDescriptor(), 0, OsConstants.SEEK_SET);
fRawLength = android.system.Os.read(pfd.getFileDescriptor(), fRawInput, 0, fRawInput.length);
android.system.Os.lseek(pfd.getFileDescriptor(), 0, OsConstants.SEEK_SET);
} catch (Exception e) {
throw new RuntimeException(e);
}
return this;
}
private static final int kBufSize = 8000;
/**
@ -111,7 +127,7 @@ public class CharsetDetector {
* @stable ICU 3.4
*/
public CharsetDetector setText(InputStream in) throws IOException {
public CharsetDetector setText(@NonNull InputStream in) throws IOException {
fInputStream = in;
fInputStream.mark(kBufSize);
fRawInput = new byte[kBufSize]; // Always make a new buffer because the

View File

@ -39,7 +39,7 @@ public final class PfdHelper {
public static long length(ParcelFileDescriptor pfd) throws IOException {
try {
return android.system.Os.lseek(pfd.getFileDescriptor(), 0, OsConstants.SEEK_END);
return android.system.Os.fstat(pfd.getFileDescriptor()).st_size; //android.system.Os.lseek(pfd.getFileDescriptor(), 0, OsConstants.SEEK_END);
} catch (ErrnoException e) {
throw rethrowAsIOException(e);
}

View File

@ -24,6 +24,7 @@ public class AndroidZipEntry implements ZipConstants, Cloneable {
private static Calendar cal;
private final String name;
private final int nameLen;
private int size;
private int compressedSize;
private int crc;
@ -54,13 +55,15 @@ public class AndroidZipEntry implements ZipConstants, Cloneable {
* @throws NullPointerException when name is null.
* @throws IllegalArgumentException when name is bigger then 65535 chars.
*/
public AndroidZipEntry(String name) {
int length = name.length();
if (length > 65535)
throw new IllegalArgumentException("name length is " + length);
public AndroidZipEntry(String name, int nameLen) {
//int length = name.length();
this.nameLen = nameLen;
if (nameLen > 65535)
throw new IllegalArgumentException("name length is " + nameLen);
this.name = name;
}
/**
* Creates a copy of the given zip entry.
*
@ -68,6 +71,7 @@ public class AndroidZipEntry implements ZipConstants, Cloneable {
*/
public AndroidZipEntry(AndroidZipEntry e) {
name = e.name;
nameLen = e.nameLen;
known = e.known;
size = e.size;
compressedSize = e.compressedSize;
@ -116,6 +120,10 @@ public class AndroidZipEntry implements ZipConstants, Cloneable {
return name;
}
public int getNameLen() {
return nameLen;
}
/**
* Sets the time of last modification of the entry.
*

View File

@ -242,9 +242,9 @@ public class AndroidZipFile implements ZipConstants {
buffer = new byte[needBuffer];
PfdHelper.readFully(pfd, buffer, 0, nameLen);
String name = new String(buffer, 0, 0, nameLen);
String name = new String(buffer, 0, nameLen);
AndroidZipEntry entry = new AndroidZipEntry(name);
AndroidZipEntry entry = new AndroidZipEntry(name, nameLen);
entry.setMethod(method);
entry.setCrc(crc & 0xffffffffL);
entry.setSize(size & 0xffffffffL);
@ -361,10 +361,10 @@ public class AndroidZipFile implements ZipConstants {
if (entry.getMethod() != readLeShort(locBuf, LOCHOW))
throw new ZipException("Compression method mismatch: " + name);
if (entry.getName().length() != readLeShort(locBuf, LOCNAM))
if (entry.getNameLen() != readLeShort(locBuf, LOCNAM))
throw new ZipException("file name length mismatch: " + name);
int extraLen = entry.getName().length() + readLeShort(locBuf, LOCEXT);
int extraLen = entry.getNameLen() + readLeShort(locBuf, LOCEXT);
return entry.offset + LOCHDR + extraLen;
}
}