Skip to content

Commit

Permalink
Omit all line terminators for ImageStore.getBase64ForTag
Browse files Browse the repository at this point in the history
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 #13856

Differential Revision: D6017764

Pulled By: shergin

fbshipit-source-id: adf667dc722ddfe31449afd8cd20a0a192eacff6
  • Loading branch information
FnTm authored and facebook-github-bot committed Oct 10, 2017
1 parent 7c89cf3 commit 7a7bdee
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,27 +78,34 @@ protected void doInBackgroundGuarded(Void... params) {
ContentResolver contentResolver = getReactApplicationContext().getContentResolver();
Uri uri = Uri.parse(mUri);
InputStream is = contentResolver.openInputStream(uri);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Base64OutputStream b64os = new Base64OutputStream(baos, Base64.DEFAULT);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
try {
while ((bytesRead = is.read(buffer)) > -1) {
b64os.write(buffer, 0, bytesRead);
}
mSuccess.invoke(baos.toString());
mSuccess.invoke(convertInputStreamToBase64OutputStream(is));
} catch (IOException e) {
mError.invoke(e.getMessage());
} finally {
closeQuietly(is);
closeQuietly(b64os); // this also closes baos
}
} catch (FileNotFoundException e) {
mError.invoke(e.getMessage());
}
}
}

String convertInputStreamToBase64OutputStream(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
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);
}
} finally {
closeQuietly(b64os); // this also closes baos and flushes the final content to it
}
return baos.toString();
}

private static void closeQuietly(Closeable closeable) {
try {
closeable.close();
Expand Down
1 change: 1 addition & 0 deletions ReactAndroid/src/test/java/com/facebook/react/modules/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
}

0 comments on commit 7a7bdee

Please sign in to comment.