tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 91b141b818516bb2f162b43c7a4cfdb2d91f9814
parent 65a54d7720b4a73fd936b97366fd94c2096e83ff
Author: Miao Bin <bin.miao@intel.com>
Date:   Fri,  9 Jan 2026 08:36:49 +0000

Bug 2009097 [wpt PR 57066] - WebNN: Replace null characters in node names for ORT backend, a=testonly

Automatic update from web-platform-tests
WebNN: Replace null characters in node names for ORT backend

Operation label contains null characters ('\0') may cause ORT's
CreateSessionFromModel API to fail with "two nodes with the same node
name".

This CL adds a WPT case introduces a graph containing two add operations
named 'node\0a' and 'node\0b'. These will be truncated to the same name
'node' in the CreateSessionFromModel API and leading to the error.

This CL replaces all '\0' characters with '_' in operation labels to
ensure compatibility with ORT's C API. And the unique
`next_operation_id_` appended to node names prevented collisions.

Bug: 471649998
Change-Id: I2340ca2ed8e1b7aa44a4909f91f0589d8e0b8294
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7330619
Reviewed-by: Rafael Cintron <rafael.cintron@microsoft.com>
Reviewed-by: Hu, Ningxin <ningxin.hu@intel.com>
Reviewed-by: David Baron <dbaron@chromium.org>
Commit-Queue: Miao, Bin <bin.miao@intel.com>
Cr-Commit-Position: refs/heads/main@{#1566067}

--

wpt-commits: a564417be56ae6880d5b9ab72731f2272e5a7cff
wpt-pr: 57066

Diffstat:
Atesting/web-platform/tests/webnn/conformance_tests/operations-with-special-names.https.any.js | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 98 insertions(+), 0 deletions(-)

diff --git a/testing/web-platform/tests/webnn/conformance_tests/operations-with-special-names.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/operations-with-special-names.https.any.js @@ -0,0 +1,98 @@ +// META: title=test input with special character names +// META: global=window +// META: variant=?cpu +// META: variant=?gpu +// META: variant=?npu +// META: script=../resources/utils.js +// META: timeout=long + +'use strict'; + +// https://www.w3.org/TR/webnn/#dom-mloperatoroptions-label + +let mlContext; + +// Skip tests if WebNN is unimplemented. +promise_setup(async () => { + assert_implements(navigator.ml, 'missing navigator.ml'); + mlContext = await navigator.ml.createContext(contextOptions); +}); + +const specialNameArray = [ + ['12-L#!.☺', '🤦🏼‍♂️124DS#!F'], + + // Escape Sequence + ['\0node_a', '\0node_b'], + ['node\0a', 'node\0b'], + + // Hexadecimal Escape Sequences + // '\x41'→ 'A' + ['\x41\x41\x41', '\x42\x42\x42'], + + // Unicode & Hexadecimal Characters + // "\u00A9" → "©" + // "\xA9" → "©" + // "\u2665" → "♥" + // "\u2026" → "…" + // "\U0001F600" → 😀 (Grinning Face Emoji) + ['\u00A9\xA9\u2665\u2026', '\U0001F600'] +]; + +specialNameArray.forEach((name) => { + promise_test(async () => { + // The following code builds a graph as: + // constant1 ---+ + // +--- Add (label_0) ---> intermediateOutput1 ---+ + // input1 ---+ | + // +--- Mul---> output + // constant2 ---+ | + // +--- Add (label_1) ---> intermediateOutput2 ---+ + // input2 ---+ + + const TENSOR_DIMS = [1, 2, 2, 2]; + const TENSOR_SIZE = 8; + + const builder = new MLGraphBuilder(mlContext); + const desc = { dataType: 'float32', shape: TENSOR_DIMS }; + const constantBuffer1 = new Float32Array(TENSOR_SIZE).fill(0.5); + const constant1 = builder.constant(desc, constantBuffer1); + + const input1 = builder.input('input1', desc); + const constantBuffer2 = new Float32Array(TENSOR_SIZE).fill(0.5); + const constant2 = builder.constant(desc, constantBuffer2); + + const input2 = builder.input('input2', desc); + + const intermediateOutput1 = builder.add(constant1, input1, {label: name[0]}); + const intermediateOutput2 = builder.add(constant2, input2, {label: name[1]}); + + const output = builder.mul(intermediateOutput1, intermediateOutput2); + const graph = await builder.build({'output': output}); + + const inputBuffer1 = new Float32Array(TENSOR_SIZE).fill(1); + const inputBuffer2 = new Float32Array(TENSOR_SIZE).fill(1); + + desc.writable = true; + const inputTensor1 = await mlContext.createTensor(desc); + const inputTensor2 = await mlContext.createTensor(desc); + mlContext.writeTensor(inputTensor1, inputBuffer1); + mlContext.writeTensor(inputTensor2, inputBuffer2); + + const outputTensor = await mlContext.createTensor({ + ...desc, + readable: true, + writable: false, + }); + + const inputs = { + 'input1': inputTensor1, + 'input2': inputTensor2, + }; + const outputs = {'output': outputTensor}; + mlContext.dispatch(graph, inputs, outputs); + + assert_array_equals( + new Float32Array(await mlContext.readTensor(outputTensor)), + Float32Array.from([2.25, 2.25, 2.25, 2.25, 2.25, 2.25, 2.25, 2.25])); + }, `'add' nodes with special character name '${name[0]}' and '${name[1]}'`); +});