From 3f6dbb7e8e3efa776f65ba0d2478be21e5ce7625 Mon Sep 17 00:00:00 2001 From: bibi samina Date: Thu, 16 Jul 2026 14:37:42 +0530 Subject: [PATCH 1/3] fix fragment id capture from stack frame file name --- .../core/server/StackTraceDeobfuscator.java | 2 +- .../server/StackTraceDeobfuscatorTest.java | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/user/src/com/google/gwt/core/server/StackTraceDeobfuscator.java b/user/src/com/google/gwt/core/server/StackTraceDeobfuscator.java index b2ba404fd0..197467bc61 100644 --- a/user/src/com/google/gwt/core/server/StackTraceDeobfuscator.java +++ b/user/src/com/google/gwt/core/server/StackTraceDeobfuscator.java @@ -147,7 +147,7 @@ Map getAll(String strongName, Set symbols) { } private static final Pattern JsniRefPattern = Pattern.compile("@?([^:]+)::([^(]+)(\\((.*)\\))?"); - private static final Pattern fragmentIdPattern = Pattern.compile(".*(\\d+)\\.js"); + private static final Pattern fragmentIdPattern = Pattern.compile("(?:.*[^\\d])?(\\d+)\\.js"); // Matches ServerSerializationStreamReader: the strong name reaches us straight from the // client (X-GWT-Permutation header) and is concatenated into symbol/source map file names. private static final Pattern strongNamePattern = Pattern.compile("[a-zA-Z0-9_]+"); diff --git a/user/test/com/google/gwt/core/server/StackTraceDeobfuscatorTest.java b/user/test/com/google/gwt/core/server/StackTraceDeobfuscatorTest.java index b82490fc19..691dc8aff1 100644 --- a/user/test/com/google/gwt/core/server/StackTraceDeobfuscatorTest.java +++ b/user/test/com/google/gwt/core/server/StackTraceDeobfuscatorTest.java @@ -41,6 +41,18 @@ private static StackTraceElement[] trace() { return new StackTraceElement[] {new StackTraceElement("C", "m", "C.java", 1)}; } + /** + * Builds a frame as the browser reports it for a fragment, whose file name comes from the + * "//# sourceURL=<module>-<fragment>.js" comment written by CrossSiteIframeLinker. + * The column marker makes the frame source map capable, and an unknown method symbol leaves + * the fragment id to be recovered from the file name. + */ + private static StackTraceElement[] traceInFragmentFile(String fileName) { + return new StackTraceElement[] {new StackTraceElement("C", "unknown", fileName + "@1", 1)}; + } + + private static final String STRONG_NAME = "0F2C4A6E8B1D3F5709ABCDEF12345678"; + public void testTraversalStrongNameIsNotUsedToBuildPath() { RecordingDeobfuscator d = new RecordingDeobfuscator(); d.resymbolize(trace(), "../../../../../../etc/passwd"); @@ -53,4 +65,25 @@ public void testValidStrongNameStillLoadsSymbolMap() { d.resymbolize(trace(), "0F2C4A6E8B1D3F5709ABCDEF12345678"); assertEquals("0F2C4A6E8B1D3F5709ABCDEF12345678.symbolMap", d.opened.get(0)); } + + public void testSingleDigitFragmentIdIsReadFromFileName() { + RecordingDeobfuscator d = new RecordingDeobfuscator(); + d.resymbolize(traceInFragmentFile("app-5.js"), STRONG_NAME); + assertTrue("expected fragment 5 to be requested: " + d.opened, + d.opened.contains(STRONG_NAME + "_sourceMap5.json")); + } + + public void testMultiDigitFragmentIdIsReadFromFileName() { + RecordingDeobfuscator d = new RecordingDeobfuscator(); + d.resymbolize(traceInFragmentFile("app-12.js"), STRONG_NAME); + assertTrue("expected fragment 12, not its last digit: " + d.opened, + d.opened.contains(STRONG_NAME + "_sourceMap12.json")); + } + + public void testMultiDigitFragmentIdIsReadFromModuleNameEndingInDigit() { + RecordingDeobfuscator d = new RecordingDeobfuscator(); + d.resymbolize(traceInFragmentFile("app2-104.js"), STRONG_NAME); + assertTrue("expected fragment 104, not its last digit: " + d.opened, + d.opened.contains(STRONG_NAME + "_sourceMap104.json")); + } } From dd6f1e8831f81445293b4add0e423fe25afa4cb4 Mon Sep 17 00:00:00 2001 From: bibi samina Date: Fri, 17 Jul 2026 10:46:14 +0530 Subject: [PATCH 2/3] Use \D in fragment id pattern --- user/src/com/google/gwt/core/server/StackTraceDeobfuscator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user/src/com/google/gwt/core/server/StackTraceDeobfuscator.java b/user/src/com/google/gwt/core/server/StackTraceDeobfuscator.java index 197467bc61..2f412f2bf3 100644 --- a/user/src/com/google/gwt/core/server/StackTraceDeobfuscator.java +++ b/user/src/com/google/gwt/core/server/StackTraceDeobfuscator.java @@ -147,7 +147,7 @@ Map getAll(String strongName, Set symbols) { } private static final Pattern JsniRefPattern = Pattern.compile("@?([^:]+)::([^(]+)(\\((.*)\\))?"); - private static final Pattern fragmentIdPattern = Pattern.compile("(?:.*[^\\d])?(\\d+)\\.js"); + private static final Pattern fragmentIdPattern = Pattern.compile("(?:.*\\D)?(\\d+)\\.js"); // Matches ServerSerializationStreamReader: the strong name reaches us straight from the // client (X-GWT-Permutation header) and is concatenated into symbol/source map file names. private static final Pattern strongNamePattern = Pattern.compile("[a-zA-Z0-9_]+"); From a1b821e021b9dd8c5911846247a713d0fa1b86e8 Mon Sep 17 00:00:00 2001 From: bibi samina Date: Fri, 17 Jul 2026 16:15:22 +0530 Subject: [PATCH 3/3] Use neutral assertion messages in fragment id tests --- .../google/gwt/core/server/StackTraceDeobfuscatorTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user/test/com/google/gwt/core/server/StackTraceDeobfuscatorTest.java b/user/test/com/google/gwt/core/server/StackTraceDeobfuscatorTest.java index 691dc8aff1..c8e221404f 100644 --- a/user/test/com/google/gwt/core/server/StackTraceDeobfuscatorTest.java +++ b/user/test/com/google/gwt/core/server/StackTraceDeobfuscatorTest.java @@ -76,14 +76,14 @@ public void testSingleDigitFragmentIdIsReadFromFileName() { public void testMultiDigitFragmentIdIsReadFromFileName() { RecordingDeobfuscator d = new RecordingDeobfuscator(); d.resymbolize(traceInFragmentFile("app-12.js"), STRONG_NAME); - assertTrue("expected fragment 12, not its last digit: " + d.opened, + assertTrue("expected fragment 12 to be requested: " + d.opened, d.opened.contains(STRONG_NAME + "_sourceMap12.json")); } public void testMultiDigitFragmentIdIsReadFromModuleNameEndingInDigit() { RecordingDeobfuscator d = new RecordingDeobfuscator(); d.resymbolize(traceInFragmentFile("app2-104.js"), STRONG_NAME); - assertTrue("expected fragment 104, not its last digit: " + d.opened, + assertTrue("expected fragment 104 to be requested: " + d.opened, d.opened.contains(STRONG_NAME + "_sourceMap104.json")); } }