From df5242a5f129814506bec9169d19d9af05d218d3 Mon Sep 17 00:00:00 2001 From: Googler Date: Wed, 4 Dec 2024 15:25:29 -0800 Subject: [PATCH] Include JS class names in the auto-generated transpiled Java class names to make deobfuscation of `class.getName()` output possible. Most classes will have unique names, as for the most part Closure Compiler will assign them to variables or global-shared-object properties sharing a common namespace. In case there is ambiguity, a unique ID is still added as a suffix after the JS class name. PiperOrigin-RevId: 702881060 --- .../nativebootstrap/Util.impl.java.js | 22 ++++++++++++++----- ...tlinThrowsInJsFunction.stacktrace_j2cl.txt | 2 +- ...sInJsFunction.stacktrace_j2cl_compiled.txt | 2 +- .../ThrowsInJsFunction.stacktrace_j2cl.txt | 2 +- ...sInJsFunction.stacktrace_j2cl_compiled.txt | 2 +- .../java/classliteralstripped/Main.java | 5 ++++- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/jre/java/javaemul/internal/nativebootstrap/Util.impl.java.js b/jre/java/javaemul/internal/nativebootstrap/Util.impl.java.js index a41f6df195..f1a34096fa 100644 --- a/jre/java/javaemul/internal/nativebootstrap/Util.impl.java.js +++ b/jre/java/javaemul/internal/nativebootstrap/Util.impl.java.js @@ -160,9 +160,21 @@ class Util { */ static $getGeneratedClassName_(ctor) { const propName = '$$generatedClassName'; - return ctor.prototype.hasOwnProperty(propName) ? - ctor.prototype[propName] : - ctor.prototype[propName] = 'Class$obf_' + ++Util.$nextUniqId_; + if (ctor.prototype.hasOwnProperty(propName)) { + return ctor.prototype[propName]; + } + + // Use the constructor "name", which should be the result of the variable + // name JSCompiler assigned the class/function to. This allows for manual + // deobfuscation of the class name. + const constructorName = ctor.name; + const nextUniqId = Util.$nextUniqIdByName_.get(constructorName) ?? 0; + Util.$nextUniqIdByName_.set(constructorName, nextUniqId + 1); + const generatedClassName = + 'Class$obf_' + constructorName + '_' + nextUniqId; + + ctor.prototype[propName] = generatedClassName; + return generatedClassName; } /** @@ -289,9 +301,9 @@ class Util { /** - * @private {number} + * @private @const {!Map} */ -Util.$nextUniqId_ = 1000; +Util.$nextUniqIdByName_ = new Map(); /** * @type {number} diff --git a/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/KotlinThrowsInJsFunction.stacktrace_j2cl.txt b/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/KotlinThrowsInJsFunction.stacktrace_j2cl.txt index 168ffdb068..5326b6aeab 100644 --- a/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/KotlinThrowsInJsFunction.stacktrace_j2cl.txt +++ b/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/KotlinThrowsInJsFunction.stacktrace_j2cl.txt @@ -1,6 +1,6 @@ java.lang.RuntimeException: __the_message__! at com.google.j2cl.junit.integration.stacktrace.data.KotlinThrowsInJsFunction$MyFunctionImpl.run(KotlinThrowsInJsFunction.kt:50) - at lambda(jre/java/jre.js/javaemul/internal/nativebootstrap/Util.impl.java.js:196:31) + at lambda(jre/java/jre.js/javaemul/internal/nativebootstrap/Util.impl.java.js:208:31) at com.google.j2cl.junit.integration.stacktrace.data.KotlinThrowsInJsFunction.executesFunction(KotlinThrowsInJsFunction.kt:55) at com.google.j2cl.junit.integration.stacktrace.data.KotlinThrowsInJsFunction$1.run(KotlinThrowsInJsFunction.kt:41) at com.google.j2cl.junit.integration.stacktrace.data.KotlinThrowsInJsFunction.executesFunction(KotlinThrowsInJsFunction.kt:55) diff --git a/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/KotlinThrowsInJsFunction.stacktrace_j2cl_compiled.txt b/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/KotlinThrowsInJsFunction.stacktrace_j2cl_compiled.txt index 4e9afaa68d..afab079c82 100644 --- a/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/KotlinThrowsInJsFunction.stacktrace_j2cl_compiled.txt +++ b/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/KotlinThrowsInJsFunction.stacktrace_j2cl_compiled.txt @@ -1,6 +1,6 @@ java.lang.RuntimeException: __the_message__! at com.google.j2cl.junit.integration.stacktrace.data.KotlinThrowsInJsFunction$MyFunctionImpl.run(KotlinThrowsInJsFunction.kt:50) - at apply(/jre/java/jre.js/javaemul/internal/nativebootstrap/Util.impl.java.js:196:31) + at apply(/jre/java/jre.js/javaemul/internal/nativebootstrap/Util.impl.java.js:208:31) at com.google.j2cl.junit.integration.stacktrace.data.KotlinThrowsInJsFunction.executesFunction(KotlinThrowsInJsFunction.kt:55) at com.google.j2cl.junit.integration.stacktrace.data.KotlinThrowsInJsFunction$1.run(KotlinThrowsInJsFunction.kt:41) at com.google.j2cl.junit.integration.stacktrace.data.KotlinThrowsInJsFunction.executesFunction(KotlinThrowsInJsFunction.kt:55) diff --git a/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/ThrowsInJsFunction.stacktrace_j2cl.txt b/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/ThrowsInJsFunction.stacktrace_j2cl.txt index c66ae3d6fa..36d9a3f882 100644 --- a/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/ThrowsInJsFunction.stacktrace_j2cl.txt +++ b/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/ThrowsInJsFunction.stacktrace_j2cl.txt @@ -1,6 +1,6 @@ java.lang.RuntimeException: __the_message__! at com.google.j2cl.junit.integration.stacktrace.data.ThrowsInJsFunction$MyFunctionImpl.run(ThrowsInJsFunction.java:55) - at lambda(jre/java/jre.js/javaemul/internal/nativebootstrap/Util.impl.java.js:196:31) + at lambda(jre/java/jre.js/javaemul/internal/nativebootstrap/Util.impl.java.js:208:31) at com.google.j2cl.junit.integration.stacktrace.data.ThrowsInJsFunction.executesFunction(ThrowsInJsFunction.java:60) at com.google.j2cl.junit.integration.stacktrace.data.ThrowsInJsFunction$1.run(ThrowsInJsFunction.java:46) at com.google.j2cl.junit.integration.stacktrace.data.ThrowsInJsFunction.executesFunction(ThrowsInJsFunction.java:60) diff --git a/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/ThrowsInJsFunction.stacktrace_j2cl_compiled.txt b/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/ThrowsInJsFunction.stacktrace_j2cl_compiled.txt index 24dc4bc5f0..b5d14aab50 100644 --- a/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/ThrowsInJsFunction.stacktrace_j2cl_compiled.txt +++ b/junit/generator/javatests/com/google/j2cl/junit/integration/stacktrace/data/ThrowsInJsFunction.stacktrace_j2cl_compiled.txt @@ -1,6 +1,6 @@ java.lang.RuntimeException: __the_message__! at com.google.j2cl.junit.integration.stacktrace.data.ThrowsInJsFunction$MyFunctionImpl.run(ThrowsInJsFunction.java:55) - at apply(/jre/java/jre.js/javaemul/internal/nativebootstrap/Util.impl.java.js:196:31) + at apply(/jre/java/jre.js/javaemul/internal/nativebootstrap/Util.impl.java.js:208:31) at com.google.j2cl.junit.integration.stacktrace.data.ThrowsInJsFunction.executesFunction(ThrowsInJsFunction.java:60) at com.google.j2cl.junit.integration.stacktrace.data.ThrowsInJsFunction$1.run(ThrowsInJsFunction.java:46) at com.google.j2cl.junit.integration.stacktrace.data.ThrowsInJsFunction.executesFunction(ThrowsInJsFunction.java:60) diff --git a/transpiler/javatests/com/google/j2cl/integration/java/classliteralstripped/Main.java b/transpiler/javatests/com/google/j2cl/integration/java/classliteralstripped/Main.java index 230ef9e9f1..cea26b5caf 100644 --- a/transpiler/javatests/com/google/j2cl/integration/java/classliteralstripped/Main.java +++ b/transpiler/javatests/com/google/j2cl/integration/java/classliteralstripped/Main.java @@ -150,7 +150,10 @@ private static void testNative() { } private static void assertClassName(String name, String canonicalName, String simpleName) { - assertTrue("Name should have the pattern XXX_Class$obf_1XXX", name.contains("Class$obf_10")); + assertTrue( + "Name should have the pattern Class$obf_XXX_# or Class$obf_####, but did not match: " + + name, + name.matches("^Class\\$obf_(.*_\\d+|[1-9]\\d{3,})$")); assertTrue(name.endsWith(simpleName)); assertEquals(name, canonicalName); }