Skip to content

Commit

Permalink
fix: disable usage of JDK Unsafe class in GSON (#2341)
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Nov 13, 2024
1 parent 60dcdc7 commit 1e1036c
Show file tree
Hide file tree
Showing 20 changed files with 138 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import jadx.api.ICodeInfo;
import jadx.api.ICodeWriter;
Expand All @@ -32,13 +31,13 @@
import jadx.core.dex.nodes.FieldNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.RootNode;
import jadx.core.utils.GsonUtils;
import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.JadxRuntimeException;

public class JsonCodeGen {

private static final Gson GSON = new GsonBuilder()
.setPrettyPrinting()
private static final Gson GSON = GsonUtils.defaultGsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)
.disableHtmlEscaping()
.create();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import jadx.api.JadxArgs;
import jadx.core.codegen.json.mapping.JsonClsMapping;
Expand All @@ -24,14 +23,14 @@
import jadx.core.dex.nodes.FieldNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.RootNode;
import jadx.core.utils.GsonUtils;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.core.utils.files.FileUtils;

public class JsonMappingGen {
private static final Logger LOG = LoggerFactory.getLogger(JsonMappingGen.class);

private static final Gson GSON = new GsonBuilder()
.setPrettyPrinting()
private static final Gson GSON = GsonUtils.defaultGsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)
.disableHtmlEscaping()
.create();
Expand Down
21 changes: 20 additions & 1 deletion jadx-core/src/main/java/jadx/core/utils/GsonUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import java.lang.reflect.Type;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
Expand All @@ -11,11 +14,27 @@

public class GsonUtils {

public static Gson buildGson() {
return defaultGsonBuilder().create();
}

public static GsonBuilder defaultGsonBuilder() {
return new GsonBuilder()
.disableJdkUnsafe()
.setPrettyPrinting();
}

public static void fillObjectFromJsonString(GsonBuilder builder, Object obj, String jsonStr) {
Class<?> type = obj.getClass();
Gson gson = builder.registerTypeAdapter(type, (InstanceCreator<?>) t -> obj).create();
gson.fromJson(jsonStr, type);
}

public static <T> InterfaceReplace<T> interfaceReplace(Class<T> replaceCls) {
return new InterfaceReplace<>(replaceCls);
}

private static final class InterfaceReplace<T> implements JsonSerializer<T>, JsonDeserializer<T> {
public static final class InterfaceReplace<T> implements JsonSerializer<T>, JsonDeserializer<T> {
private final Class<T> replaceCls;

private InterfaceReplace(Class<T> replaceCls) {
Expand Down
4 changes: 1 addition & 3 deletions jadx-gui/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,8 @@ runtime {
"java.desktop",
"java.naming",
"java.xml",
// needed for "https" protocol to get plugins and updates
// needed for "https" protocol to download plugins and updates
"jdk.crypto.cryptoki",
// add Unsafe class, used by GSON
"jdk.unsupported",
)
jpackage {
imageOptions = listOf("--icon", "$projectDir/src/main/resources/logos/jadx-logo.ico")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

import jadx.api.plugins.utils.CommonFileUtils;
import jadx.core.utils.GsonUtils;
import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.core.utils.files.FileUtils;
Expand All @@ -34,7 +34,7 @@
public class CacheManager {
private static final Logger LOG = LoggerFactory.getLogger(CacheManager.class);

private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static final Gson GSON = GsonUtils.buildGson();
private static final Type CACHES_TYPE = new TypeToken<List<CacheEntry>>() {
}.getType();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

import jadx.core.dex.nodes.ClassNode;
import jadx.gui.device.debugger.smali.Smali;
import jadx.gui.treemodel.JClass;

import static jadx.core.utils.GsonUtils.buildGson;

public class BreakpointManager {
private static final Logger LOG = LoggerFactory.getLogger(BreakpointManager.class);

private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static final Gson GSON = buildGson();
private static final Type TYPE_TOKEN = new TypeToken<Map<String, List<FileBreakpoint>>>() {
}.getType();

Expand Down Expand Up @@ -159,9 +160,13 @@ public interface Listener {
}

protected static class FileBreakpoint {
final String cls;
final String mth;
final long codeOffset;
public String cls;
public String mth;
public long codeOffset;

public FileBreakpoint() {
// needed for JSON deserialization
}

private FileBreakpoint(String cls, String mth, long codeOffset) {
this.cls = cls;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import jadx.api.ICodeInfo;
import jadx.api.impl.SimpleCodeInfo;
import jadx.core.utils.GsonUtils;
import jadx.gui.treemodel.JClass;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.panel.ContentPanel;
Expand All @@ -30,8 +28,6 @@ public class QuarkReportNode extends JNode {

private static final Logger LOG = LoggerFactory.getLogger(QuarkReportNode.class);

private static final Gson GSON = new GsonBuilder().create();

private static final ImageIcon ICON = UiUtils.openSvgIcon("ui/quark");

private final Path reportFile;
Expand Down Expand Up @@ -62,7 +58,7 @@ public ContentPanel getContentPanel(TabbedPane tabbedPane) {
try {
QuarkReportData data;
try (BufferedReader reader = Files.newBufferedReader(reportFile)) {
data = GSON.fromJson(reader, QuarkReportData.class);
data = GsonUtils.buildGson().fromJson(reader, QuarkReportData.class);
}
data.validate();
return new QuarkReportPanel(tabbedPane, this, data);
Expand Down
16 changes: 8 additions & 8 deletions jadx-gui/src/main/java/jadx/gui/settings/JadxProject.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import jadx.api.JadxArgs;
import jadx.api.data.ICodeComment;
Expand All @@ -34,7 +33,6 @@
import jadx.api.data.impl.JadxCodeRename;
import jadx.api.data.impl.JadxNodeRef;
import jadx.api.plugins.utils.CommonFileUtils;
import jadx.core.utils.GsonUtils;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.core.utils.files.FileUtils;
import jadx.gui.cache.manager.CacheManager;
Expand All @@ -44,6 +42,9 @@
import jadx.gui.ui.codearea.EditorViewState;
import jadx.gui.utils.RelativePathTypeAdapter;

import static jadx.core.utils.GsonUtils.defaultGsonBuilder;
import static jadx.core.utils.GsonUtils.interfaceReplace;

public class JadxProject {
private static final Logger LOG = LoggerFactory.getLogger(JadxProject.class);

Expand Down Expand Up @@ -335,13 +336,12 @@ public static ProjectData loadProjectData(Path path) {
}

private static Gson buildGson(Path basePath) {
return new GsonBuilder()
return defaultGsonBuilder()
.registerTypeHierarchyAdapter(Path.class, new RelativePathTypeAdapter(basePath))
.registerTypeAdapter(ICodeComment.class, GsonUtils.interfaceReplace(JadxCodeComment.class))
.registerTypeAdapter(ICodeRename.class, GsonUtils.interfaceReplace(JadxCodeRename.class))
.registerTypeAdapter(IJavaNodeRef.class, GsonUtils.interfaceReplace(JadxNodeRef.class))
.registerTypeAdapter(IJavaCodeRef.class, GsonUtils.interfaceReplace(JadxCodeRef.class))
.setPrettyPrinting()
.registerTypeAdapter(ICodeComment.class, interfaceReplace(JadxCodeComment.class))
.registerTypeAdapter(ICodeRename.class, interfaceReplace(JadxCodeRename.class))
.registerTypeAdapter(IJavaNodeRef.class, interfaceReplace(JadxNodeRef.class))
.registerTypeAdapter(IJavaCodeRef.class, interfaceReplace(JadxCodeRef.class))
.create();
}

Expand Down
25 changes: 11 additions & 14 deletions jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;
import com.google.gson.JsonObject;

import jadx.core.utils.GsonUtils;
import jadx.gui.utils.PathTypeAdapter;
import jadx.gui.utils.RectangleTypeAdapter;

Expand All @@ -34,20 +34,16 @@ public boolean shouldSkipField(FieldAttributes f) {
|| f.hasModifier(Modifier.PUBLIC)
|| f.hasModifier(Modifier.TRANSIENT)
|| f.hasModifier(Modifier.STATIC)
|| (f.getAnnotation(GsonExclude.class) != null);
|| f.getAnnotation(GsonExclude.class) != null;
}

@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
};
private static final GsonBuilder GSON_BUILDER = new GsonBuilder()
.setExclusionStrategies(EXCLUDE_FIELDS)
.registerTypeHierarchyAdapter(Path.class, PathTypeAdapter.singleton())
.registerTypeHierarchyAdapter(Rectangle.class, RectangleTypeAdapter.singleton())
.setPrettyPrinting();
private static final Gson GSON = GSON_BUILDER.create();

private static final Gson GSON = makeGsonBuilder().create();

private JadxSettingsAdapter() {
}
Expand Down Expand Up @@ -92,17 +88,18 @@ public static JsonObject makeJsonObject(JadxSettings settings) {
}

public static void fill(JadxSettings settings, String jsonStr) {
populate(GSON_BUILDER, jsonStr, JadxSettings.class, settings);
GsonUtils.fillObjectFromJsonString(makeGsonBuilder(), settings, jsonStr);
}

private static <T> void populate(GsonBuilder builder, String json, Class<T> type, final T into) {
builder.registerTypeAdapter(type, (InstanceCreator<T>) t -> into)
.create()
.fromJson(json, type);
private static GsonBuilder makeGsonBuilder() {
return GsonUtils.defaultGsonBuilder()
.setExclusionStrategies(EXCLUDE_FIELDS)
.registerTypeHierarchyAdapter(Path.class, PathTypeAdapter.singleton())
.registerTypeHierarchyAdapter(Rectangle.class, RectangleTypeAdapter.singleton());
}

/**
* Annotation for specifying fields that should not be be saved/loaded
* Annotation for specifying fields that should not be saved/loaded
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;

import jadx.api.CommentsLevel;
Expand All @@ -57,6 +56,7 @@
import jadx.api.plugins.events.JadxEvents;
import jadx.api.plugins.events.types.ReloadSettingsWindow;
import jadx.api.plugins.gui.ISettingsGroup;
import jadx.core.utils.GsonUtils;
import jadx.gui.settings.JadxSettings;
import jadx.gui.settings.JadxSettingsAdapter;
import jadx.gui.settings.JadxUpdateChannel;
Expand Down Expand Up @@ -747,7 +747,7 @@ private void copySettings() {
settingsJson.remove("lastOpenFilePath");
settingsJson.remove("lastSaveFilePath");
settingsJson.remove("recentProjects");
String settingsText = new GsonBuilder().setPrettyPrinting().create().toJson(settingsJson);
String settingsText = GsonUtils.buildGson().toJson(settingsJson);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
StringSelection selection = new StringSelection(settingsText);
clipboard.setContents(selection, selection);
Expand Down
2 changes: 1 addition & 1 deletion jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ private void checkForUpdate() {
if (!settings.isCheckForUpdates()) {
return;
}
JadxUpdate.check(settings.getJadxUpdateChannel(), release -> SwingUtilities.invokeLater(() -> {
new JadxUpdate().check(settings.getJadxUpdateChannel(), release -> SwingUtilities.invokeLater(() -> {
switch (settings.getJadxUpdateChannel()) {
case STABLE:
updateLink.setUrl(JadxUpdate.JADX_RELEASES_URL);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package jadx.gui.ui.codearea;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

import jadx.core.utils.GsonUtils;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.action.ActionModel;

public class JsonPrettifyAction extends JNodeAction {

private static final long serialVersionUID = -2682529369671695550L;
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();

private static final Gson GSON = GsonUtils.buildGson();

public JsonPrettifyAction(CodeArea codeArea) {
super(ActionModel.JSON_PRETTIFY, codeArea);
Expand Down
Loading

0 comments on commit 1e1036c

Please sign in to comment.