Merge pull request #2692 from ag2s20150909/master

修复中文AndroidZipFile不能读取非ASCII字符文件名
pull/2700/head
kunfei 2 years ago committed by GitHub
commit c225668454
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      app/src/main/java/io/legado/app/lib/icu4j/CharsetDetector.java
  2. 2
      epublib/src/main/java/me/ag2s/base/PfdHelper.java
  3. 16
      epublib/src/main/java/me/ag2s/epublib/util/zip/AndroidZipEntry.java
  4. 8
      epublib/src/main/java/me/ag2s/epublib/util/zip/AndroidZipFile.java

@ -8,6 +8,10 @@
*/ */
package io.legado.app.lib.icu4j; package io.legado.app.lib.icu4j;
import android.os.ParcelFileDescriptor;
import android.system.OsConstants;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import java.io.IOException; import java.io.IOException;
@ -88,13 +92,25 @@ public class CharsetDetector {
* @return This CharsetDetector * @return This CharsetDetector
* @stable ICU 3.4 * @stable ICU 3.4
*/ */
public CharsetDetector setText(byte[] in) { public CharsetDetector setText(@NonNull byte[] in) {
fRawInput = in; fRawInput = in;
fRawLength = in.length; fRawLength = in.length;
return this; 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; private static final int kBufSize = 8000;
/** /**
@ -111,7 +127,7 @@ public class CharsetDetector {
* @stable ICU 3.4 * @stable ICU 3.4
*/ */
public CharsetDetector setText(InputStream in) throws IOException { public CharsetDetector setText(@NonNull InputStream in) throws IOException {
fInputStream = in; fInputStream = in;
fInputStream.mark(kBufSize); fInputStream.mark(kBufSize);
fRawInput = new byte[kBufSize]; // Always make a new buffer because the fRawInput = new byte[kBufSize]; // Always make a new buffer because the

@ -39,7 +39,7 @@ public final class PfdHelper {
public static long length(ParcelFileDescriptor pfd) throws IOException { public static long length(ParcelFileDescriptor pfd) throws IOException {
try { 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) { } catch (ErrnoException e) {
throw rethrowAsIOException(e); throw rethrowAsIOException(e);
} }

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

@ -242,9 +242,9 @@ public class AndroidZipFile implements ZipConstants {
buffer = new byte[needBuffer]; buffer = new byte[needBuffer];
PfdHelper.readFully(pfd, buffer, 0, nameLen); 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.setMethod(method);
entry.setCrc(crc & 0xffffffffL); entry.setCrc(crc & 0xffffffffL);
entry.setSize(size & 0xffffffffL); entry.setSize(size & 0xffffffffL);
@ -361,10 +361,10 @@ public class AndroidZipFile implements ZipConstants {
if (entry.getMethod() != readLeShort(locBuf, LOCHOW)) if (entry.getMethod() != readLeShort(locBuf, LOCHOW))
throw new ZipException("Compression method mismatch: " + name); 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); 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; return entry.offset + LOCHDR + extraLen;
} }
} }

Loading…
Cancel
Save