From c0fdf64ecf3363ea2edaae275a614937a3d7d036 Mon Sep 17 00:00:00 2001 From: webreflection Date: Tue, 18 Aug 2026 09:57:39 +0200 Subject: [PATCH] Avoid throwing on blob: created via URL.createObjectURL() --- src/preamble.js | 25 +++++++++++++------ .../test_codesize_file_preload.expected.js | 7 +++++- .../test_codesize_minimal_O0.expected.js | 25 +++++++++++++------ 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/preamble.js b/src/preamble.js index 79da5c867daa1..74fe8bdbcf1f5 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -100,6 +100,12 @@ function _free() { #endif // free #endif // ASSERTIONS +/** + * Indicates whether filename is delivered via URL.createObjectURL() + * @noinline + */ +var isBlobURI = (filename) => filename.startsWith('blob:'); + /** * Indicates whether filename is delivered via file protocol (as opposed to http/https) * @noinline @@ -685,13 +691,18 @@ async function instantiateAsync(binary, binaryFile, imports) { && !isFileURI(binaryFile) #endif #if ENVIRONMENT_MAY_BE_NODE - // Avoid instantiateStreaming() on Node.js environment for now, as while - // Node.js v18.1.0 implements it, it does not have a full fetch() - // implementation yet. - // - // Reference: - // https://github.com/emscripten-core/emscripten/pull/16917 - && !ENVIRONMENT_IS_NODE + && ( + // Avoid instantiateStreaming() on Node.js environment for now, as while + // Node.js v18.1.0 implements it, it does not have a full fetch() + // implementation yet. + // + // Reference: + // https://github.com/emscripten-core/emscripten/pull/16917 + !ENVIRONMENT_IS_NODE + // On browsers this check won't be reached but on Node.js it is the only way to avoid + // throwing when URL.createObjectURL(blob) has been passed as the binaryFile. + || isBlobURI(binaryFile) + ) #endif #if ENVIRONMENT_MAY_BE_SHELL // Shell environments don't have fetch. diff --git a/test/codesize/test_codesize_file_preload.expected.js b/test/codesize/test_codesize_file_preload.expected.js index 024496f7d7701..b3e691e8214c4 100644 --- a/test/codesize/test_codesize_file_preload.expected.js +++ b/test/codesize/test_codesize_file_preload.expected.js @@ -294,6 +294,11 @@ var ABORT = false; // but only when noExitRuntime is false. var EXITSTATUS; +/** + * Indicates whether filename is delivered via URL.createObjectURL() + * @noinline + */ var isBlobURI = (filename) => filename.startsWith('blob:'); + /** * Indicates whether filename is delivered via file protocol (as opposed to http/https) * @noinline @@ -415,7 +420,7 @@ async function instantiateArrayBuffer(binaryFile, imports) { } async function instantiateAsync(binary, binaryFile, imports) { - if (!binary && !isFileURI(binaryFile) && !ENVIRONMENT_IS_NODE) { + if (!binary && !isFileURI(binaryFile) && (!ENVIRONMENT_IS_NODE || isBlobURI(binaryFile))) { try { var response = fetch(binaryFile, { credentials: "same-origin" diff --git a/test/codesize/test_codesize_minimal_O0.expected.js b/test/codesize/test_codesize_minimal_O0.expected.js index 1b627a7f0a2cf..45677df6b3a7a 100644 --- a/test/codesize/test_codesize_minimal_O0.expected.js +++ b/test/codesize/test_codesize_minimal_O0.expected.js @@ -286,6 +286,12 @@ function _free() { abort('free() called but not included in the build - add `_free` to EXPORTED_FUNCTIONS'); } +/** + * Indicates whether filename is delivered via URL.createObjectURL() + * @noinline + */ +var isBlobURI = (filename) => filename.startsWith('blob:'); + /** * Indicates whether filename is delivered via file protocol (as opposed to http/https) * @noinline @@ -651,13 +657,18 @@ async function instantiateAsync(binary, binaryFile, imports) { if (!binary // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously. && !isFileURI(binaryFile) - // Avoid instantiateStreaming() on Node.js environment for now, as while - // Node.js v18.1.0 implements it, it does not have a full fetch() - // implementation yet. - // - // Reference: - // https://github.com/emscripten-core/emscripten/pull/16917 - && !ENVIRONMENT_IS_NODE + && ( + // Avoid instantiateStreaming() on Node.js environment for now, as while + // Node.js v18.1.0 implements it, it does not have a full fetch() + // implementation yet. + // + // Reference: + // https://github.com/emscripten-core/emscripten/pull/16917 + !ENVIRONMENT_IS_NODE + // On browsers this check won't be reached but on Node.js it is the only way to avoid + // throwing when URL.createObjectURL(blob) has been passed as the binaryFile. + || isBlobURI(binaryFile) + ) ) { try { var response = fetch(binaryFile, { credentials: 'same-origin' });