diff options
author | Paulo Casanova <pasc@google.com> | 2017-05-08 13:42:16 +0100 |
---|---|---|
committer | Paulo Casanova <pasc@google.com> | 2017-05-08 13:43:19 +0100 |
commit | 6fb3edd101b373e026ef3e8bcae35e8dd111dd7f (patch) | |
tree | 41df20dbd9c57d156bef905771ac86268ede1487 /src/main/java/com/android | |
parent | 4a3db1dabcf1c7ad66b186059a8493cc69e7ca67 (diff) | |
download | apkzlib-6fb3edd101b373e026ef3e8bcae35e8dd111dd7f.tar.gz |
Updated ZFile to use UTF-8 if needed.
If ASCII decoding fails, ZFile will now automatically try
UTF-8.
Change-Id: I29ef2cf3c043cf31d6c07c70271297356d2571f2
Test: Included
Diffstat (limited to 'src/main/java/com/android')
4 files changed, 30 insertions, 11 deletions
diff --git a/src/main/java/com/android/apkzlib/zip/CentralDirectory.java b/src/main/java/com/android/apkzlib/zip/CentralDirectory.java index 4305d80..44389c1 100644 --- a/src/main/java/com/android/apkzlib/zip/CentralDirectory.java +++ b/src/main/java/com/android/apkzlib/zip/CentralDirectory.java @@ -341,7 +341,9 @@ class CentralDirectory { + "."); } - String fileName = EncodeUtils.decode(bytes, fileNameLength, flags); + byte[] encodedFileName = new byte[fileNameLength]; + bytes.get(encodedFileName); + String fileName = EncodeUtils.decode(encodedFileName, flags); byte[] extraField = new byte[extraFieldLength]; bytes.get(extraField); @@ -362,11 +364,7 @@ class CentralDirectory { versionNeededToExtract)); CentralDirectoryHeader centralDirectoryHeader = new CentralDirectoryHeader( - fileName, - uncompressedSize, - compressInfo, - flags, - file); + fileName, encodedFileName, uncompressedSize, compressInfo, flags, file); centralDirectoryHeader.setMadeBy(madeBy); centralDirectoryHeader.setLastModTime(lastModTime); centralDirectoryHeader.setLastModDate(lastModDate); diff --git a/src/main/java/com/android/apkzlib/zip/CentralDirectoryHeader.java b/src/main/java/com/android/apkzlib/zip/CentralDirectoryHeader.java index 7e7e50b..f10477f 100644 --- a/src/main/java/com/android/apkzlib/zip/CentralDirectoryHeader.java +++ b/src/main/java/com/android/apkzlib/zip/CentralDirectoryHeader.java @@ -128,6 +128,7 @@ public class CentralDirectoryHeader implements Cloneable { * Creates data for a file. * * @param name the file name + * @param encodedFileName the encoded file name, this array will be owned by the header * @param uncompressedSize the uncompressed file size * @param compressInfo computation that defines the compression information * @param flags flags used in the entry @@ -135,6 +136,7 @@ public class CentralDirectoryHeader implements Cloneable { */ CentralDirectoryHeader( @Nonnull String name, + @Nonnull byte[] encodedFileName, long uncompressedSize, @Nonnull Future<CentralDirectoryHeaderCompressInfo> compressInfo, @Nonnull GPFlags flags, @@ -156,7 +158,7 @@ public class CentralDirectoryHeader implements Cloneable { internalAttributes = 0; externalAttributes = 0; offset = -1; - encodedFileName = EncodeUtils.encode(name, gpBit); + this.encodedFileName = encodedFileName; this.compressInfo = compressInfo; file = zFile; } diff --git a/src/main/java/com/android/apkzlib/zip/EncodeUtils.java b/src/main/java/com/android/apkzlib/zip/EncodeUtils.java index 6579d1c..94cabbe 100644 --- a/src/main/java/com/android/apkzlib/zip/EncodeUtils.java +++ b/src/main/java/com/android/apkzlib/zip/EncodeUtils.java @@ -19,7 +19,9 @@ package com.android.apkzlib.zip; import com.google.common.base.Charsets; import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; +import java.nio.charset.CodingErrorAction; import javax.annotation.Nonnull; /** @@ -52,10 +54,9 @@ public class EncodeUtils { + "length is " + length + "."); } - Charset charset = flagsCharset(flags); byte[] stringBytes = new byte[length]; bytes.get(stringBytes); - return charset.decode(ByteBuffer.wrap(stringBytes)).toString(); + return decode(stringBytes, flags); } /** @@ -68,7 +69,23 @@ public class EncodeUtils { @Nonnull public static String decode(@Nonnull byte[] data, @Nonnull GPFlags flags) { Charset charset = flagsCharset(flags); - return charset.decode(ByteBuffer.wrap(data)).toString(); + + while (true) { + try { + return charset.newDecoder() + .onMalformedInput(CodingErrorAction.REPORT) + .decode(ByteBuffer.wrap(data)) + .toString(); + } catch (CharacterCodingException e) { + // If we're trying to decode ASCII, try UTF-8. Otherwise, revert to the default + // behavior (usually replacing invalid characters). + if (charset == Charsets.US_ASCII) { + charset = Charsets.UTF_8; + } else { + return charset.decode(ByteBuffer.wrap(data)).toString(); + } + } + } } /** diff --git a/src/main/java/com/android/apkzlib/zip/ZFile.java b/src/main/java/com/android/apkzlib/zip/ZFile.java index 2ec8df7..d4d730e 100644 --- a/src/main/java/com/android/apkzlib/zip/ZFile.java +++ b/src/main/java/com/android/apkzlib/zip/ZFile.java @@ -1522,12 +1522,14 @@ public class ZFile implements Closeable { SettableFuture<CentralDirectoryHeaderCompressInfo> compressInfo = SettableFuture.create(); + GPFlags flags = GPFlags.make(encodeWithUtf8); CentralDirectoryHeader newFileData = new CentralDirectoryHeader( name, + EncodeUtils.encode(name, flags), source.size(), compressInfo, - GPFlags.make(encodeWithUtf8), + flags, this); newFileData.setCrc32(crc32); |