Open Bug 1919901 Opened 8 days ago Updated 3 days ago

The Wasm JS string builtin 'substring' does not correctly clamp the 'end' param

Categories

(Core :: JavaScript: WebAssembly, defect, P3)

Firefox 130
defect

Tracking

()

UNCONFIRMED

People

(Reporter: sjrdoeraene, Unassigned)

References

(Blocks 2 open bugs)

Details

Attachments

(1 file)

1.26 KB, application/x-zip-compressed
Details
Attached file bug.zip

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0

Steps to reproduce:

Either unzip the attached bug.zip file to a directory, or recreate the files as follows:

index.html:

<html>
<head>
  <title>Bug</title>
</head>
<body>
  <script type=module src="./bug.js"></script>
</body>
</html>

bug.js

const options = {
  builtins: ["js-string"],
};
const instantiated = await WebAssembly.instantiateStreaming(
  fetch("./bug.wasm"), {}, options
);
const instance = instantiated.instance;
console.log(instance);
const { substringBridge } = instance.exports;

console.log(substringBridge("foobar", 1, 4));  // 'oob', OK
console.log(substringBridge("foobar", 1, 6));  // 'oobar', OK
console.log(substringBridge("foobar", 1, 10)); // '', should be 'oobar'
console.log(substringBridge("foobar", 1, -1)); // '', should be 'oobar'

bug.wat

(module
  (type $substringType (func (param externref) (param i32) (param i32) (result (ref extern))))
  (import "wasm:js-string" "substring" (func $substring (type $substringType)))
  (func (export "substringBridge") (param $str externref) (param $start i32) (param $end i32) (result externref)
    local.get $str
    local.get $start
    local.get $end
    call $substring))

and compile to bug.wasm.


Then

  1. In Firefox's about:config page, turn on the option javascript.options.wasm_js_string_builtins
  2. Start a local web server in the given directory (e.g., with npx http-server)
  3. Open http://127.0.0.1:8080/ (or another appropriate URL depending on the web server used)
  4. Open the console
  5. Observe results

Actual results:

The following four strings are logged:

oob
oobar
<empty string>
<empty string>

The last 2 strings are incorrect. They should both be oobar.

Expected results:

oob
oobar
oobar
oobar

Indeed, the spec of the JS string builtin for substring (https://github.com/WebAssembly/js-string-builtins/blob/main/proposals/js-string-builtins/Overview.md#wasmjs-string-substring) says that

  • The integer arguments are interpreted as unsigned 32-bit integers (so -1 is interpreted as 2**32 - 1
  • The end parameter is clamped to the string.length if it is larger.

Therefore, both for 10 and -1, end should be clamped at 6 and behave like the second call.

(For the record, and as some validation that my interpretation of the spec is accurate, V8 behaves as expected.)

The Bugbug bot thinks this bug should belong to the 'Core::JavaScript: WebAssembly' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → JavaScript: WebAssembly
Product: Firefox → Core
Severity: -- → S3
Priority: -- → P3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: