Skip to content

Commit 15d11a2

Browse files
authored
StackTraceDeobfuscator should never provide null methodName (#9997)
Improves accuracy of deobfuscated stack traces by using the best answer between original JS names, symbol maps, and source maps, by both avoiding taking an identifier from the sourcemap if none is provided, and normalizing away chromium specific prefixes in stack trace elements. Fixes #9996 Follow-up #9936
1 parent be05c1e commit 15d11a2

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

user/src/com/google/gwt/core/server/StackTraceDeobfuscator.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.io.InputStream;
2727
import java.io.InputStreamReader;
2828
import java.net.URL;
29+
import java.util.Collections;
2930
import java.util.HashMap;
3031
import java.util.HashSet;
3132
import java.util.Map;
@@ -186,9 +187,9 @@ public final StackTraceElement[] resymbolize(StackTraceElement[] st, String stro
186187
return null;
187188
}
188189
// Warm the symbol cache for all symbols in this stack trace.
189-
Set<String> requiredSymbols = new HashSet<String>();
190+
Set<String> requiredSymbols = new HashSet<>();
190191
for (StackTraceElement ste : st) {
191-
requiredSymbols.add(ste.getMethodName());
192+
requiredSymbols.add(normalizeSymbol(ste.getMethodName()));
192193
}
193194
loadSymbolMap(strongName, requiredSymbols);
194195

@@ -199,6 +200,17 @@ public final StackTraceElement[] resymbolize(StackTraceElement[] st, String stro
199200
return newSt;
200201
}
201202

203+
/**
204+
* Helper to clean up client-provided symbols.
205+
*/
206+
private static String normalizeSymbol(String symbol) {
207+
// Chrome prefixes "new " for constructor calls, eliminate the prefix
208+
if (symbol.startsWith("new ")) {
209+
symbol = symbol.substring(4);
210+
}
211+
return symbol;
212+
}
213+
202214
/**
203215
* Best effort resymbolization of a single stack trace element.
204216
*
@@ -305,7 +317,13 @@ public final StackTraceElement resymbolize(StackTraceElement ste, String strongN
305317

306318
if (declaringClass == null || declaringClass.equals(ste.getClassName())) {
307319
declaringClass = mappingForLine.getOriginalFile();
308-
methodName = mappingForLine.getIdentifier().orElse(null);
320+
if (mappingForLine.getIdentifier().isPresent()) {
321+
// Only overwrite the name if the sourcemap had an explicit identifier
322+
methodName = mappingForLine.getIdentifier().get();
323+
} else if (methodName == null) {
324+
// No other name was provided by symbolMaps, fall back to JS name
325+
methodName = ste.getMethodName();
326+
}
309327
}
310328
fileName = mappingForLine.getOriginalFile();
311329
lineNumber = mappingForLine.getLineNumber();
@@ -366,9 +384,8 @@ private String loadStreamAsString(InputStream stream) {
366384
}
367385

368386
private String loadOneSymbol(String strongName, String symbol) {
369-
Set<String> symbolSet = new HashSet<String>();
370-
symbolSet.add(symbol);
371-
Map<String, String> symbolMap = loadSymbolMap(strongName, symbolSet);
387+
symbol = normalizeSymbol(symbol);
388+
Map<String, String> symbolMap = loadSymbolMap(strongName, Collections.singleton(symbol));
372389
return symbolMap.get(symbol);
373390
}
374391

0 commit comments

Comments
 (0)