diff --git a/jadx-gui/src/main/java/jadx/gui/JadxWrapper.java b/jadx-gui/src/main/java/jadx/gui/JadxWrapper.java index f11a0bcf1..cec9b4fb9 100644 --- a/jadx-gui/src/main/java/jadx/gui/JadxWrapper.java +++ b/jadx-gui/src/main/java/jadx/gui/JadxWrapper.java @@ -67,7 +67,6 @@ public class JadxWrapper { /** * Get the complete list of classes - * @return */ public List getClasses() { return decompiler.getClasses(); @@ -75,19 +74,20 @@ public class JadxWrapper { /** * Get all classes that are not excluded by the excluded packages settings - * @return */ public List getIncludedClasses() { List classList = decompiler.getClasses(); String excludedPackages = settings.getExcludedPackages().trim(); - if (excludedPackages.length() == 0) + if (excludedPackages.length() == 0) { return classList; + } String[] excluded = excludedPackages.split("[ ]+"); return classList.stream().filter(cls -> { for (String exclude : excluded) { - if (cls.getFullName().startsWith(exclude)) + if (cls.getFullName().startsWith(exclude)) { return false; + } } return true; }).collect(Collectors.toList()); diff --git a/jadx-gui/src/main/java/jadx/gui/jobs/BackgroundWorker.java b/jadx-gui/src/main/java/jadx/gui/jobs/BackgroundWorker.java index 59ad04e39..8d666e5e1 100644 --- a/jadx-gui/src/main/java/jadx/gui/jobs/BackgroundWorker.java +++ b/jadx-gui/src/main/java/jadx/gui/jobs/BackgroundWorker.java @@ -3,12 +3,12 @@ package jadx.gui.jobs; import javax.swing.*; import java.util.concurrent.Future; -import jadx.gui.utils.NLS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import jadx.gui.ui.ProgressPanel; import jadx.gui.utils.CacheObject; +import jadx.gui.utils.NLS; import jadx.gui.utils.Utils; import jadx.gui.utils.search.TextSearchIndex; @@ -27,12 +27,7 @@ public class BackgroundWorker extends SwingWorker { if (isDone()) { return; } - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - progressPane.setVisible(true); - } - }); + SwingUtilities.invokeLater(() -> progressPane.setVisible(true)); addPropertyChangeListener(progressPane); execute(); } @@ -46,7 +41,7 @@ public class BackgroundWorker extends SwingWorker { } @Override - protected Void doInBackground() throws Exception { + protected Void doInBackground() { try { System.gc(); LOG.debug("Memory usage: Before decompile: {}", Utils.memoryInfo()); diff --git a/jadx-gui/src/main/java/jadx/gui/jobs/DecompileJob.java b/jadx-gui/src/main/java/jadx/gui/jobs/DecompileJob.java index 983165067..65675072c 100644 --- a/jadx-gui/src/main/java/jadx/gui/jobs/DecompileJob.java +++ b/jadx-gui/src/main/java/jadx/gui/jobs/DecompileJob.java @@ -11,12 +11,7 @@ public class DecompileJob extends BackgroundJob { protected void runJob() { for (final JavaClass cls : wrapper.getIncludedClasses()) { - addTask(new Runnable() { - @Override - public void run() { - cls.decompile(); - } - }); + addTask(cls::decompile); } } diff --git a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java index c88a6ba3e..4c134d0bc 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java @@ -150,7 +150,6 @@ public class JadxSettings extends JadxCLIArgs { return true; } - public boolean isShowHeapUsageBar() { return showHeapUsageBar; } diff --git a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsAdapter.java b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsAdapter.java index 66a7a09e5..30f3c44ca 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsAdapter.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsAdapter.java @@ -21,7 +21,7 @@ public class JadxSettingsAdapter { private static final Preferences PREFS = Preferences.userNodeForPackage(JadxGUI.class); - private static ExclusionStrategy EXCLUDE_FIELDS = new ExclusionStrategy() { + private static final ExclusionStrategy EXCLUDE_FIELDS = new ExclusionStrategy() { @Override public boolean shouldSkipField(FieldAttributes f) { return JadxSettings.SKIP_FIELDS.contains(f.getName()) diff --git a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java index e61027f74..927d99916 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java @@ -1,8 +1,6 @@ package jadx.gui.settings; import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.MouseAdapter; @@ -245,11 +243,11 @@ public class JadxSettingsWindow extends JDialog { }); JButton editExcludedPackages = new JButton(NLS.str("preferences.excludedPackages.button")); - editExcludedPackages.addActionListener( event -> { + editExcludedPackages.addActionListener(event -> { String result = JOptionPane.showInputDialog(this, NLS.str("preferences.excludedPackages.editDialog"), settings.getExcludedPackages()); - if (result !=null) { + if (result != null) { settings.setExcludedPackages(result); } }); diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/ApkSignature.java b/jadx-gui/src/main/java/jadx/gui/treemodel/ApkSignature.java index d59136bd7..9e9f3f266 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/ApkSignature.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/ApkSignature.java @@ -1,34 +1,36 @@ package jadx.gui.treemodel; -import com.android.apksig.ApkVerifier; -import jadx.api.ResourceType; -import jadx.gui.JadxWrapper; -import jadx.gui.utils.CertificateManager; -import jadx.gui.utils.NLS; -import jadx.gui.utils.Utils; -import org.apache.commons.lang3.exception.ExceptionUtils; -import org.apache.commons.text.StringEscapeUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import javax.swing.*; import java.io.File; import java.security.cert.Certificate; import java.util.List; import java.util.stream.Collectors; -public class ApkSignature extends JNode { +import com.android.apksig.ApkVerifier; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.commons.text.StringEscapeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jadx.gui.JadxWrapper; +import jadx.gui.utils.CertificateManager; +import jadx.gui.utils.NLS; +import jadx.gui.utils.Utils; + +public class ApkSignature extends JNode { + private static final long serialVersionUID = -9121321926113143407L; + + private static final Logger LOG = LoggerFactory.getLogger(ApkSignature.class); - private static final Logger log = LoggerFactory.getLogger(ApkSignature.class); private static final ImageIcon CERTIFICATE_ICON = Utils.openIcon("certificate_obj"); private final transient File openFile; - private String content = null; + private String content; public static ApkSignature getApkSignature(JadxWrapper wrapper) { // Only show the ApkSignature node if an AndroidManifest.xml is present. // Without a manifest the Google ApkVerifier refuses to work. - if (!wrapper.getResources().stream().anyMatch(r -> "AndroidManifest.xml".equals(r.getName()))) { + if (wrapper.getResources().stream().noneMatch(r -> "AndroidManifest.xml".equals(r.getName()))) { return null; } File openFile = wrapper.getOpenFile(); @@ -56,8 +58,9 @@ public class ApkSignature extends JNode { @Override public String getContent() { - if (content != null) + if (content != null) { return this.content; + } ApkVerifier verifier = new ApkVerifier.Builder(openFile).build(); try { ApkVerifier.Result result = verifier.verify(); @@ -80,7 +83,7 @@ public class ApkSignature extends JNode { writeIssues(builder, err, result.getErrors()); writeIssues(builder, warn, result.getWarnings()); - if (result.getV1SchemeSigners().size() > 0) { + if (!result.getV1SchemeSigners().isEmpty()) { builder.append("

"); builder.escape(String.format(result.isVerifiedUsingV1Scheme() ? sigSucc : sigFail, 1)); builder.append("

\n"); @@ -101,7 +104,7 @@ public class ApkSignature extends JNode { } builder.append(""); } - if (result.getV2SchemeSigners().size() > 0) { + if (!result.getV2SchemeSigners().isEmpty()) { builder.append("

"); builder.escape(String.format(result.isVerifiedUsingV2Scheme() ? sigSucc : sigFail, 2)); builder.append("

\n"); @@ -121,7 +124,7 @@ public class ApkSignature extends JNode { } this.content = builder.toString(); } catch (Exception e) { - log.error(e.getMessage(), e); + LOG.error(e.getMessage(), e); StringEscapeUtils.Builder builder = StringEscapeUtils.builder(StringEscapeUtils.ESCAPE_HTML4); builder.append("

"); builder.escape(NLS.str("apkSignature.exception")); @@ -147,7 +150,7 @@ public class ApkSignature extends JNode { } private void writeIssues(StringEscapeUtils.Builder builder, String issueType, List issueList) { - if (issueList.size() > 0) { + if (!issueList.isEmpty()) { builder.append("

"); builder.escape(issueType); builder.append("

"); @@ -155,7 +158,7 @@ public class ApkSignature extends JNode { // Unprotected Zip entry issues are very common, handle them separately List unprotIssues = issueList.stream().filter(i -> i.getIssue() == ApkVerifier.Issue.JAR_SIG_UNPROTECTED_ZIP_ENTRY).collect(Collectors.toList()); - if (unprotIssues.size() > 0) { + if (!unprotIssues.isEmpty()) { builder.append("

"); builder.escape(NLS.str("apkSignature.unprotectedEntry")); builder.append("

"); @@ -167,7 +170,7 @@ public class ApkSignature extends JNode { } List remainingIssues = issueList.stream().filter(i -> i.getIssue() != ApkVerifier.Issue.JAR_SIG_UNPROTECTED_ZIP_ENTRY).collect(Collectors.toList()); - if (remainingIssues.size() > 0) { + if (!remainingIssues.isEmpty()) { builder.append("
\n");
 				for (ApkVerifier.IssueWithParams issue : remainingIssues) {
 					builder.escape(issue.toString());
@@ -177,8 +180,5 @@ public class ApkSignature extends JNode {
 			}
 			builder.append("
"); } - } - - } diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JSources.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JSources.java index a0208e1ac..d6541fb8c 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JSources.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JSources.java @@ -85,7 +85,7 @@ public class JSources extends JNode { } } // use identity set for collect inner packages - Set innerPackages = Collections.newSetFromMap(new IdentityHashMap()); + Set innerPackages = Collections.newSetFromMap(new IdentityHashMap<>()); for (JPackage pkg : pkgMap.values()) { innerPackages.addAll(pkg.getInnerPackages()); } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/AboutDialog.java b/jadx-gui/src/main/java/jadx/gui/ui/AboutDialog.java index 33c9252d6..9be61b539 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/AboutDialog.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/AboutDialog.java @@ -2,8 +2,6 @@ package jadx.gui.ui; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import jadx.api.JadxDecompiler; import jadx.gui.utils.NLS; @@ -42,11 +40,7 @@ class AboutDialog extends JDialog { textPane.add(Box.createRigidArea(new Dimension(0, 20))); JButton close = new JButton(NLS.str("tabs.close")); - close.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent event) { - dispose(); - } - }); + close.addActionListener(event -> dispose()); close.setAlignmentX(0.5f); Container contentPane = getContentPane(); diff --git a/jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java b/jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java index 597239bc0..4f5b73088 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java @@ -33,14 +33,14 @@ import jadx.gui.jobs.DecompileJob; import jadx.gui.treemodel.JNode; import jadx.gui.ui.codearea.CodeArea; import jadx.gui.utils.CacheObject; -import jadx.gui.utils.NLS; import jadx.gui.utils.JumpPosition; +import jadx.gui.utils.NLS; import jadx.gui.utils.search.TextSearchIndex; public abstract class CommonSearchDialog extends JDialog { + private static final long serialVersionUID = 8939332306115370276L; private static final Logger LOG = LoggerFactory.getLogger(CommonSearchDialog.class); - private static final long serialVersionUID = 8939332306115370276L; public static final int RESULTS_PER_PAGE = 100; @@ -399,7 +399,7 @@ public abstract class CommonSearchDialog extends JDialog { private final JLabel emptyLabel = new JLabel(); private final Color codeSelectedColor; private final Color codeBackground; - private Map componentCache = new HashMap<>(); + private final Map componentCache = new HashMap<>(); public ResultsTableCellRenderer() { RSyntaxTextArea area = CodeArea.getDefaultArea(mainWindow); diff --git a/jadx-gui/src/main/java/jadx/gui/ui/HeapUsageBar.java b/jadx-gui/src/main/java/jadx/gui/ui/HeapUsageBar.java index 680d1c2f9..2881833b1 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/HeapUsageBar.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/HeapUsageBar.java @@ -1,38 +1,33 @@ package jadx.gui.ui; -import jadx.gui.utils.NLS; -import jadx.gui.utils.Utils; - import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import jadx.gui.utils.NLS; +import jadx.gui.utils.Utils; + public class HeapUsageBar extends JProgressBar implements ActionListener { + private static final long serialVersionUID = -8739563124249884967L; - private static final double TWO_TO_20 = 1048576d; // 1024 * 1024 + private static final double TWO_TO_20 = 1048576d; - private final Color GREEN = new Color(0, 180, 0); - private final Color RED = new Color(200, 0, 0); + private static final Color GREEN = new Color(0, 180, 0); + private static final Color RED = new Color(200, 0, 0); - private final Runtime r; - - private String maxHeapStr; - - private final Timer timer; - - private final double maxGB; + private final transient Runtime runtime = Runtime.getRuntime(); + private final transient Timer timer; private final String textFormat; + private final double maxGB; public HeapUsageBar() { - super(); - textFormat = NLS.str("heapUsage.text"); - r = Runtime.getRuntime(); + this.textFormat = NLS.str("heapUsage.text"); setBorderPainted(false); setStringPainted(true); setValue(10); - int maxKB = (int) (r.maxMemory() / 1024); + int maxKB = (int) (runtime.maxMemory() / 1024); setMaximum(maxKB); maxGB = maxKB / TWO_TO_20; update(); @@ -40,12 +35,12 @@ public class HeapUsageBar extends JProgressBar implements ActionListener { } public void update() { - long used = r.totalMemory() - r.freeMemory(); + long used = runtime.totalMemory() - runtime.freeMemory(); int usedKB = (int) (used / 1024); setValue(usedKB); setString(String.format(textFormat, (usedKB / TWO_TO_20), maxGB)); - if ((used + Utils.MIN_FREE_MEMORY) > r.maxMemory()) { + if ((used + Utils.MIN_FREE_MEMORY) > runtime.maxMemory()) { setForeground(RED); } else { setForeground(GREEN); diff --git a/jadx-gui/src/main/java/jadx/gui/ui/HtmlPanel.java b/jadx-gui/src/main/java/jadx/gui/ui/HtmlPanel.java index 8a93034f7..52af564cd 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/HtmlPanel.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/HtmlPanel.java @@ -1,17 +1,10 @@ package jadx.gui.ui; +import javax.swing.*; +import java.awt.*; + import jadx.gui.settings.JadxSettings; import jadx.gui.treemodel.JNode; -import jadx.gui.ui.codearea.CodeArea; -import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; - -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.plaf.PanelUI; -import java.awt.*; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; public final class HtmlPanel extends ContentPanel { private static final long serialVersionUID = -6251262855835426245L; @@ -36,14 +29,14 @@ public final class HtmlPanel extends ContentPanel { textArea.setFont(settings.getFont()); } - private static class JHtmlPane extends JEditorPane { - - boolean antiAliasingEnabled; + private static final class JHtmlPane extends JEditorPane { + private static final long serialVersionUID = 6886040384052136157L; public JHtmlPane() { setContentType("text/html"); } + @Override public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g.create(); try { @@ -53,6 +46,5 @@ public final class HtmlPanel extends ContentPanel { g2d.dispose(); } } - } } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/MainDropTarget.java b/jadx-gui/src/main/java/jadx/gui/ui/MainDropTarget.java index 604b2615f..c635cbfd4 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/MainDropTarget.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/MainDropTarget.java @@ -59,7 +59,7 @@ public class MainDropTarget implements DropTargetListener { try { Transferable transferable = dtde.getTransferable(); List transferData = (List) transferable.getTransferData(DataFlavor.javaFileListFlavor); - if (transferData != null && transferData.size() > 0) { + if (!transferData.isEmpty()) { dtde.dropComplete(true); // load first file mainWindow.openFile(transferData.get(0)); diff --git a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java index e6280950b..e39470ea7 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java @@ -9,7 +9,6 @@ import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.ExpandVetoException; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; @@ -28,7 +27,6 @@ import java.util.Arrays; import java.util.Timer; import java.util.TimerTask; -import jadx.gui.treemodel.*; import org.fife.ui.rsyntaxtextarea.Theme; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,13 +38,20 @@ import jadx.gui.jobs.DecompileJob; import jadx.gui.jobs.IndexJob; import jadx.gui.settings.JadxSettings; import jadx.gui.settings.JadxSettingsWindow; +import jadx.gui.treemodel.ApkSignature; +import jadx.gui.treemodel.JCertificate; +import jadx.gui.treemodel.JClass; +import jadx.gui.treemodel.JLoadableNode; +import jadx.gui.treemodel.JNode; +import jadx.gui.treemodel.JResource; +import jadx.gui.treemodel.JRoot; import jadx.gui.update.JadxUpdate; import jadx.gui.update.JadxUpdate.IUpdateCallback; import jadx.gui.update.data.Release; import jadx.gui.utils.CacheObject; +import jadx.gui.utils.JumpPosition; import jadx.gui.utils.Link; import jadx.gui.utils.NLS; -import jadx.gui.utils.JumpPosition; import jadx.gui.utils.Utils; import static javax.swing.KeyStroke.getKeyStroke; @@ -90,7 +95,6 @@ public class MainWindow extends JFrame { private boolean isFlattenPackage; private JToggleButton flatPkgButton; private JCheckBoxMenuItem flatPkgMenuItem; - private JCheckBoxMenuItem heapUsageBarMenuItem; private JToggleButton deobfToggleBtn; private JCheckBoxMenuItem deobfMenuItem; @@ -382,7 +386,7 @@ public class MainWindow extends JFrame { flatPkgMenuItem = new JCheckBoxMenuItem(NLS.str("menu.flatten"), ICON_FLAT_PKG); flatPkgMenuItem.setState(isFlattenPackage); - heapUsageBarMenuItem = new JCheckBoxMenuItem(NLS.str("menu.heapUsageBar")); + JCheckBoxMenuItem heapUsageBarMenuItem = new JCheckBoxMenuItem(NLS.str("menu.heapUsageBar")); heapUsageBarMenuItem.setState(settings.isShowHeapUsageBar()); heapUsageBarMenuItem.addActionListener(event -> { settings.setShowHeapUsageBar(!settings.isShowHeapUsageBar()); @@ -589,7 +593,7 @@ public class MainWindow extends JFrame { }); tree.addTreeWillExpandListener(new TreeWillExpandListener() { @Override - public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException { + public void treeWillExpand(TreeExpansionEvent event) { TreePath path = event.getPath(); Object node = path.getLastPathComponent(); if (node instanceof JLoadableNode) { @@ -598,7 +602,8 @@ public class MainWindow extends JFrame { } @Override - public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException { + public void treeWillCollapse(TreeExpansionEvent event) { + // ignore } }); diff --git a/jadx-gui/src/main/java/jadx/gui/ui/TabbedPane.java b/jadx-gui/src/main/java/jadx/gui/ui/TabbedPane.java index 1fc5b1e06..5e6183e15 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/TabbedPane.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/TabbedPane.java @@ -1,5 +1,20 @@ package jadx.gui.ui; +import javax.swing.*; +import javax.swing.plaf.basic.BasicButtonUI; +import javax.swing.text.BadLocationException; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import jadx.api.ResourceFile; import jadx.api.ResourceType; import jadx.gui.treemodel.ApkSignature; @@ -13,29 +28,6 @@ import jadx.gui.utils.JumpManager; import jadx.gui.utils.JumpPosition; import jadx.gui.utils.NLS; import jadx.gui.utils.Utils; -import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.swing.BorderFactory; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JTabbedPane; -import javax.swing.SwingUtilities; -import javax.swing.plaf.basic.BasicButtonUI; -import javax.swing.text.BadLocationException; -import java.awt.Component; -import java.awt.FlowLayout; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; public class TabbedPane extends JTabbedPane { diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/LineNumbers.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/LineNumbers.java index 04e2b86ba..2b58f9c07 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/LineNumbers.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/LineNumbers.java @@ -32,16 +32,16 @@ public class LineNumbers extends JPanel implements CaretListener { private static final int NUM_HEIGHT = Integer.MAX_VALUE - 1000000; private static final Map DESKTOP_HINTS = (Map) Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"); - private CodeArea codeArea; + private final CodeArea codeArea; private boolean useSourceLines = true; private int lastDigits; private int lastLine; private Map fonts; - private transient final Color numberColor; - private transient final Color currentColor; - private transient final Border border; + private final transient Color numberColor; + private final transient Color currentColor; + private final transient Border border; public LineNumbers(CodeArea component) { this.codeArea = component; @@ -199,12 +199,10 @@ public class LineNumbers extends JPanel implements CaretListener { String fontFamily = (String) as.getAttribute(StyleConstants.FontFamily); Integer fontSize = (Integer) as.getAttribute(StyleConstants.FontSize); String key = fontFamily + fontSize; - FontMetrics fm = fonts.get(key); - if (fm == null) { + FontMetrics fm = fonts.computeIfAbsent(key, k -> { Font font = new Font(fontFamily, Font.PLAIN, fontSize); - fm = codeArea.getFontMetrics(font); - fonts.put(key, fm); - } + return codeArea.getFontMetrics(font); + }); descent = Math.max(descent, fm.getDescent()); } } diff --git a/jadx-gui/src/main/java/jadx/gui/update/JadxUpdate.java b/jadx-gui/src/main/java/jadx/gui/update/JadxUpdate.java index f3c1fd2c1..c88ceca4f 100644 --- a/jadx-gui/src/main/java/jadx/gui/update/JadxUpdate.java +++ b/jadx-gui/src/main/java/jadx/gui/update/JadxUpdate.java @@ -6,9 +6,8 @@ import java.io.Reader; import java.lang.reflect.Type; import java.net.HttpURLConnection; import java.net.URL; -import java.util.Collections; +import java.nio.charset.StandardCharsets; import java.util.Comparator; -import java.util.Iterator; import java.util.List; import com.google.gson.Gson; @@ -32,12 +31,8 @@ public class JadxUpdate { private static final Type RELEASES_LIST_TYPE = new TypeToken>() { }.getType(); - private static final Comparator RELEASE_COMPARATOR = new Comparator() { - @Override - public int compare(Release o1, Release o2) { - return VersionComparator.checkAndCompare(o1.getName(), o2.getName()); - } - }; + private static final Comparator RELEASE_COMPARATOR = (o1, o2) -> + VersionComparator.checkAndCompare(o1.getName(), o2.getName()); public interface IUpdateCallback { void onUpdate(Release r); @@ -47,17 +42,14 @@ public class JadxUpdate { } public static void check(final IUpdateCallback callback) { - Runnable run = new Runnable() { - @Override - public void run() { - try { - Release release = checkForNewRelease(); - if (release != null) { - callback.onUpdate(release); - } - } catch (Exception e) { - LOG.debug("Jadx update error", e); + Runnable run = () -> { + try { + Release release = checkForNewRelease(); + if (release != null) { + callback.onUpdate(release); } + } catch (Exception e) { + LOG.debug("Jadx update error", e); } }; Thread thread = new Thread(run); @@ -77,17 +69,11 @@ public class JadxUpdate { if (list == null) { return null; } - for (Iterator it = list.iterator(); it.hasNext(); ) { - Release release = it.next(); - if (release.getName().equalsIgnoreCase(version) - || release.isPreRelease()) { - it.remove(); - } - } + list.removeIf(release -> release.getName().equalsIgnoreCase(version) || release.isPreRelease()); if (list.isEmpty()) { return null; } - Collections.sort(list, RELEASE_COMPARATOR); + list.sort(RELEASE_COMPARATOR); Release latest = list.get(list.size() - 1); if (VersionComparator.checkAndCompare(version, latest.getName()) >= 0) { return null; @@ -101,7 +87,7 @@ public class JadxUpdate { HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestMethod("GET"); if (con.getResponseCode() == 200) { - Reader reader = new InputStreamReader(con.getInputStream(), "UTF-8"); + Reader reader = new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8); return GSON.fromJson(reader, type); } return null; diff --git a/jadx-gui/src/main/java/jadx/gui/utils/CertificateManager.java b/jadx-gui/src/main/java/jadx/gui/utils/CertificateManager.java index 29928aa7b..a64ec479f 100755 --- a/jadx-gui/src/main/java/jadx/gui/utils/CertificateManager.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/CertificateManager.java @@ -21,8 +21,8 @@ public class CertificateManager { private static final Logger LOG = LoggerFactory.getLogger(CertificateManager.class); private static final String CERTIFICATE_TYPE_NAME = "X.509"; + private final Certificate cert; private X509Certificate x509cert; - private Certificate cert; public static String decode(InputStream in) { StringBuilder strBuild = new StringBuilder(); diff --git a/jadx-gui/src/main/java/jadx/gui/utils/CodeLinesInfo.java b/jadx-gui/src/main/java/jadx/gui/utils/CodeLinesInfo.java index cb7a3a890..e2d2d0061 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/CodeLinesInfo.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/CodeLinesInfo.java @@ -9,7 +9,7 @@ import jadx.api.JavaMethod; import jadx.api.JavaNode; public class CodeLinesInfo { - private NavigableMap map = new TreeMap<>(); + private final NavigableMap map = new TreeMap<>(); public CodeLinesInfo(JavaClass cls) { addClass(cls); diff --git a/jadx-gui/src/main/java/jadx/gui/utils/CodeUsageInfo.java b/jadx-gui/src/main/java/jadx/gui/utils/CodeUsageInfo.java index 581e5c3c2..6a5869334 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/CodeUsageInfo.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/CodeUsageInfo.java @@ -2,7 +2,6 @@ package jadx.gui.utils; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -47,11 +46,11 @@ public class CodeUsageInfo { private void addUsage(JNode jNode, JavaClass javaClass, CodeLinesInfo linesInfo, CodePosition codePosition, List lines) { - UsageInfo usageInfo = usageMap.computeIfAbsent(jNode, key -> new UsageInfo()); - int line = codePosition.getLine(); - JavaNode javaNodeByLine = linesInfo.getJavaNodeByLine(line); - StringRef codeLine = lines.get(line - 1); - JNode node = nodeCache.makeFrom(javaNodeByLine == null ? javaClass : javaNodeByLine); + UsageInfo usageInfo = usageMap.computeIfAbsent(jNode, key -> new UsageInfo()); + int line = codePosition.getLine(); + JavaNode javaNodeByLine = linesInfo.getJavaNodeByLine(line); + StringRef codeLine = lines.get(line - 1); + JNode node = nodeCache.makeFrom(javaNodeByLine == null ? javaClass : javaNodeByLine); CodeNode codeNode = new CodeNode(node, line, codeLine); usageInfo.addUsage(codeNode); } diff --git a/jadx-gui/src/main/java/jadx/gui/utils/JumpManager.java b/jadx-gui/src/main/java/jadx/gui/utils/JumpManager.java index aef5bc0f1..e0d9608f5 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/JumpManager.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/JumpManager.java @@ -5,7 +5,7 @@ import java.util.List; public class JumpManager { - private List list = new ArrayList<>(); + private final List list = new ArrayList<>(); private int currentPos = 0; public void addPosition(JumpPosition pos) { diff --git a/jadx-gui/src/main/java/jadx/gui/utils/LangLocale.java b/jadx-gui/src/main/java/jadx/gui/utils/LangLocale.java index b3bead3bf..922d61426 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/LangLocale.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/LangLocale.java @@ -3,7 +3,7 @@ package jadx.gui.utils; import java.util.Locale; public class LangLocale { - private Locale locale; + private final Locale locale; public LangLocale(Locale locale) { this.locale = locale; diff --git a/jadx-gui/src/main/java/jadx/gui/utils/Link.java b/jadx-gui/src/main/java/jadx/gui/utils/Link.java index 27880e912..66fa6d0d7 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/Link.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/Link.java @@ -16,7 +16,7 @@ public class Link extends JLabel implements MouseListener { private static final Logger LOG = LoggerFactory.getLogger(Link.class); - private String url; + private final String url; public Link(String text, String url) { super(text); diff --git a/jadx-gui/src/main/java/jadx/gui/utils/NLS.java b/jadx-gui/src/main/java/jadx/gui/utils/NLS.java index 4e30a6727..74ee8594e 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/NLS.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/NLS.java @@ -4,24 +4,29 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.PropertyResourceBundle; +import java.util.ResourceBundle; +import java.util.Vector; -import org.jetbrains.annotations.NotNull; +import jadx.core.utils.exceptions.JadxRuntimeException; public class NLS { - private static Vector i18nLocales = new Vector<>(); + private static final Vector i18nLocales = new Vector<>(); - private static Map i18nMessagesMap = new HashMap<>(); + private static final Map i18nMessagesMap = new HashMap<>(); + + private static final ResourceBundle fallbackMessagesMap; + private static final LangLocale localLocale; // Use these two fields to avoid invoking Map.get() method twice. private static ResourceBundle localizedMessagesMap; - private static ResourceBundle fallbackMessagesMap; - private static LangLocale currentLocale; - private static LangLocale localLocale; static { localLocale = new LangLocale(Locale.getDefault()); @@ -45,10 +50,13 @@ public class NLS { ClassLoader classLoader = ClassLoader.getSystemClassLoader(); String resName = String.format("i18n/Messages_%s.properties", locale.get()); URL bundleUrl = classLoader.getResource(resName); + if (bundleUrl == null) { + throw new JadxRuntimeException("Locale resource not found: " + resName); + } try (Reader reader = new InputStreamReader(bundleUrl.openStream(), StandardCharsets.UTF_8)) { bundle = new PropertyResourceBundle(reader); } catch (IOException e) { - throw new RuntimeException("Failed to load " + resName, e); + throw new JadxRuntimeException("Failed to load " + resName, e); } i18nMessagesMap.put(locale, bundle); } @@ -66,7 +74,8 @@ public class NLS { if (bundle != null) { try { return bundle.getString(key); - } catch (MissingResourceException e) { + } catch (MissingResourceException ignored) { + // use fallback string } } return fallbackMessagesMap.getString(key); // definitely exists diff --git a/jadx-gui/src/main/java/jadx/gui/utils/Utils.java b/jadx-gui/src/main/java/jadx/gui/utils/Utils.java index c709350dd..4dadef845 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/Utils.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/Utils.java @@ -30,7 +30,7 @@ public class Utils { * The minimum about of memory in bytes we are trying to keep free, otherwise the application may run out of heap * which ends up in a Java garbage collector running "amok" (CPU utilization 100% for each core and the UI is * not responsive). - * + *

* We can calculate and store this value here as the maximum heap is fixed for each JVM instance * and can't be changed at runtime. */ @@ -123,8 +123,7 @@ public class Utils { public static long calculateMinFreeMemory() { Runtime runtime = Runtime.getRuntime(); long minFree = (long) (runtime.maxMemory() * 0.2); - minFree = Math.min(minFree, 512 * 1048576); - return minFree; + return Math.min(minFree, 512 * 1024L * 1024L); } public static boolean isFreeMemoryAvailable() { @@ -151,7 +150,7 @@ public class Utils { } private static String format(long mem) { - return Long.toString((long) (mem / 1024. / 1024.)) + "MB"; + return (long) (mem / (double) (1024L * 1024L)) + "MB"; } /** diff --git a/jadx-gui/src/main/resources/i18n/Messages_en_US.properties b/jadx-gui/src/main/resources/i18n/Messages_en_US.properties index c1e3aba38..ad43b2ff4 100644 --- a/jadx-gui/src/main/resources/i18n/Messages_en_US.properties +++ b/jadx-gui/src/main/resources/i18n/Messages_en_US.properties @@ -47,7 +47,7 @@ tabs.closeAll=Close All nav.back=Back nav.forward=Forward -message.indexingClassesSkipped=Jadx is running low on memory. Therefore %d classes were not indexed.
If you want all classes to be indexed restart Jadx with increased maximum heap size. +message.indexingClassesSkipped=Jadx is running low on memory. Therefore %d classes were not indexed.
If you want all classes to be indexed restart Jadx with increased maximum heap size. heapUsage.text=JADX memory usage: %.2f GB of %.2f GB @@ -152,4 +152,4 @@ apkSignature.signatureFailed=Invalid APK signature v%d found apkSignature.errors=Errors apkSignature.warnings=Warnings apkSignature.exception=APK verification failed -apkSignature.unprotectedEntry=Files that are not protected by signature. Unauthorized modifications to this JAR entry will not be detected. \ No newline at end of file +apkSignature.unprotectedEntry=Files that are not protected by signature. Unauthorized modifications to this JAR entry will not be detected. diff --git a/jadx-gui/src/test/groovy/jadx/gui/tests/TestStringRef.groovy b/jadx-gui/src/test/groovy/jadx/gui/tests/TestStringRef.groovy index 352978ab8..b6d30cdd3 100644 --- a/jadx-gui/src/test/groovy/jadx/gui/tests/TestStringRef.groovy +++ b/jadx-gui/src/test/groovy/jadx/gui/tests/TestStringRef.groovy @@ -1,4 +1,5 @@ package jadx.gui.tests + import jadx.gui.utils.search.StringRef import spock.lang.Specification diff --git a/jadx-gui/src/test/java/jadx/gui/utils/CertificateManagerTest.java b/jadx-gui/src/test/java/jadx/gui/utils/CertificateManagerTest.java index 0fd763e62..0e0e15268 100644 --- a/jadx-gui/src/test/java/jadx/gui/utils/CertificateManagerTest.java +++ b/jadx-gui/src/test/java/jadx/gui/utils/CertificateManagerTest.java @@ -1,112 +1,122 @@ package jadx.gui.utils; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.security.cert.Certificate; +import java.util.Collection; + import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import java.io.*; -import java.security.cert.Certificate; -import java.util.Collection; +public class CertificateManagerTest { + private static final String CERTIFICATE_TEST_DIR = "certificate-test/"; + private static final String DSA = "CERT.DSA"; + private static final String RSA = "CERT.RSA"; + private static final String EMPTY = "EMPTY.txt"; + private String emptyPath; + private CertificateManager certificateManagerRSA; + private CertificateManager certificateManagerDSA; -public class CertificateManagerTest { - private static final String DSA = "CERT.DSA"; - private static final String RSA = "CERT.RSA"; - private static final String EMPTY = "EMPTY.txt"; - private String emptyPath; - CertificateManager certificateManagerRSA; - CertificateManager certificateManagerDSA; + private CertificateManager getCertificateManger(String resName) { + String certPath = getResourcePath(resName); + try (InputStream in = new FileInputStream(certPath)) { + Collection certificates = CertificateManager.readCertificates(in); + Certificate cert = certificates.iterator().next(); + return new CertificateManager(cert); + } catch (Exception e) { + throw new RuntimeException("Failed to create CertificateManager"); + } + } - private CertificateManager getCertificateManger(String resName) - { - String sertPath = getClass().getClassLoader().getResource(resName).getPath(); - try (InputStream in = new FileInputStream(sertPath)) { - Collection certificates = CertificateManager.readCertificates(in); - Certificate cert = (Certificate)certificates.toArray()[0]; - return new CertificateManager(cert); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } + @Before + public void setUp() { + emptyPath = getResourcePath(EMPTY); + certificateManagerRSA = getCertificateManger(RSA); + certificateManagerDSA = getCertificateManger(DSA); + } - @Before - public void setUp() { - emptyPath = getClass().getClassLoader().getResource(EMPTY).getPath(); - certificateManagerRSA = getCertificateManger(RSA); - certificateManagerDSA = getCertificateManger(DSA); - } + @Test + public void decodeNotCertificateFile() throws IOException { + try (InputStream in = new FileInputStream(emptyPath)) { + String result = CertificateManager.decode(in); + Assert.assertEquals("", result); + } + } + @Test + public void decodeRSAKeyHeader() { + String string = certificateManagerRSA.generateHeader(); + Assert.assertTrue(string.contains("X.509")); + Assert.assertTrue(string.contains("0x4bd68052")); + Assert.assertTrue(string.contains("CN=test cert, OU=test unit, O=OOO TestOrg, L=St.Peterburg, ST=Russia, C=123456")); + } - @Test - public void decodeNotCertificateFile() { - try (InputStream in = new FileInputStream(emptyPath)) { - String result = CertificateManager.decode(in); - Assert.assertEquals(result, ""); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } + @Test + public void decodeDSAKeyHeader() { + String string = certificateManagerDSA.generateHeader(); + Assert.assertTrue(string.contains("X.509")); + Assert.assertTrue(string.contains("0x16420ba2")); + Assert.assertTrue(string.contains("O=\"UJMRFVV CN=EDCVBGT C=TG\"")); + } - @Test - public void decodeRSAKeyHeader() { - String string = certificateManagerRSA.generateHeader(); - Assert.assertTrue(string.contains("X.509")); - Assert.assertTrue(string.contains("0x4bd68052")); - Assert.assertTrue(string.contains("CN=test cert, OU=test unit, O=OOO TestOrg, L=St.Peterburg, ST=Russia, C=123456")); + @Test + public void decodeRSAKeySignature() { + String string = certificateManagerRSA.generateSignature(); + Assert.assertTrue(string.contains("SHA256withRSA")); + Assert.assertTrue(string.contains("1.2.840.113549.1.1.11")); + } - } + @Test + public void decodeDSAKeySignature() { + String string = certificateManagerDSA.generateSignature(); + Assert.assertTrue(string.contains("SHA1withDSA")); + Assert.assertTrue(string.contains("1.2.840.10040.4.3")); + } - @Test - public void decodeDSAKeyHeader() { - String string = certificateManagerDSA.generateHeader(); - Assert.assertTrue(string.contains("X.509")); - Assert.assertTrue(string.contains("0x16420ba2")); - Assert.assertTrue(string.contains("O=\"UJMRFVV CN=EDCVBGT C=TG\"")); + @Test + public void decodeRSAFingerprint() { + String string = certificateManagerRSA.generateFingerprint(); + Assert.assertTrue(string.contains("61 18 0A 71 3F C9 55 16 4E 04 E3 C5 45 08 D9 11")); + Assert.assertTrue(string.contains("A0 6E A6 06 DB 2C 6F 3A 16 56 7F 75 97 7B AE 85 C2 13 09 37")); + Assert.assertTrue(string.contains("12 53 E8 BB C8 AA 27 A8 49 9B F8 0D 6E 68 CE 32 35 50 DE 55 A7 E7 8C 29 51 00 96 D7 56 F4 54 " + + "44")); + } - } - @Test - public void decodeRSAKeySignature() { - String string = certificateManagerRSA.generateSignature(); - Assert.assertTrue(string.contains("SHA256withRSA")); - Assert.assertTrue(string.contains("1.2.840.113549.1.1.11")); - } - @Test - public void decodeDSAKeySignature() { - String string = certificateManagerDSA.generateSignature(); - Assert.assertTrue(string.contains("SHA1withDSA")); - Assert.assertTrue(string.contains("1.2.840.10040.4.3")); - } - @Test - public void decodeRSAFingerprint() { - String string = certificateManagerRSA.generateFingerprint(); - Assert.assertTrue(string.contains("61 18 0A 71 3F C9 55 16 4E 04 E3 C5 45 08 D9 11")); - Assert.assertTrue(string.contains("A0 6E A6 06 DB 2C 6F 3A 16 56 7F 75 97 7B AE 85 C2 13 09 37")); - Assert.assertTrue(string.contains("12 53 E8 BB C8 AA 27 A8 49 9B F8 0D 6E 68 CE 32 35 50 DE 55 A7 E7 8C 29 51 00 96 D7 56 F4 54 44")); - } - @Test - public void decodeDSAFingerprint() { - String string = certificateManagerDSA.generateFingerprint(); - Assert.assertTrue(string.contains("D9 06 A6 2D 1F 79 8C 9D A6 EF 40 C7 2E C2 EA 0B")); - Assert.assertTrue(string.contains("18 E9 9C D4 A1 40 8F 63 FA EC 2E 62 A0 F2 AE B7 3F C3 C2 04")); - Assert.assertTrue(string.contains("74 F9 48 64 EE AC 92 26 53 2C 7A 0E 55 BE 5E D8 2F A7 D9 A9 99 F5 D5 21 2C 51 21 C4 31 AD 73 40")); - } - @Test - public void decodeRSAPubKey() { - String string = certificateManagerRSA.generatePublicKey(); - Assert.assertTrue(string.contains("RSA")); - Assert.assertTrue(string.contains("65537")); - Assert.assertTrue(string.contains("16819531290318044625546437357099080306019392752925688951114880688329201213180109168890384305768067101521914473763638669503560977521269328582980060332888147680193318231260043189411794465899645633586173494259691101582064441956032924396850221679489313043628562082670183392670094163371858684118480409374749790551473773845213427476236147328434427272177623018935282929152308753854314219987617604037468769472089902090243358285991739642170211970862773121939911777280101937073243006335384636193260583579409760790138329893534549366882523130765297472656435892831796545149793228897111760122091442123535919361963075454640516520743")); - } - @Test - public void decodeDSAPubKey() { - String string = certificateManagerDSA.generatePublicKey(); - Assert.assertTrue(string.contains("DSA")); - Assert.assertTrue(string.contains("19323367605058154682563301282345453222279312104889899001698209626254725581511375469963812461090495963838615773832867364330457010553974237985991904800958394169421485070378434746792379708805563793253282995274293621162504943287538455944652344378242226897507369146942411692220922477368782490423187845815262510366")); - } + @Test + public void decodeDSAFingerprint() { + String string = certificateManagerDSA.generateFingerprint(); + Assert.assertTrue(string.contains("D9 06 A6 2D 1F 79 8C 9D A6 EF 40 C7 2E C2 EA 0B")); + Assert.assertTrue(string.contains("18 E9 9C D4 A1 40 8F 63 FA EC 2E 62 A0 F2 AE B7 3F C3 C2 04")); + Assert.assertTrue(string.contains("74 F9 48 64 EE AC 92 26 53 2C 7A 0E 55 BE 5E D8 2F A7 D9 A9 99 F5 D5 21 2C 51 21 C4 31 AD 73 " + + "40")); + } -} \ No newline at end of file + @Test + public void decodeRSAPubKey() { + String string = certificateManagerRSA.generatePublicKey(); + Assert.assertTrue(string.contains("RSA")); + Assert.assertTrue(string.contains("65537")); + Assert.assertTrue(string.contains( + "16819531290318044625546437357099080306019392752925688951114880688329201213180109168890384305768067101521914473763638669503560977521269328582980060332888147680193318231260043189411794465899645633586173494259691101582064441956032924396850221679489313043628562082670183392670094163371858684118480409374749790551473773845213427476236147328434427272177623018935282929152308753854314219987617604037468769472089902090243358285991739642170211970862773121939911777280101937073243006335384636193260583579409760790138329893534549366882523130765297472656435892831796545149793228897111760122091442123535919361963075454640516520743")); + } + + @Test + public void decodeDSAPubKey() { + String string = certificateManagerDSA.generatePublicKey(); + Assert.assertTrue(string.contains("DSA")); + Assert.assertTrue(string.contains( + "19323367605058154682563301282345453222279312104889899001698209626254725581511375469963812461090495963838615773832867364330457010553974237985991904800958394169421485070378434746792379708805563793253282995274293621162504943287538455944652344378242226897507369146942411692220922477368782490423187845815262510366")); + } + + private String getResourcePath(String resName) { + URL resource = getClass().getClassLoader().getResource(CERTIFICATE_TEST_DIR + resName); + if (resource == null) { + throw new RuntimeException("Resource not found: " + resName); + } + return resource.getPath(); + } +} diff --git a/jadx-gui/src/test/resources/CERT.DSA b/jadx-gui/src/test/resources/certificate-test/CERT.DSA similarity index 100% rename from jadx-gui/src/test/resources/CERT.DSA rename to jadx-gui/src/test/resources/certificate-test/CERT.DSA diff --git a/jadx-gui/src/test/resources/CERT.RSA b/jadx-gui/src/test/resources/certificate-test/CERT.RSA similarity index 100% rename from jadx-gui/src/test/resources/CERT.RSA rename to jadx-gui/src/test/resources/certificate-test/CERT.RSA diff --git a/jadx-gui/src/test/resources/EMPTY.txt b/jadx-gui/src/test/resources/certificate-test/EMPTY.txt similarity index 100% rename from jadx-gui/src/test/resources/EMPTY.txt rename to jadx-gui/src/test/resources/certificate-test/EMPTY.txt