commit db1c582340f0863be18fda49790405ce18eacd91
parent 32076d9dcc345a8975eea8cfbff1469512721b34
Author: Dominic Farolino <dom@chromium.org>
Date: Wed, 3 Dec 2025 13:57:15 +0000
Bug 2003273 [wpt PR 56366] - Crash: Enforce initialization length of bytes, a=testonly
Automatic update from web-platform-tests
Crash: Enforce initialization length of bytes
Prior to this CL, one could call `CrashReportStorage#initialize()` to,
in theory, initialize a number of bytes available for crash reporting
storage, and then call `set()` with arbitrarily large strings and never
observe an error when going over the initially requested size.
This CL enforces the requested length in each call to `set()`, ensuring
that an `NotAllowedError` DOMException is thrown whenever it would
overflow the initially requested size. This is done by maintaining
another copy of the K/V data in the renderer process, owned and managed
by `blink::CrashReportStorage`.
Note that this only enforces the length in the renderer process, as this
CL is really just a preparatory CL for the shared memory integration
https://crrev.com/c/6788146. It's more about getting the expected
behavior right for the Origin Trial, than the security of the feature
that will be enforced in the shared memory version.
R=dcheng
Bug: 400432195
Change-Id: Ia8838d03826aa840cca373a58eb4bb621b53e23d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7201910
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Dominic Farolino <dom@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1552125}
--
wpt-commits: ece6ee69e36e05a5851498619e7e38831094632b
wpt-pr: 56366
Diffstat:
1 file changed, 47 insertions(+), 0 deletions(-)
diff --git a/testing/web-platform/tests/reporting/crashReport-test.html b/testing/web-platform/tests/reporting/crashReport-test.html
@@ -138,5 +138,52 @@ promise_test(async t => {
child_window.crashReport.set('key', 'value');
child_window.crashReport.remove('key');
}, 'crashReport.set() and .remove() succeed after initialize() resolves');
+
+promise_test(async t => {
+ const iframe = document.createElement('iframe');
+ const loadPromise = new Promise(resolve => iframe.onload = resolve);
+ document.body.appendChild(iframe);
+ t.add_cleanup(() => iframe.remove());
+ await loadPromise;
+
+ const child_window = iframe.contentWindow;
+
+ // 8 bytes is too small for the key/value pair "a"/"a" to be written; the
+ // memory required is 9 bytes, to support the JSONified format:
+ //
+ // {"a":"a"}
+ //
+ // Similarly, 17 bytes is required for "a"/"a" *and* "b"/"b" to be written, to
+ // support the format:
+ //
+ // {"a":"a","b":"b"}
+ await child_window.crashReport.initialize(8);
+ assert_throws_dom('NotAllowedError', child_window.DOMException, () => {
+ child_window.crashReport.set('a', 'a');
+ });
+
+ // This just fits in our 8-byte buffer though!
+ child_window.crashReport.set('b', '');
+}, 'crashReport.set() throws when there is not enough memory');
+
+promise_test(async t => {
+ const iframe = document.createElement('iframe');
+ const loadPromise = new Promise(resolve => iframe.onload = resolve);
+ document.body.appendChild(iframe);
+ t.add_cleanup(() => iframe.remove());
+ await loadPromise;
+
+ const child_window = iframe.contentWindow;
+
+ await child_window.crashReport.initialize(9);
+ child_window.crashReport.set('a', 'a');
+ assert_throws_dom('NotAllowedError', child_window.DOMException, () => {
+ child_window.crashReport.set('b', 'b');
+ });
+ child_window.crashReport.remove('a');
+ // Now `set()` will work again.
+ child_window.crashReport.set('b', 'b');
+}, 'crashReport.remove() properly frees memory, and allows you to invoke ' +
+ 'set() again, assigning bytes to memory that was previously full');
</script>
</body>