-
Notifications
You must be signed in to change notification settings - Fork 24.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Creating new Blob
from Uint8Array
produces garbage data
#41079
Comments
|
Blob
from Uint8Array
produces garbage data
Still happens for patch 0.72.6, I have updated the issue, please remove the tag |
After a bit more tinkering I think it's really that the Blob implementation does not understand Uint8Arrays, because if I do this (effectively constructing a normal array) I get the same result on the web as I do on a native device: |
@CodyJasonBennett I saw that you implemented some additional Blob code which is not yet released that allows for Blobs to be constructed from ArrayBuffer. From what I was able to gather I think that the changes you did would also allow for Blobs to be constructed from a Uint8Array, but there is no explicit code branch for it here: react-native/packages/react-native/Libraries/Blob/BlobManager.js Lines 70 to 86 in c47bef6
Is that assessment correct? EDIT: I just tried to create a small patch myself which uses 'base64-js'. But this still produces an unusable blob which just contains the base64 content as a string...
|
@CodyJasonBennett how confident are you in your implementation? I just applied all your changes as a patch and tried to construct a blob from an ArrayBuffer and it just gave me a blob which is a basically just the buffer content as text. (The output is the value the blob actually should have if it was base64 encoded) |
For a second I though that this might at least be a workaround |
I'm pretty sure this assumption is correct, and consequently, I'm inclined to revert #39276 until we do this properly. My previous code example did not run into this since text was incidentally decoded by const data = await new Promise((res, rej) => {
const reader = new FileReader()
reader.onload = () => res(reader.result)
reader.onerror = rej
reader.readAsText(blob)
})
// `data:${blob.type};base64,${data}`
`` |
@CodyJasonBennett If you decide to revert the changes maybe there should also be an Error throwing if a part is |
I'm not sure what you mean. The old and current checks consider all typed arrays -- that's what
Upon further review that PR is working as I initially intended even if incomplete -- this is the equivalent code for web That's obviously not desirable here in this issue though. I'm not keen on handling encoding for arbitrary binary data, but I wonder if we can get away with UTF or some other encoding to bring it closer to web. I can't find anything concrete on what the internal behavior should look like as everything states that ASCII should be used for safe transmission. |
In the "old" implementation this was the check, which did not throw an Errror if a part is
|
Summary: As per #41079, we're outputting ASCII encoded data URIs to `FileReader.readAsDataURL` due to lack of native `ArrayBuffer` support and unclear use of encoding to align with web. I'll revisit this at a later point with a better testing strategy once we have a good idea of how this should behave internally. Aside from purely reverting #39276, I've kept the use of `ArrayBuffer.isView(part)` to the previous `part instanceof global.ArrayBufferView` since it is more correct. ## Changelog: [INTERNAL] [REMOVED] - Revert Blob from ArrayBuffer Pull Request resolved: #41170 Test Plan: Run the following at the project root to selectively test changes: `jest packages/react-native/Libraries/Blob` Reviewed By: cipolleschi Differential Revision: D50601036 Pulled By: dmytrorykun fbshipit-source-id: 0ef5c960c253db255c2f8532ea1f44111093706c
facebook#41170) Summary: As per facebook#41079, we're outputting ASCII encoded data URIs to `FileReader.readAsDataURL` due to lack of native `ArrayBuffer` support and unclear use of encoding to align with web. I'll revisit this at a later point with a better testing strategy once we have a good idea of how this should behave internally. Aside from purely reverting facebook#39276, I've kept the use of `ArrayBuffer.isView(part)` to the previous `part instanceof global.ArrayBufferView` since it is more correct. ## Changelog: [INTERNAL] [REMOVED] - Revert Blob from ArrayBuffer Pull Request resolved: facebook#41170 Test Plan: Run the following at the project root to selectively test changes: `jest packages/react-native/Libraries/Blob` Reviewed By: cipolleschi Differential Revision: D50601036 Pulled By: dmytrorykun fbshipit-source-id: 0ef5c960c253db255c2f8532ea1f44111093706c
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
not stale |
On react native 0.75.1 after enabling new arch + bridgeless this got completely broken. The above example throws:
I added workaround in form of turning the chunk into base64 before: function chunkToBase64(chunk) { tho this could potentially affect performance. Does anyone has a better solution / will this be fixed? |
related: #44125 |
Hello everyone, I'm facing the same problem when working with new Uint8Array, I'm using expo in its latest version (51.0.36) and react native in version 0.74.5, I need to do this conversion because I have an api in .Net which only receives a specific type of file, is there anything to solve this problem? |
Description
I'm trying to manually convert base64 data to a Blob and vice versa. To do this I create a
Uint8Array
from the base64 data (withatob
- polyfilled withbase-64
).For example for a very simple PNG the resulting blob is about 3-4x as large as expected and the data is unrecognizable.
The same code works fine on the web and outputs the same result for both log statements.
React Native Version
0.72.6
Output of
npx react-native info
System:
OS: macOS 14.0
CPU: (10) arm64 Apple M1 Pro
Memory: 551.34 MB / 32.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 20.8.0
path: /opt/homebrew/bin/node
Yarn:
version: 1.22.19
path: /usr/local/bin/yarn
npm:
version: 10.2.0
path: /opt/homebrew/bin/npm
Watchman:
version: 2023.10.09.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods:
version: 1.13.0
path: /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 23.0
- iOS 17.0
- macOS 14.0
- tvOS 17.0
- watchOS 10.0
Android SDK: Not Found
IDEs:
Android Studio: 2021.2 AI-212.5712.43.2112.8609683
Xcode:
version: 15.0/15A240d
path: /usr/bin/xcodebuild
Languages:
Java:
version: 11.0.20.1
path: /usr/bin/javac
Ruby:
version: 2.6.10
path: /usr/bin/ruby
npmPackages:
"@react-native-community/cli": Not Found
react:
installed: 18.2.0
wanted: 18.2.0
react-native:
installed: 0.72.5
wanted: 0.72.5
react-native-macos: Not Found
npmGlobalPackages:
"react-native": Not Found
Android:
hermesEnabled: Not found
newArchEnabled: Not found
iOS:
hermesEnabled: Not found
newArchEnabled: Not found
Steps to reproduce
base-64
Snack, screenshot, or link to a repository
https://snack.expo.dev/@stefan-5gpay/base64blobbug
On the web version both are the same:
On device (same for iOS and Android) data is different:
The text was updated successfully, but these errors were encountered: