diff --git a/fbreader/app/src/main/java/org/amse/ys/zip/MyBufferedInputStream.java b/fbreader/app/src/main/java/org/amse/ys/zip/MyBufferedInputStream.java index a29cc9fa4..8461d8a32 100644 --- a/fbreader/app/src/main/java/org/amse/ys/zip/MyBufferedInputStream.java +++ b/fbreader/app/src/main/java/org/amse/ys/zip/MyBufferedInputStream.java @@ -89,12 +89,43 @@ final class MyBufferedInputStream extends InputStream { return (fourthByte << 24) + (thirdByte << 16) + (secondByte << 8) + firstByte; } - String readString(int stringLength) throws IOException { - char[] array = new char[stringLength]; - for (int i = 0; i < stringLength; i++) { - array[i] = (char)read(); + private static final boolean isUtf8String(byte[] array) { + int nonLeadingCharsCounter = 0; + for (byte b : array) { + if (nonLeadingCharsCounter == 0) { + if ((b & 0x80) != 0) { + if ((b & 0xE0) == 0xC0) { + nonLeadingCharsCounter = 1; + } else if ((b & 0xF0) == 0xE0) { + nonLeadingCharsCounter = 2; + } else if ((b & 0xF8) == 0xF0) { + nonLeadingCharsCounter = 3; + } else { + return false; + } + } + } else { + if ((b & 0xC0) != 0x80) { + return false; + } + --nonLeadingCharsCounter; + } } - return new String(array); + return nonLeadingCharsCounter == 0; + } + + String readString(int stringLength) throws IOException { + final byte[] array = new byte[stringLength]; + read(array); + if (isUtf8String(array)) { + return new String(array, "utf-8"); + } + + final char[] chars = new char[stringLength]; + for (int i = 0; i < stringLength; i++) { + chars[i] = (char)(array[i] & 0xFF); + } + return new String(chars); } @Override diff --git a/jni/NativeFormats/util/AndroidUtil.cpp b/jni/NativeFormats/util/AndroidUtil.cpp index c91d2e7c0..712b46e1f 100644 --- a/jni/NativeFormats/util/AndroidUtil.cpp +++ b/jni/NativeFormats/util/AndroidUtil.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "AndroidUtil.h" #include "JniEnvelope.h" @@ -288,13 +289,13 @@ jstring AndroidUtil::createJavaString(JNIEnv* env, const std::string &str) { } std::string AndroidUtil::convertNonUtfString(const std::string &str) { - const int len = str.length(); - if (len == 0) { + if (ZLUnicodeUtil::isUtf8String(str)) { return str; } JNIEnv *env = getEnv(); + const int len = str.length(); jchar *chars = new jchar[len]; for (int i = 0; i < len; ++i) { chars[i] = (unsigned char)str[i];