Skip to content

Commit

Permalink
[android] update base64 decoding options (#7841)
Browse files Browse the repository at this point in the history
* [android] [camera] use .NO_WRAP to encode base64 output

* [android] [image-manipulator] use .NO_WRAP to encode base64 output

* [android] [image-picker] use .NO_WRAP to encode base64 output

* [android] [print] use .NO_WRAP to encode base64 output

* [android] [secure-store] use .NO_WRAP to encode base64 output

Co-authored-by: Bartłomiej Bukowski <bartlomiejbukowski.b@gmail.com>
Co-authored-by: Łukasz Kosmaty <lukasz.kosmaty@student.uj.edu.pl>
  • Loading branch information
3 people committed Apr 16, 2020
1 parent a45fa64 commit 101a207
Show file tree
Hide file tree
Showing 13 changed files with 37 additions and 18 deletions.
21 changes: 13 additions & 8 deletions apps/test-suite/tests/Camera.js
Expand Up @@ -94,15 +94,20 @@ export async function test(t, { setPortalChild, cleanupPortal }) {
t.expect(picture.exif).toBeDefined();
});

t.it('returns Base64 only if requested', async () => {
await mountAndWaitFor(<Camera ref={refSetter} style={style} />);
let picture = await instance.takePictureAsync({ base64: false });
t.expect(picture).toBeDefined();
t.expect(picture.base64).not.toBeDefined();
t.it(
`returns Base64 only if requested, and not contains newline and
special characters (\n or \r)`,
async () => {
await mountAndWaitFor(<Camera ref={refSetter} style={style} />);
let picture = await instance.takePictureAsync({ base64: false });
t.expect(picture).toBeDefined();
t.expect(picture.base64).not.toBeDefined();

picture = await instance.takePictureAsync({ base64: true });
t.expect(picture).toBeDefined();
t.expect(picture.base64).toBeDefined();
picture = await instance.takePictureAsync({ base64: true });
t.expect(picture).toBeDefined();
t.expect(picture.base64).toBeDefined();
t.expect(picture.base64).not.toContain('\n');
t.expect(picture.base64).not.toContain('\r');
});

t.it('returns proper `exif.Flash % 2 = 0` if the flash is off', async () => {
Expand Down
4 changes: 3 additions & 1 deletion apps/test-suite/tests/ImageManipulator.js
Expand Up @@ -55,7 +55,7 @@ export async function test(t) {
t.expect(result.uri.endsWith('.png')).toBe(true);
});

t.it('provides Base64', async () => {
t.it('provides Base64 with no newline terminator', async () => {
const result = await ImageManipulator.manipulateAsync(
image.localUri,
[{ resize: { width: 100, height: 100 } }],
Expand All @@ -65,6 +65,8 @@ export async function test(t) {
);

t.expect(typeof result.base64).toBe('string');
t.expect(result.base64).not.toContain('\n');
t.expect(result.base64).not.toContain('\r');
});

t.it('performs compression', async () => {
Expand Down
2 changes: 2 additions & 0 deletions apps/test-suite/tests/ImagePicker.js
Expand Up @@ -103,6 +103,8 @@ export async function test({ it, xit, beforeAll, expect, jasmine, xdescribe, des
if (!image.cancelled) {
expect(typeof image.base64).toBe('string');
expect(image.base64).not.toBe('');
expect(image.base64).not.toContain('\n');
expect(image.base64).not.toContain('\r');
}
});

Expand Down
2 changes: 2 additions & 0 deletions packages/expo-camera/CHANGELOG.md
Expand Up @@ -4,6 +4,8 @@

### 🛠 Breaking changes

- The base64 output will no longer contain newline and special character (`\n`, `\r`) on Android. ([#7841](https://github.com/expo/expo/pull/7841) by [@jarvisluong](https://github.com/jarvisluong))

### 🎉 New features

### 🐛 Bug fixes
Expand Up @@ -135,7 +135,7 @@ protected Bundle doInBackground(Void... voids) {

// Write base64-encoded image to the response if requested
if (isOptionEnabled(BASE64_KEY)) {
response.putString(BASE64_KEY, Base64.encodeToString(imageStream.toByteArray(), Base64.DEFAULT));
response.putString(BASE64_KEY, Base64.encodeToString(imageStream.toByteArray(), Base64.NO_WRAP));
}

// Cleanup
Expand Down Expand Up @@ -197,7 +197,7 @@ private Bundle handleSkipProcessing() {

// handle base64
if (isOptionEnabled(BASE64_KEY)) {
response.putString(BASE64_KEY, Base64.encodeToString(mImageData, Base64.DEFAULT));
response.putString(BASE64_KEY, Base64.encodeToString(mImageData, Base64.NO_WRAP));
}

return response;
Expand Down
2 changes: 2 additions & 0 deletions packages/expo-image-manipulator/CHANGELOG.md
Expand Up @@ -4,6 +4,8 @@

### 🛠 Breaking changes

- The base64 output will no longer contain newline and special character (`\n`, `\r`) on Android. ([#7841](https://github.com/expo/expo/pull/7841) by [@jarvisluong](https://github.com/jarvisluong))

### 🎉 New features

### 🐛 Bug fixes
Expand Up @@ -154,7 +154,7 @@ private void processBitmapWithActions(Bitmap bitmap, final ArrayList<Action> act
if (saveOptions.hasBase64()) {
byteOut = new ByteArrayOutputStream();
bitmap.compress(saveOptions.getFormat().getCompressFormat(), compression, byteOut);
base64String = Base64.encodeToString(byteOut.toByteArray(), Base64.DEFAULT);
base64String = Base64.encodeToString(byteOut.toByteArray(), Base64.NO_WRAP);
}
} catch (Exception e) {
e.printStackTrace();
Expand Down
2 changes: 2 additions & 0 deletions packages/expo-image-picker/CHANGELOG.md
Expand Up @@ -4,6 +4,8 @@

### 🛠 Breaking changes

- The base64 output will no longer contain newline and special character (`\n`, `\r`) on Android. ([#7841](https://github.com/expo/expo/pull/7841) by [@jarvisluong](https://github.com/jarvisluong))

### 🎉 New features

### 🐛 Bug fixes
Expand Down
Expand Up @@ -643,7 +643,7 @@ private void returnImageResult(Bundle exifData, String uri, int width, int heigh
Bundle response = new Bundle();
response.putString("uri", uri);
if (base64) {
response.putString("base64", Base64.encodeToString(base64OutputStream.toByteArray(), Base64.DEFAULT));
response.putString("base64", Base64.encodeToString(base64OutputStream.toByteArray(), Base64.NO_WRAP));
}
response.putInt("width", width);
response.putInt("height", height);
Expand Down
2 changes: 2 additions & 0 deletions packages/expo-print/CHANGELOG.md
Expand Up @@ -4,6 +4,8 @@

### 🛠 Breaking changes

- The base64 output will no longer contain newline and special character (`\n`, `\r`) on Android. ([#7841](https://github.com/expo/expo/pull/7841) by [@jarvisluong](https://github.com/jarvisluong))

### 🎉 New features

### 🐛 Bug fixes
Expand Up @@ -238,7 +238,7 @@ private String encodeFromFile(File file) throws IOException {
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
byte[] fileBytes = new byte[(int)randomAccessFile.length()];
randomAccessFile.readFully(fileBytes);
return Base64.encodeToString(fileBytes, Base64.DEFAULT);
return Base64.encodeToString(fileBytes, Base64.NO_WRAP);
}

private InputStream decodeDataURI(String uri) {
Expand Down
2 changes: 2 additions & 0 deletions packages/expo-secure-store/CHANGELOG.md
Expand Up @@ -4,6 +4,8 @@

### 🛠 Breaking changes

- The base64 output will no longer contain newline and special character (`\n`, `\r`) on Android. ([#7841](https://github.com/expo/expo/pull/7841) by [@jarvisluong](https://github.com/jarvisluong))

### 🎉 New features

### 🐛 Bug fixes
Expand Up @@ -414,9 +414,9 @@ public JSONObject createEncryptedItem(String plaintextValue, KeyStore keyStore,

byte[] plaintextBytes = plaintextValue.getBytes(StandardCharsets.UTF_8);
byte[] ciphertextBytes = cipher.doFinal(plaintextBytes);
String ciphertext = Base64.encodeToString(ciphertextBytes, Base64.DEFAULT);
String ciphertext = Base64.encodeToString(ciphertextBytes, Base64.NO_WRAP);

String ivString = Base64.encodeToString(gcmSpec.getIV(), Base64.DEFAULT);
String ivString = Base64.encodeToString(gcmSpec.getIV(), Base64.NO_WRAP);
int authenticationTagLength = gcmSpec.getTLen();

return new JSONObject()
Expand Down Expand Up @@ -551,7 +551,7 @@ public JSONObject createEncryptedItem(String plaintextValue, KeyStore keyStore,

// Ensure the IV in the encrypted item matches our generated IV
String ivString = encryptedItem.getString(AESEncrypter.IV_PROPERTY);
String expectedIVString = Base64.encodeToString(ivBytes, Base64.DEFAULT);
String expectedIVString = Base64.encodeToString(ivBytes, Base64.NO_WRAP);
if (!ivString.equals(expectedIVString)) {
Log.e(TAG, String.format("HybridAESEncrypter generated two different IVs: %s and %s", expectedIVString, ivString));
throw new IllegalStateException("HybridAESEncrypter must store the same IV as the one used to parameterize the secret key");
Expand All @@ -562,7 +562,7 @@ public JSONObject createEncryptedItem(String plaintextValue, KeyStore keyStore,
Cipher cipher = getRSACipher();
cipher.init(Cipher.ENCRYPT_MODE, privateKeyEntry.getCertificate());
byte[] encryptedSecretKeyBytes = cipher.doFinal(secretKeyBytes);
String encryptedSecretKeyString = Base64.encodeToString(encryptedSecretKeyBytes, Base64.DEFAULT);
String encryptedSecretKeyString = Base64.encodeToString(encryptedSecretKeyBytes, Base64.NO_WRAP);

// Store the encrypted symmetric key in the encrypted item
return encryptedItem.put(ENCRYPTED_SECRET_KEY_PROPERTY, encryptedSecretKeyString);
Expand Down

0 comments on commit 101a207

Please sign in to comment.