-
Notifications
You must be signed in to change notification settings - Fork 246
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
feat(crypto-js): Encode the WASM as base64 for portability #1167
Changes from 10 commits
0938566
4557494
ce03f01
0f104c7
6497d6d
28d4a69
bb96ab8
a4ca6db
9d400a7
898265b
223e65f
aa7d225
d044565
265ac1f
e989bc2
6d21df6
ee27c19
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#!/bin/bash | ||
# | ||
# Build the JavaScript modules | ||
# | ||
# This script is really a workaround for https://github.com/rustwasm/wasm-pack/issues/1074. | ||
# | ||
# Currently, the only reliable way to load WebAssembly in all the JS | ||
# environments we want to target (web-via-webpack, web-via-browserify, jest) | ||
# seems to be to pack the WASM into base64, and then unpack it and instantiate | ||
# it at runtime. | ||
# | ||
# Hopefully one day, https://github.com/rustwasm/wasm-pack/issues/1074 will be | ||
# fixed and this will be unnecessary. | ||
|
||
set -e | ||
|
||
cd $(dirname "$0")/.. | ||
|
||
RUSTFLAGS='-C opt-level=z' WASM_BINDGEN_WEAKREF=1 wasm-pack build --release --target nodejs --scope matrix-org --out-dir pkg | ||
|
||
# Convert the Wasm into a JS file that exports the base64'ed Wasm. | ||
echo "module.exports = \`$(base64 pkg/matrix_sdk_crypto_js_bg.wasm)\`;" > pkg/matrix_sdk_crypto_js_bg.wasm.js | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Hywan I don't love that this means that we'll slurp the whole 4.3MB of base64ed-WASM into bash and pass it as an argument to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh sorry, I was just trying to debug something. Your previous solution was good too! |
||
|
||
# Copy in the unbase64 module | ||
cp scripts/unbase64.js pkg/ | ||
|
||
# In the JavaScript: | ||
# 1. Replace the lines that load the Wasm, | ||
# 2. Remove the imports of `TextDecoder` and `TextEncoder`. We rely on the global defaults. | ||
loadwasm='const bytes = require("./unbase64.js")(require("./matrix_sdk_crypto_js_bg.wasm.js"));' | ||
|
||
# sed on OSX uses different syntax for sed -i, so let's just avoid it. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
sed -e "/^const path = /d" \ | ||
-e "s@^const bytes =.*@${loadwasm}@" \ | ||
-e '/Text..coder.*= require(.util.)/d' \ | ||
pkg/matrix_sdk_crypto_js.js >pkg/matrix_sdk_crypto_js.js.new | ||
mv pkg/matrix_sdk_crypto_js.js.new pkg/matrix_sdk_crypto_js.js |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// JavaScript module which exports a function which will un-base64 a string. | ||
// | ||
// Based on the code at https://developer.mozilla.org/en-US/docs/Glossary/Base64#solution_2_%E2%80%93_rewriting_atob_and_btoa_using_typedarrays_and_utf-8 | ||
|
||
const lookup = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 62, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51]); | ||
|
||
module.exports = (sBase64) => { | ||
const sB64Enc = sBase64.replace(/[^A-Za-z0-9+/]/g, ""); | ||
const nInLen = sB64Enc.length; | ||
const nOutLen = (nInLen * 3 + 1) >> 2; | ||
const taBytes = new Uint8Array(nOutLen); | ||
|
||
let nMod3; | ||
let nMod4; | ||
let nUint24 = 0; | ||
let nOutIdx = 0; | ||
for (let nInIdx = 0; nInIdx < nInLen; nInIdx++) { | ||
nMod4 = nInIdx & 3; | ||
nUint24 |= lookup[sB64Enc.charCodeAt(nInIdx)] << (6 * (3 - nMod4)); | ||
if (nMod4 === 3 || nInLen - nInIdx === 1) { | ||
nMod3 = 0; | ||
while (nMod3 < 3 && nOutIdx < nOutLen) { | ||
taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; | ||
nMod3++; | ||
nOutIdx++; | ||
} | ||
nUint24 = 0; | ||
} | ||
} | ||
|
||
return taBytes; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed these for now as I don't think they'll do the right thing, and they seemed to be a footgun.