Omit all line terminators for ImageStore.getBase64ForTag

Summary:
FIX #11142

This fixes #11142 and supersedes #11155 as I was unsure how to add/change commits in that PR.

Wrote up a bunch of unit tests for the ImageStore module. The added tests showed that there was indeed a problem with the flags used for the Base64OutputStream, and they also show that that has been fixed now.
Closes https://github.com/facebook/react-native/pull/13856

Differential Revision: D6017764

Pulled By: shergin

fbshipit-source-id: adf667dc722ddfe31449afd8cd20a0a192eacff6
This commit is contained in:
Janis Peisenieks 2017-10-09 22:02:56 -07:00 committed by Facebook Github Bot
parent 7c89cf37c6
commit 7a7bdeec3e
3 changed files with 104 additions and 9 deletions

View File

@ -78,25 +78,32 @@ public class ImageStoreManager extends ReactContextBaseJavaModule {
ContentResolver contentResolver = getReactApplicationContext().getContentResolver();
Uri uri = Uri.parse(mUri);
InputStream is = contentResolver.openInputStream(uri);
try {
mSuccess.invoke(convertInputStreamToBase64OutputStream(is));
} catch (IOException e) {
mError.invoke(e.getMessage());
} finally {
closeQuietly(is);
}
} catch (FileNotFoundException e) {
mError.invoke(e.getMessage());
}
}
}
String convertInputStreamToBase64OutputStream(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Base64OutputStream b64os = new Base64OutputStream(baos, Base64.DEFAULT);
Base64OutputStream b64os = new Base64OutputStream(baos, Base64.NO_WRAP);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
try {
while ((bytesRead = is.read(buffer)) > -1) {
b64os.write(buffer, 0, bytesRead);
}
mSuccess.invoke(baos.toString());
} catch (IOException e) {
mError.invoke(e.getMessage());
} finally {
closeQuietly(is);
closeQuietly(b64os); // this also closes baos
}
} catch (FileNotFoundException e) {
mError.invoke(e.getMessage());
}
closeQuietly(b64os); // this also closes baos and flushes the final content to it
}
return baos.toString();
}
private static void closeQuietly(Closeable closeable) {

View File

@ -26,6 +26,7 @@ rn_robolectric_test(
react_native_target("java/com/facebook/react/common/network:network"),
react_native_target("java/com/facebook/react/devsupport:interfaces"),
react_native_target("java/com/facebook/react/jstasks:jstasks"),
react_native_target("java/com/facebook/react/modules/camera:camera"),
react_native_target("java/com/facebook/react/modules/clipboard:clipboard"),
react_native_target("java/com/facebook/react/modules/common:common"),
react_native_target("java/com/facebook/react/modules/core:core"),

View File

@ -0,0 +1,87 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.modules.camera;
import android.util.Base64;
import android.util.Base64InputStream;
import com.facebook.react.bridge.ReactApplicationContext;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.robolectric.RobolectricTestRunner;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Random;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.mockito.Mockito.mock;
@RunWith(RobolectricTestRunner.class)
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"})
public class ImageStoreManagerTest {
@Test
public void itDoesNotAddLineBreaks_whenBasicStringProvided() throws IOException {
byte[] exampleString = "test".getBytes();
assertEquals("dGVzdA==", invokeConversion(new ByteArrayInputStream(exampleString)));
}
@Test
public void itDoesNotAddLineBreaks_whenEmptyStringProvided() throws IOException {
byte[] exampleString = "".getBytes();
assertEquals("", invokeConversion(new ByteArrayInputStream(exampleString)));
}
@Test
public void itDoesNotAddLineBreaks_whenStringWithSpecialCharsProvided() throws IOException {
byte[] exampleString = "sdfsdf\nasdfsdfsdfsd\r\nasdas".getBytes();
ByteArrayInputStream inputStream = new ByteArrayInputStream(exampleString);
assertFalse(invokeConversion(inputStream).contains("\n"));
}
/**
* This test tries to test the conversion when going beyond the current buffer size (8192 bytes)
*/
@Test
public void itDoesNotAddLineBreaks_whenStringBiggerThanBuffer() throws IOException {
ByteArrayInputStream inputStream = new ByteArrayInputStream(generateRandomByteString(10000));
assertFalse(invokeConversion(inputStream).contains("\n"));
}
/**
* Just to test if using the ByteArrayInputStream isn't missing something
*/
@Test
public void itDoesNotAddLineBreaks_whenBase64InputStream() throws IOException {
byte[] exampleString = "dGVzdA==".getBytes();
Base64InputStream inputStream =
new Base64InputStream(new ByteArrayInputStream(exampleString), Base64.NO_WRAP);
assertEquals("dGVzdA==", invokeConversion(inputStream));
}
private String invokeConversion(InputStream inputStream) throws IOException {
return new ImageStoreManager(mock(ReactApplicationContext.class))
.convertInputStreamToBase64OutputStream(inputStream);
}
private byte[] generateRandomByteString(final int length) {
Random r = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
char c = (char) (r.nextInt((int) (Character.MAX_VALUE)));
sb.append(c);
}
return sb.toString().getBytes();
}
}