diff --git a/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java b/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java index abc17f7bc..aa8241dff 100644 --- a/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java +++ b/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java @@ -21,7 +21,9 @@ import com.facebook.react.modules.core.DeviceEventManagerModule; import java.io.*; +import java.nio.ByteBuffer; import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; import java.security.MessageDigest; import java.util.ArrayList; import java.util.HashMap; @@ -339,7 +341,9 @@ else if(resolved == null) { boolean error = false; if (encoding.equalsIgnoreCase("utf8")) { + CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder(); while ((cursor = fs.read(buffer)) != -1) { + encoder.encode(ByteBuffer.wrap(buffer).asCharBuffer()); String chunk = new String(buffer, 0, cursor); emitStreamEvent(streamId, "data", chunk); if(tick > 0) diff --git a/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java b/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java index a894aec93..b73907950 100644 --- a/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java +++ b/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java @@ -36,6 +36,10 @@ import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.URL; +import java.nio.ByteBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; import java.security.KeyStore; import java.util.ArrayList; import java.util.Arrays; @@ -498,12 +502,28 @@ private void done(Response resp) { // encoding will somehow break the UTF8 string format, to encode UTF8 // string correctly, we should do URL encoding before BASE64. byte[] b = resp.body().bytes(); + CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder(); if(responseFormat == ResponseFormat.BASE64) { callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_BASE64, android.util.Base64.encodeToString(b, Base64.NO_WRAP)); return; } - String utf8 = new String(b); - callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_UTF8, utf8); + try { + encoder.encode(ByteBuffer.wrap(b).asCharBuffer()); + // if the data contains invalid characters the following lines will be + // skipped. + String utf8 = new String(b); + callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_UTF8, utf8); + } + // This usually mean the data is contains invalid unicode characters, it's + // binary data + catch(CharacterCodingException ignored) { + if(responseFormat == ResponseFormat.UTF8) { + callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_UTF8, ""); + } + else { + callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_BASE64, android.util.Base64.encodeToString(b, Base64.NO_WRAP)); + } + } } } catch (IOException e) { callback.invoke("RNFetchBlob failed to encode response data to BASE64 string.", null);