tor-browser

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

commit 459880d45518445afafc1f719348b8adc175a988
parent 0f95ad06ca0c379a67165c493b2a8c36e659e814
Author: Zijie Zhao <zijie4@illinois.edu>
Date:   Fri, 31 Oct 2025 05:17:53 +0000

Bug 1997216 - Fix Exception::ColumnNumber to return actual column number. r=arai,emilio

Differential Revision: https://phabricator.services.mozilla.com/D270636

Diffstat:
Mdom/base/DOMException.cpp | 8+++++++-
Mdom/base/DOMException.h | 2+-
Mdom/bindings/Bindings.conf | 4++--
Mdom/bindings/test/mochitest.toml | 2++
Adom/bindings/test/test_exception_line_column.html | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdom/bindings/test/test_exception_options_from_jsimplemented.html | 27+++++++++++++--------------
Mjs/xpconnect/src/ExecutionTracerIntegration.cpp | 2+-
Mjs/xpconnect/src/nsXPConnect.cpp | 2+-
8 files changed, 79 insertions(+), 20 deletions(-)

diff --git a/dom/base/DOMException.cpp b/dom/base/DOMException.cpp @@ -289,7 +289,13 @@ uint32_t Exception::LineNumber(JSContext* aCx) const { return 0; } -uint32_t Exception::ColumnNumber() const { return 0; } +uint32_t Exception::ColumnNumber(JSContext* aCx) const { + if (mLocation) { + return mLocation->GetColumnNumber(aCx); + } + + return 0; +} already_AddRefed<nsIStackFrame> Exception::GetLocation() const { nsCOMPtr<nsIStackFrame> location = mLocation; diff --git a/dom/base/DOMException.h b/dom/base/DOMException.h @@ -89,7 +89,7 @@ class Exception : public nsIException, public nsWrapperCache { uint32_t LineNumber(JSContext* aCx) const; - uint32_t ColumnNumber() const; + uint32_t ColumnNumber(JSContext* aCx) const; already_AddRefed<nsIStackFrame> GetLocation() const; diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf @@ -219,7 +219,7 @@ DOMInterfaces = { }, 'DOMException': { - 'implicitJSContext': [ 'filename', 'lineNumber', 'stack' ], + 'implicitJSContext': [ 'filename', 'lineNumber', 'columnNumber', 'stack' ], }, 'DOMMatrixReadOnly': { @@ -260,7 +260,7 @@ DOMInterfaces = { 'Exception': { 'headerFile': 'mozilla/dom/DOMException.h', - 'implicitJSContext': [ '__stringifier', 'filename', 'lineNumber', 'stack' ], + 'implicitJSContext': [ '__stringifier', 'filename', 'lineNumber', 'columnNumber', 'stack' ], }, 'ExtendableEvent': { diff --git a/dom/bindings/test/mochitest.toml b/dom/bindings/test/mochitest.toml @@ -96,6 +96,8 @@ skip-if = ["!debug"] ["test_exceptionThrowing.html"] +["test_exception_line_column.html"] + ["test_exception_messages.html"] ["test_exception_options_from_jsimplemented.html"] diff --git a/dom/bindings/test/test_exception_line_column.html b/dom/bindings/test/test_exception_line_column.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1997216 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1997216</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1997216 */ + + // Test 1: DOMException from querySelector + try { + document.querySelector('###INVALID_SELECTOR###'); + ok(false, "Should have thrown"); + } catch (e) { + is(e.lineNumber, 17, "querySelector exception should be on line 17"); + is(e.columnNumber, 14, "querySelector exception should be on column 14"); + } + + // Test 2: Manually created DOMException + try { + throw new DOMException('Test exception', 'NotFoundError'); + } catch (e) { + is(e.lineNumber, 26, "Manual DOMException should be on line 26"); + is(e.columnNumber, 11, "Manual DOMException should be on column 11"); + } + + // Test 3: DOMException from invalid appendChild + try { + document.documentElement.appendChild(null); + ok(false, "Should have thrown"); + } catch (e) { + is(e.lineNumber, 34, "appendChild exception should be on line 34"); + is(e.columnNumber, 30, "appendChild exception should be on column 30"); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1997216">Mozilla Bug 1997216</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/bindings/test/test_exception_options_from_jsimplemented.html b/dom/bindings/test/test_exception_options_from_jsimplemented.html @@ -20,7 +20,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107592 var asyncFrame; /* Async parent frames from pushPrefEnv don't show up in e10s. */ if (!SpecialPowers.getBoolPref("javascript.options.asyncstack_capture_debuggee_only")) { - asyncFrame = `Async*@${file}:153:17 + asyncFrame = `Async*@${file}:152:17 `; } else { asyncFrame = ""; @@ -64,8 +64,7 @@ ${asyncFrame}`, file, "Should still have the right file name"); is(e.lineNumber, 50, "Should still have the right line number"); - todo_isnot(e.columnNumber, 0, - "No column number support for DOMException yet"); + is(e.columnNumber, 9, "Should have the right column number"); } try { @@ -78,13 +77,13 @@ ${asyncFrame}`, is(e.message, "We are a TypeError", "Should also have the right message (2)"); is(e.stack, - `doTest@${file}:72:9 + `doTest@${file}:71:9 ${asyncFrame}`, "Exception stack for TypeError should only show our code"); is(e.fileName, file, "Should still have the right file name for TypeError"); - is(e.lineNumber, 72, "Should still have the right line number for TypeError"); + is(e.lineNumber, 71, "Should still have the right line number for TypeError"); is(e.columnNumber, 9, "Should have the right column number for TypeError"); } @@ -98,14 +97,14 @@ ${asyncFrame}`, is(e.message, "missing argument 0 when calling function Array.prototype.forEach", "Should also have the right message (3)"); is(e.stack, - `doTest/<@${file}:92:61 -doTest@${file}:92:9 + `doTest/<@${file}:91:61 +doTest@${file}:91:9 ${asyncFrame}`, "Exception stack for TypeError should only show our code (3)"); is(e.fileName, file, "Should still have the right file name for TypeError (3)"); - is(e.lineNumber, 92, "Should still have the right line number for TypeError (3)"); + is(e.lineNumber, 91, "Should still have the right line number for TypeError (3)"); is(e.columnNumber, 61, "Should have the right column number for TypeError (3)"); } @@ -118,14 +117,14 @@ ${asyncFrame}`, is(e.name, "NS_ERROR_UNEXPECTED", "Name should be sanitized (4)"); is(e.message, "", "Message should be sanitized (5)"); is(e.stack, - `doTest@${file}:113:9 + `doTest@${file}:112:9 ${asyncFrame}`, "Exception stack for sanitized exception should only show our code (4)"); is(e.filename, file, "Should still have the right file name for sanitized exception (4)"); - is(e.lineNumber, 113, "Should still have the right line number for sanitized exception (4)"); - todo_isnot(e.columnNumber, 0, "Should have the right column number for sanitized exception (4)"); + is(e.lineNumber, 112, "Should still have the right line number for sanitized exception (4)"); + is(e.columnNumber, 9, "Should have the right column number for sanitized exception (4)"); } try { @@ -137,14 +136,14 @@ ${asyncFrame}`, is(e.name, "NS_ERROR_UNEXPECTED", "Name should be sanitized (5)"); is(e.message, "", "Message should be sanitized (5)"); is(e.stack, - `doTest@${file}:132:9 + `doTest@${file}:131:9 ${asyncFrame}`, "Exception stack for sanitized exception should only show our code (5)"); is(e.filename, file, "Should still have the right file name for sanitized exception (5)"); - is(e.lineNumber, 132, "Should still have the right line number for sanitized exception (5)"); - todo_isnot(e.columnNumber, 0, "Should have the right column number for sanitized exception (5)"); + is(e.lineNumber, 131, "Should still have the right line number for sanitized exception (5)"); + is(e.columnNumber, 9, "Should have the right column number for sanitized exception (5)"); } SimpleTest.finish(); diff --git a/js/xpconnect/src/ExecutionTracerIntegration.cpp b/js/xpconnect/src/ExecutionTracerIntegration.cpp @@ -168,7 +168,7 @@ bool ExecutionTracerIntegration::WriteExceptionSummary( uint32_t line = exception->LineNumber(aCx); aWriter->writeUint32(line); - uint32_t column = exception->ColumnNumber(); + uint32_t column = exception->ColumnNumber(aCx); aWriter->writeUint32(column); nsCOMPtr<nsIStackFrame> stack = exception->GetLocation(); diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp @@ -253,7 +253,7 @@ void xpc::ErrorReport::Init(JSContext* aCx, mozilla::dom::Exception* aException, } mSourceId = aException->SourceId(aCx); mLineNumber = aException->LineNumber(aCx); - mColumn = aException->ColumnNumber(); + mColumn = aException->ColumnNumber(aCx); } static LazyLogModule gJSDiagnostics("JSDiagnostics");