Projects STRLCPY jadx Commits bc4db61e
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■
    jadx-gui/src/main/java/jadx/gui/plugins/quark/QuarkManager.java
    skipped 106 lines
    107 107   private void loadReport() {
    108 108   try {
    109 109   QuarkReportNode quarkNode = new QuarkReportNode(reportFile);
    110  - JRoot root = mainWindow.getCacheObject().getJRoot();
     110 + JRoot root = mainWindow.getTreeRoot();
    111 111   root.replaceCustomNode(quarkNode);
    112 112   root.update();
    113 113   mainWindow.reloadTree();
    skipped 109 lines
  • ■ ■ ■ ■ ■ ■
    jadx-gui/src/main/java/jadx/gui/search/providers/ResourceSearchProvider.java
    1 1  package jadx.gui.search.providers;
    2 2   
    3  -import java.io.File;
    4  -import java.io.IOException;
    5  -import java.util.ArrayList;
     3 +import java.util.ArrayDeque;
     4 +import java.util.Deque;
     5 +import java.util.Enumeration;
    6 6  import java.util.HashSet;
    7  -import java.util.List;
    8 7  import java.util.Set;
    9  -import java.util.zip.ZipEntry;
    10  -import java.util.zip.ZipFile;
    11 8   
    12 9  import javax.swing.tree.TreeNode;
    13 10   
    skipped 4 lines
    18 15  import jadx.api.ICodeWriter;
    19 16  import jadx.api.ResourceFile;
    20 17  import jadx.api.ResourceType;
    21  -import jadx.core.utils.files.FileUtils;
     18 +import jadx.api.plugins.utils.CommonFileUtils;
    22 19  import jadx.gui.jobs.Cancelable;
    23 20  import jadx.gui.search.ISearchProvider;
    24 21  import jadx.gui.search.SearchSettings;
    25 22  import jadx.gui.treemodel.JNode;
    26 23  import jadx.gui.treemodel.JResSearchNode;
    27 24  import jadx.gui.treemodel.JResource;
     25 +import jadx.gui.treemodel.JRoot;
    28 26  import jadx.gui.ui.MainWindow;
    29  -import jadx.gui.utils.CacheObject;
    30 27   
    31 28  public class ResourceSearchProvider implements ISearchProvider {
    32 29   private static final Logger LOG = LoggerFactory.getLogger(ResourceSearchProvider.class);
    33 30   
    34  - private final CacheObject cache;
    35 31   private final SearchSettings searchSettings;
    36  - private final Set<String> extSet = new HashSet<>();
    37  - 
    38  - private List<JResource> resNodes;
    39  - private String fileExts;
     32 + private final Set<String> extSet;
     33 + private final int sizeLimit;
    40 34   private boolean anyExt;
    41  - private int sizeLimit;
    42 35   
    43  - private int progress;
     36 + /**
     37 + * Resources queue for process. Using UI nodes to reuse loading cache
     38 + */
     39 + private final Deque<JResource> resQueue;
    44 40   private int pos;
    45 41   
    46 42   public ResourceSearchProvider(MainWindow mw, SearchSettings searchSettings) {
    47  - this.cache = mw.getCacheObject();
    48 43   this.searchSettings = searchSettings;
     44 + this.sizeLimit = mw.getSettings().getSrhResourceSkipSize() * 1048576;
     45 + this.extSet = buildAllowedFilesExtensions(mw.getSettings().getSrhResourceFileExt());
     46 + this.resQueue = initResQueue(mw);
    49 47   }
    50 48   
    51 49   @Override
    52 50   public @Nullable JNode next(Cancelable cancelable) {
    53  - if (resNodes == null) {
    54  - load();
    55  - }
    56  - if (resNodes.isEmpty()) {
    57  - return null;
    58  - }
    59 51   while (true) {
    60 52   if (cancelable.isCanceled()) {
    61 53   return null;
    62 54   }
    63  - JResource resNode = resNodes.get(progress);
     55 + JResource resNode = getNextNode();
     56 + if (resNode == null) {
     57 + return null;
     58 + }
    64 59   JNode newResult = search(resNode);
    65 60   if (newResult != null) {
    66 61   return newResult;
    67 62   }
    68  - progress++;
    69 63   pos = 0;
    70  - if (progress >= resNodes.size()) {
     64 + resQueue.removeLast();
     65 + addChildren(resQueue, resNode);
     66 + if (resQueue.isEmpty()) {
    71 67   return null;
    72 68   }
    73 69   }
    skipped 20 lines
    94 90   return new JResSearchNode(resNode, line.trim(), newPos);
    95 91   }
    96 92   
    97  - private synchronized void load() {
    98  - resNodes = new ArrayList<>();
    99  - sizeLimit = cache.getJadxSettings().getSrhResourceSkipSize() * 1048576;
    100  - fileExts = cache.getJadxSettings().getSrhResourceFileExt();
    101  - for (String extStr : fileExts.split("\\|")) {
    102  - String ext = extStr.trim();
    103  - if (!ext.isEmpty()) {
    104  - anyExt = ext.equals("*");
    105  - if (anyExt) {
    106  - break;
    107  - }
    108  - extSet.add(ext);
    109  - }
     93 + private @Nullable JResource getNextNode() {
     94 + JResource node = resQueue.peekLast();
     95 + if (node == null) {
     96 + return null;
    110 97   }
    111  - try (ZipFile zipFile = getZipFile(cache.getJRoot())) {
    112  - traverseTree(cache.getJRoot(), zipFile); // reindex
     98 + try {
     99 + node.loadNode();
    113 100   } catch (Exception e) {
    114  - LOG.error("Failed to apply settings to resource index", e);
     101 + LOG.error("Error load resource node: {}", node, e);
     102 + resQueue.removeLast();
     103 + return getNextNode();
    115 104   }
     105 + if (node.getType() == JResource.JResType.FILE) {
     106 + if (shouldProcess(node)) {
     107 + return node;
     108 + }
     109 + resQueue.removeLast();
     110 + return getNextNode();
     111 + }
     112 + // dit or root
     113 + resQueue.removeLast();
     114 + addChildren(resQueue, node);
     115 + return getNextNode();
    116 116   }
    117 117   
    118  - private void traverseTree(TreeNode root, @Nullable ZipFile zip) {
    119  - for (int i = 0; i < root.getChildCount(); i++) {
    120  - TreeNode node = root.getChildAt(i);
     118 + private void addChildren(Deque<JResource> deque, JResource resNode) {
     119 + Enumeration<TreeNode> children = resNode.children();
     120 + while (children.hasMoreElements()) {
     121 + TreeNode node = children.nextElement();
    121 122   if (node instanceof JResource) {
    122  - JResource resNode = (JResource) node;
    123  - try {
    124  - resNode.loadNode();
    125  - } catch (Exception e) {
    126  - LOG.error("Error load resource node: {}", resNode, e);
    127  - return;
    128  - }
    129  - ResourceFile resFile = resNode.getResFile();
    130  - if (resFile == null) {
    131  - traverseTree(node, zip);
    132  - } else {
    133  - if (resFile.getType() == ResourceType.ARSC && shouldSearchXML()) {
    134  - resFile.loadContent();
    135  - resNode.getFiles().forEach(t -> traverseTree(t, null));
    136  - } else {
    137  - filter(resNode, zip);
    138  - }
    139  - }
     123 + deque.add((JResource) node);
    140 124   }
    141 125   }
    142 126   }
    143 127   
    144  - private boolean shouldSearchXML() {
    145  - return anyExt || fileExts.contains(".xml");
    146  - }
    147  - 
    148  - @Nullable
    149  - private ZipFile getZipFile(TreeNode res) {
    150  - for (int i = 0; i < res.getChildCount(); i++) {
    151  - TreeNode node = res.getChildAt(i);
     128 + private static Deque<JResource> initResQueue(MainWindow mw) {
     129 + JRoot jRoot = mw.getTreeRoot();
     130 + Deque<JResource> deque = new ArrayDeque<>(jRoot.getChildCount());
     131 + Enumeration<TreeNode> children = jRoot.children();
     132 + while (children.hasMoreElements()) {
     133 + TreeNode node = children.nextElement();
    152 134   if (node instanceof JResource) {
    153 135   JResource resNode = (JResource) node;
    154  - try {
    155  - resNode.loadNode();
    156  - } catch (Exception e) {
    157  - LOG.error("Error load resource node: {}", resNode, e);
    158  - return null;
     136 + deque.add(resNode);
     137 + }
     138 + }
     139 + return deque;
     140 + }
     141 + 
     142 + private Set<String> buildAllowedFilesExtensions(String srhResourceFileExt) {
     143 + Set<String> set = new HashSet<>();
     144 + for (String extStr : srhResourceFileExt.split("[|.]")) {
     145 + String ext = extStr.trim();
     146 + if (!ext.isEmpty()) {
     147 + anyExt = ext.equals("*");
     148 + if (anyExt) {
     149 + break;
    159 150   }
    160  - ResourceFile file = resNode.getResFile();
    161  - if (file == null) {
    162  - ZipFile zip = getZipFile(resNode);
    163  - if (zip != null) {
    164  - return zip;
    165  - }
    166  - } else {
    167  - ResourceFile.ZipRef zipRef = file.getZipRef();
    168  - if (zipRef != null) {
    169  - File zfile = zipRef.getZipFile();
    170  - if (FileUtils.isZipFile(zfile)) {
    171  - try {
    172  - return new ZipFile(zfile);
    173  - } catch (IOException ignore) {
    174  - }
    175  - }
    176  - }
    177  - }
     151 + set.add(ext);
    178 152   }
    179 153   }
    180  - return null;
     154 + return set;
    181 155   }
    182 156   
    183  - private void filter(JResource resNode, ZipFile zip) {
    184  - ResourceFile resFile = resNode.getResFile();
    185  - if (JResource.isSupportedForView(resFile.getType())) {
    186  - long size = -1;
    187  - if (zip != null) {
    188  - ZipEntry entry = zip.getEntry(resFile.getOriginalName());
    189  - if (entry != null) {
    190  - size = entry.getSize();
     157 + private boolean shouldProcess(JResource resNode) {
     158 + if (!anyExt) {
     159 + String fileExt;
     160 + ResourceFile resFile = resNode.getResFile();
     161 + if (resFile.getType() == ResourceType.ARSC) {
     162 + fileExt = "xml";
     163 + } else {
     164 + fileExt = CommonFileUtils.getFileExtension(resFile.getOriginalName());
     165 + if (fileExt == null) {
     166 + return false;
    191 167   }
    192 168   }
    193  - if (size == -1) { // resource from ARSC is unknown size
    194  - try {
    195  - size = resNode.getCodeInfo().getCodeStr().length();
    196  - } catch (Exception ignore) {
    197  - return;
    198  - }
     169 + if (!extSet.contains(fileExt)) {
     170 + return false;
    199 171   }
    200  - if (size <= sizeLimit) {
    201  - if (!anyExt) {
    202  - for (String ext : extSet) {
    203  - if (resFile.getOriginalName().endsWith(ext)) {
    204  - resNodes.add(resNode);
    205  - break;
    206  - }
    207  - }
    208  - } else {
    209  - resNodes.add(resNode);
    210  - }
    211  - } else {
    212  - LOG.debug("Resource index skipped because of size limit: {} res size {} bytes", resNode, size);
     172 + }
     173 + if (sizeLimit == 0) {
     174 + return true;
     175 + }
     176 + try {
     177 + int charsCount = resNode.getCodeInfo().getCodeStr().length();
     178 + long size = charsCount * 8L;
     179 + if (size > sizeLimit) {
     180 + LOG.debug("Resource search skipped because of size limit: {} res size {} bytes", resNode, size);
     181 + return false;
    213 182   }
     183 + return true;
     184 + } catch (Exception e) {
     185 + LOG.warn("Resource load error: {}", resNode, e);
     186 + return false;
    214 187   }
    215 188   }
    216 189   
    217 190   @Override
    218 191   public int progress() {
    219  - return progress;
     192 + return 0;
    220 193   }
    221 194   
    222 195   @Override
    223 196   public int total() {
    224  - return resNodes == null ? 0 : resNodes.size();
     197 + return 0;
    225 198   }
    226 199  }
    227 200   
  • ■ ■ ■ ■ ■
    jadx-gui/src/main/java/jadx/gui/treemodel/JResource.java
    skipped 91 lines
    92 92   }
    93 93   
    94 94   @Override
    95  - public void loadNode() {
     95 + public synchronized void loadNode() {
    96 96   getCodeInfo();
    97 97   update();
    98 98   }
    skipped 1 lines
    100 100   @Override
    101 101   public String getName() {
    102 102   return name;
     103 + }
     104 + 
     105 + public JResType getType() {
     106 + return type;
    103 107   }
    104 108   
    105 109   public List<JResource> getFiles() {
    skipped 243 lines
  • ■ ■ ■ ■ ■ ■
    jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
    skipped 595 lines
    596 596   
    597 597   protected void resetCache() {
    598 598   cacheObject.reset();
    599  - cacheObject.setJRoot(treeRoot);
    600  - cacheObject.setJadxSettings(settings);
    601 599   }
    602 600   
    603 601   synchronized void runInitialBackgroundJobs() {
    skipped 76 lines
    680 678   
    681 679   public void initTree() {
    682 680   treeRoot = new JRoot(wrapper);
    683  - cacheObject.setJRoot(treeRoot);
    684 681   treeRoot.setFlatPackages(isFlattenPackage);
    685 682   treeModel.setRoot(treeRoot);
    686 683   addTreeCustomNodes();
    687 684   treeRoot.update();
    688 685   reloadTree();
    689  - cacheObject.setJadxSettings(settings);
    690 686   }
    691 687   
    692 688   private void clearTree() {
    skipped 942 lines
  • ■ ■ ■ ■ ■ ■
    jadx-gui/src/main/java/jadx/gui/utils/CacheObject.java
    skipped 7 lines
    8 8  import org.jetbrains.annotations.Nullable;
    9 9   
    10 10  import jadx.api.JavaClass;
    11  -import jadx.gui.settings.JadxSettings;
    12  -import jadx.gui.treemodel.JRoot;
    13 11  import jadx.gui.ui.dialog.SearchDialog;
    14 12   
    15 13  public class CacheObject {
    skipped 2 lines
    18 16   private JNodeCache jNodeCache;
    19 17   private Map<SearchDialog.SearchPreset, Set<SearchDialog.SearchOptions>> lastSearchOptions;
    20 18   
    21  - private JRoot jRoot;
    22  - private JadxSettings settings;
    23  - 
    24 19   private List<List<JavaClass>> decompileBatches;
    25 20   
    26 21   public CacheObject() {
    skipped 1 lines
    28 23   }
    29 24   
    30 25   public void reset() {
    31  - jRoot = null;
    32  - settings = null;
    33 26   lastSearch = null;
    34 27   jNodeCache = new JNodeCache();
    35 28   lastSearchOptions = new HashMap<>();
    skipped 15 lines
    51 44   
    52 45   public Map<SearchDialog.SearchPreset, Set<SearchDialog.SearchOptions>> getLastSearchOptions() {
    53 46   return lastSearchOptions;
    54  - }
    55  - 
    56  - public void setJadxSettings(JadxSettings settings) {
    57  - this.settings = settings;
    58  - }
    59  - 
    60  - public JadxSettings getJadxSettings() {
    61  - return this.settings;
    62  - }
    63  - 
    64  - public JRoot getJRoot() {
    65  - return jRoot;
    66  - }
    67  - 
    68  - public void setJRoot(JRoot jRoot) {
    69  - this.jRoot = jRoot;
    70 47   }
    71 48   
    72 49   public @Nullable List<List<JavaClass>> getDecompileBatches() {
    skipped 8 lines
Please wait...
Page is in error, reload to recover