-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Add CROSS_ORIGIN_STORAGE link flag
#27066
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
Open
tomayac
wants to merge
80
commits into
emscripten-core:main
Choose a base branch
from
tomayac:cross-origin-storage
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
80 commits
Select commit
Hold shift + click to select a range
9024b2f
feat: add CROSS_ORIGIN_STORAGE support for Wasm loading
tomayac 403c59f
fix: correct COS implementation to match WICG explainer API
tomayac 4657036
test: add test suite for CROSS_ORIGIN_STORAGE feature
tomayac 44f94e5
docs: add Cross-Origin Storage guide and polish setting comment
tomayac 7ea1d45
test: add cross_origin_storage browser example
tomayac 5c65fe5
feat: add COS instrumentation callbacks and update example/docs/tests
tomayac e123413
fix: add link-time validation and changelog entry for CROSS_ORIGIN_ST…
tomayac e094e46
fix: remove incorrect 'base64' claim in SINGLE_FILE + COS descriptions
tomayac df886f9
feat: warn when CROSS_ORIGIN_STORAGE is used with SPLIT_MODULE or MAI…
tomayac 894cedc
fix: warn when CROSS_ORIGIN_STORAGE is used with SIDE_MODULE
tomayac 4c872ed
docs: clarify that COS only makes sense for widely-shared public Wasm…
tomayac 343d0b9
feat: add CROSS_ORIGIN_STORAGE_ORIGINS setting
tomayac d87413a
fix: make '*' the implicit default for CROSS_ORIGIN_STORAGE_ORIGINS
tomayac 186e8cb
fix: final polish — warnings, stale comments, doc consistency
tomayac 461b275
test: add missing SIDE_MODULE warning test for CROSS_ORIGIN_STORAGE
tomayac 1410b97
fix: correct COS test failures and add demo Makefile
tomayac 9533aaf
docs: replace concrete project examples with generic descriptions
tomayac a32dad5
docs: add Chrome Web Store link for COS extension in See also
tomayac 80d15c2
docs: replace CDN framing with 'popular' in COS guide
tomayac 6635a14
docs: note multi-origin exception and origins flag in COS when-to-use
tomayac 7522109
feat: pass hash as first arg to onCOSCacheMiss(hash, url)
tomayac 485d6ab
docs: remove CDN mention and add visibility/security note in preamble.js
tomayac 6e0f82b
docs: add timing-oracle security note to visibility upgrade callout i…
tomayac b38d5bc
docs: remove CDN mentions from CROSS_ORIGIN_STORAGE settings comments
tomayac 4141f13
style: normalize double spaces after periods in COS settings comments
tomayac 906d53d
style: use American spelling 'serialized' consistently
tomayac 1c944e7
docs: describe progressive enhancement and fallback path in COS examp…
tomayac 6656094
fix: ruff docstring formatting and regenerate settings_reference.rst
tomayac 0ebc151
docs: warn about post-emcc wasm post-processing invalidating the embe…
tomayac d4b44f2
feat(cross-origin-storage): expose Module['wasmSHA256'] for custom in…
tomayac 7a7efe7
fix(cross-origin-storage): also patch Module['wasmSHA256'] in post-bi…
tomayac c10b7ba
Merge branch 'main' into cross-origin-storage
tomayac 05dafe6
docs: drop =1 from -sCROSS_ORIGIN_STORAGE flag references in COS guide
tomayac ed5611e
docs: use :ref: cross-references for settings in COS guide prose
tomayac db36d8b
docs: remove redundant link-time note from COS usage section
tomayac 5dfb0c3
docs: use unquoted comma-separated syntax for CROSS_ORIGIN_STORAGE_OR…
tomayac f1ce667
docs: use comma-separated syntax for CROSS_ORIGIN_STORAGE_ORIGINS exa…
tomayac 9c1056d
fix: make CROSS_ORIGIN_STORAGE + WASM_ASYNC_COMPILATION=0 a hard error
tomayac 419d0bf
docs: update build-time constant example to match current cosHash obj…
tomayac 37988bf
docs: use Module['wasmSHA256'] consistently and fix sed to patch both…
tomayac d459be3
refactor: rename wasmSHA256 to wasmHash and expose {algorithm,value} …
tomayac 0efc119
refactor: address multiple PR review comments on CROSS_ORIGIN_STORAGE
tomayac ce79cdb
refactor: make COS instrumentation callbacks opt-in via INCOMING_MODU…
tomayac 9596b82
Add browser tests
tomayac 619dedf
fix: CI failures — ruff, build-docs, and browser-test experimental wa…
tomayac 748585d
remove: dead WASM_SHA256 internal setting
tomayac 765ed7a
style: add -O2 to COS example build and browser tests
tomayac e5b74d5
chore: untrack generated COS example build artifacts
tomayac 3ad3cc8
test: log COS events to console in miss_then_hit browser test
tomayac 4302b9c
Merge branch 'main' into cross-origin-storage
tomayac 09ae30d
style: move [experimental] tag to end of CROSS_ORIGIN_STORAGE comment
tomayac e624ca2
fix: remove redundant cosHash?.value guard in COS preamble
tomayac a1e290c
fix: make CROSS_ORIGIN_STORAGE a hard error for non-web environments
tomayac 46d948f
remove: Makefile from COS example directory
tomayac 408118d
style: drop -o flag from COS error-only tests
tomayac ed92f2f
style: prefer hello_world.c over hello_world.cpp in COS tests
tomayac 278eb7f
style: drop docstrings and comments from COS tests
tomayac f2c9029
refactor: extract setup_cross_origin_storage() from phase_linker_setup
tomayac 8d399fa
remove: COS example build artifact entries from .gitignore
tomayac b09b640
refactor: consolidate 19 COS unit tests into 5
tomayac f8f5ddd
merge: resolve import conflict with upstream main
tomayac 9465e49
style: shorten COS ChangeLog entry to 3 lines
tomayac f7ce0fd
remove: test_cross_origin_storage_callbacks from test_other.py
tomayac a77d2fb
fix: copyright year and remove redundant build comment from main.cpp
tomayac 4a038e4
remove: test/cross_origin_storage/ example directory
tomayac 7fe5ed9
Make feature detection rock-solid
tomayac 2f21411
Make feature detection compact
tomayac bc048fb
fix: use Markdown syntax in ChangeLog, not RST :ref:
tomayac 146cf39
refactor: move COS incompatibilities to INCOMPATIBLE_SETTINGS
tomayac d057132
style: clean up COS browser tests
tomayac d12b027
style: add PR number to COS ChangeLog entry
tomayac 4834510
refactor: clean up COS preamble and hash injection
tomayac ed25ea6
Merge remote-tracking branch 'upstream/main' into cross-origin-storage
tomayac c9bc25f
test: simplify COS assertions — use tighter algorithm+value regex
tomayac 33e2369
test: use simplified CROSS_ORIGIN_STORAGE_ORIGINS syntax in test
tomayac 64eb609
test: drop redundant -sENVIRONMENT=web from COS error tests (web is d…
tomayac fb71285
Merge branch 'main' into cross-origin-storage
tomayac 12c24a0
test: add TODO to remove COS extension once Chromium ships the featur…
tomayac 1466998
Rebaseline codesize test to fix CI
tomayac 5dafaae
Merge branch 'main' into cross-origin-storage
tomayac File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| #!/usr/bin/env python3 | ||
| # Copyright 2026 The Emscripten Authors. All rights reserved. | ||
| # Emscripten is available under two separate licenses, the MIT license and the | ||
| # University of Illinois/NCSA Open Source License. Both these licenses can be | ||
| # found in the LICENSE file. | ||
|
|
||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| r"""Download the Cross-Origin Storage Chrome extension for COS browser tests. | ||
|
|
||
| The COS extension polyfills navigator.crossOriginStorage in Chrome so that | ||
| automated browser tests can exercise the cache-miss and cache-hit paths without | ||
| requiring a native browser implementation of the API. | ||
|
|
||
| Usage | ||
| ----- | ||
|
|
||
| Run once to download and unpack the extension:: | ||
|
|
||
| python3 test/setup_cos_extension.py | ||
|
|
||
| Then pass the printed path as EMTEST_COS_EXTENSION_PATH when running the | ||
| browser tests:: | ||
|
|
||
| EMTEST_COS_EXTENSION_PATH=$(python3 test/setup_cos_extension.py) \\ | ||
| python3 test/runner.py browser.test_cross_origin_storage_miss_then_hit | ||
|
|
||
| Or, with --print-path suppressed so only the path is printed (suitable for | ||
| shell variable assignment), use --quiet:: | ||
|
|
||
| ext=$(python3 test/setup_cos_extension.py --quiet) | ||
| EMTEST_COS_EXTENSION_PATH=$ext python3 test/runner.py \\ | ||
| browser.test_cross_origin_storage_fallback \\ | ||
| browser.test_cross_origin_storage_miss_then_hit | ||
|
|
||
| The extension is downloaded from its GitHub source repository and unpacked into | ||
| out/cos_extension/ (relative to the Emscripten root). Re-run with --force to | ||
| refresh an existing download. | ||
|
|
||
| Source: https://github.com/web-ai-community/cross-origin-storage-extension | ||
| """ | ||
|
|
||
| import argparse | ||
| import io | ||
| import os | ||
| import sys | ||
| import urllib.request | ||
| import zipfile | ||
|
|
||
| # Archive of the main branch of the COS extension source repository. | ||
| EXTENSION_ARCHIVE_URL = ( | ||
| 'https://github.com/web-ai-community/cross-origin-storage-extension' | ||
| '/archive/refs/heads/main.zip' | ||
| ) | ||
|
|
||
| # Default destination relative to the Emscripten root (i.e. two levels up from | ||
| # this script, which lives in test/). | ||
| _SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) | ||
| DEFAULT_DEST = os.path.join(_SCRIPT_DIR, '..', 'out', 'cos_extension') | ||
|
|
||
|
|
||
| def _find_manifest(root): | ||
| """Return the directory containing manifest.json, searching up to 2 levels. | ||
|
|
||
| Returns None if root does not exist or no manifest.json is found. | ||
| """ | ||
| if not os.path.isdir(root): | ||
| return None | ||
| if os.path.exists(os.path.join(root, 'manifest.json')): | ||
| return root | ||
| for entry in os.scandir(root): | ||
| if entry.is_dir(): | ||
| candidate = os.path.join(entry.path, 'manifest.json') | ||
| if os.path.exists(candidate): | ||
| return entry.path | ||
| return None | ||
|
|
||
|
|
||
| def download_and_unpack(dest_dir, quiet=False): | ||
| """Download the extension archive from GitHub and unpack it into dest_dir. | ||
|
|
||
| Returns the path of the directory that contains manifest.json. | ||
| """ | ||
| if not quiet: | ||
| print('Downloading COS extension from GitHub...', file=sys.stderr) | ||
| req = urllib.request.Request( | ||
| EXTENSION_ARCHIVE_URL, | ||
| headers={'User-Agent': 'emscripten-test-setup'}, | ||
| ) | ||
| with urllib.request.urlopen(req) as response: | ||
| data = response.read() | ||
|
|
||
| if not quiet: | ||
| print(f'Unpacking to {dest_dir} ...', file=sys.stderr) | ||
| os.makedirs(dest_dir, exist_ok=True) | ||
|
|
||
| with zipfile.ZipFile(io.BytesIO(data)) as zf: | ||
| # GitHub archives wrap everything in a top-level directory, e.g. | ||
| # "cross-origin-storage-extension-main/". Strip that prefix. | ||
| names = zf.namelist() | ||
| prefix = names[0].split('/')[0] + '/' if names else '' | ||
| for member in names: | ||
| if member == prefix: | ||
| continue | ||
| rel = member[len(prefix):] | ||
| if not rel: | ||
| continue | ||
| target = os.path.join(dest_dir, rel) | ||
| if member.endswith('/'): | ||
| os.makedirs(target, exist_ok=True) | ||
| else: | ||
| os.makedirs(os.path.dirname(target), exist_ok=True) | ||
| with zf.open(member) as src, open(target, 'wb') as dst: | ||
| dst.write(src.read()) | ||
|
|
||
| extension_dir = _find_manifest(dest_dir) | ||
| if extension_dir is None: | ||
| print( | ||
| f'ERROR: manifest.json not found anywhere under {dest_dir}.\n' | ||
| 'The extension repository structure may have changed.\n' | ||
| 'Please report this at https://github.com/emscripten-core/emscripten/issues', | ||
| file=sys.stderr, | ||
| ) | ||
| sys.exit(1) | ||
|
|
||
| return extension_dir | ||
|
|
||
|
|
||
| def main(): | ||
| parser = argparse.ArgumentParser( | ||
| description=__doc__, | ||
| formatter_class=argparse.RawDescriptionHelpFormatter, | ||
| ) | ||
| parser.add_argument( | ||
| '--dest', | ||
| default=DEFAULT_DEST, | ||
| help='Directory to unpack the extension into (default: out/cos_extension)', | ||
| ) | ||
| parser.add_argument( | ||
| '--force', | ||
| action='store_true', | ||
| help='Re-download even if the extension is already present', | ||
| ) | ||
| parser.add_argument( | ||
| '--quiet', | ||
| action='store_true', | ||
| help='Suppress informational messages; print only the extension path', | ||
| ) | ||
| args = parser.parse_args() | ||
|
|
||
| dest = os.path.realpath(args.dest) | ||
|
|
||
| extension_dir = _find_manifest(dest) | ||
| if extension_dir and not args.force: | ||
| if not args.quiet: | ||
| print( | ||
| f'Extension already present at {extension_dir} ' | ||
| f'(use --force to re-download)', | ||
| file=sys.stderr, | ||
| ) | ||
| else: | ||
| extension_dir = download_and_unpack(dest, quiet=args.quiet) | ||
| if not args.quiet: | ||
| print(f'Extension ready at {extension_dir}', file=sys.stderr) | ||
|
|
||
| # Always print the path as the last line so callers can capture it with | ||
| # $(...) or --quiet. | ||
| print(extension_dir) | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| main() |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.