capacitor-dex-editor 0.0.67 → 0.0.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -665,6 +665,18 @@ public class DexEditorPluginPlugin extends Plugin {
665
665
  ));
666
666
  break;
667
667
 
668
+ case "searchTextInApk":
669
+ result.put("data", dexManager.searchTextInApk(
670
+ params.getString("apkPath"),
671
+ params.getString("pattern"),
672
+ params.optJSONArray("fileExtensions"),
673
+ params.optBoolean("caseSensitive", false),
674
+ params.optBoolean("isRegex", false),
675
+ params.optInt("maxResults", 50),
676
+ params.optInt("contextLines", 2)
677
+ ));
678
+ break;
679
+
668
680
  case "readApkFile":
669
681
  result.put("data", dexManager.readApkFile(
670
682
  params.getString("apkPath"),
@@ -3676,6 +3676,136 @@ public class DexManager {
3676
3676
  return result;
3677
3677
  }
3678
3678
 
3679
+ /**
3680
+ * 在 APK 中搜索文本内容
3681
+ */
3682
+ public JSObject searchTextInApk(String apkPath, String pattern, org.json.JSONArray fileExtensions,
3683
+ boolean caseSensitive, boolean isRegex, int maxResults, int contextLines) throws Exception {
3684
+ JSObject result = new JSObject();
3685
+ JSArray results = new JSArray();
3686
+
3687
+ // 二进制文件扩展名(跳过)
3688
+ java.util.Set<String> binaryExtensions = new java.util.HashSet<>(java.util.Arrays.asList(
3689
+ ".dex", ".so", ".png", ".jpg", ".jpeg", ".gif", ".webp", ".ico",
3690
+ ".zip", ".apk", ".jar", ".class", ".ogg", ".mp3", ".wav", ".mp4",
3691
+ ".arsc", ".9.png", ".ttf", ".otf", ".woff"
3692
+ ));
3693
+
3694
+ // 解析文件扩展名过滤
3695
+ java.util.Set<String> allowedExtensions = new java.util.HashSet<>();
3696
+ if (fileExtensions != null && fileExtensions.length() > 0) {
3697
+ for (int i = 0; i < fileExtensions.length(); i++) {
3698
+ String ext = fileExtensions.getString(i);
3699
+ if (!ext.startsWith(".")) ext = "." + ext;
3700
+ allowedExtensions.add(ext.toLowerCase());
3701
+ }
3702
+ }
3703
+
3704
+ // 编译搜索模式
3705
+ java.util.regex.Pattern regex;
3706
+ int flags = caseSensitive ? 0 : java.util.regex.Pattern.CASE_INSENSITIVE;
3707
+ if (isRegex) {
3708
+ regex = java.util.regex.Pattern.compile(pattern, flags);
3709
+ } else {
3710
+ regex = java.util.regex.Pattern.compile(java.util.regex.Pattern.quote(pattern), flags);
3711
+ }
3712
+
3713
+ int totalFound = 0;
3714
+ int filesSearched = 0;
3715
+ boolean truncated = false;
3716
+
3717
+ java.util.zip.ZipFile zipFile = null;
3718
+ try {
3719
+ zipFile = new java.util.zip.ZipFile(apkPath);
3720
+ java.util.Enumeration<? extends java.util.zip.ZipEntry> entries = zipFile.entries();
3721
+
3722
+ while (entries.hasMoreElements() && totalFound < maxResults) {
3723
+ java.util.zip.ZipEntry entry = entries.nextElement();
3724
+ if (entry.isDirectory()) continue;
3725
+
3726
+ String name = entry.getName();
3727
+ String ext = "";
3728
+ int dotIndex = name.lastIndexOf('.');
3729
+ if (dotIndex > 0) {
3730
+ ext = name.substring(dotIndex).toLowerCase();
3731
+ }
3732
+
3733
+ // 跳过二进制文件
3734
+ if (binaryExtensions.contains(ext)) continue;
3735
+
3736
+ // 检查扩展名过滤
3737
+ if (!allowedExtensions.isEmpty() && !allowedExtensions.contains(ext)) continue;
3738
+
3739
+ // 跳过大文件(> 1MB)
3740
+ if (entry.getSize() > 1024 * 1024) continue;
3741
+
3742
+ try {
3743
+ java.io.InputStream is = zipFile.getInputStream(entry);
3744
+ byte[] data = new byte[(int) entry.getSize()];
3745
+ int totalRead = 0;
3746
+ int read;
3747
+ while (totalRead < data.length && (read = is.read(data, totalRead, data.length - totalRead)) != -1) {
3748
+ totalRead += read;
3749
+ }
3750
+ is.close();
3751
+
3752
+ // 检查是否是二进制
3753
+ boolean isBinary = false;
3754
+ for (int i = 0; i < Math.min(100, data.length); i++) {
3755
+ if (data[i] == 0) {
3756
+ isBinary = true;
3757
+ break;
3758
+ }
3759
+ }
3760
+ if (isBinary) continue;
3761
+
3762
+ String content = new String(data, java.nio.charset.StandardCharsets.UTF_8);
3763
+ String[] lines = content.split("\n");
3764
+
3765
+ filesSearched++;
3766
+
3767
+ for (int i = 0; i < lines.length && totalFound < maxResults; i++) {
3768
+ java.util.regex.Matcher matcher = regex.matcher(lines[i]);
3769
+ if (matcher.find()) {
3770
+ JSObject match = new JSObject();
3771
+ match.put("file", name);
3772
+ match.put("lineNumber", i + 1);
3773
+ match.put("line", lines[i].trim());
3774
+
3775
+ // 添加上下文
3776
+ JSArray context = new JSArray();
3777
+ int start = Math.max(0, i - contextLines);
3778
+ int end = Math.min(lines.length, i + contextLines + 1);
3779
+ for (int j = start; j < end; j++) {
3780
+ context.put(lines[j]);
3781
+ }
3782
+ match.put("context", context);
3783
+
3784
+ results.put(match);
3785
+ totalFound++;
3786
+ }
3787
+ }
3788
+ } catch (Exception e) {
3789
+ // 跳过无法读取的文件
3790
+ }
3791
+ }
3792
+
3793
+ truncated = totalFound >= maxResults;
3794
+
3795
+ } finally {
3796
+ if (zipFile != null) {
3797
+ try { zipFile.close(); } catch (Exception ignored) {}
3798
+ }
3799
+ }
3800
+
3801
+ result.put("results", results);
3802
+ result.put("totalFound", totalFound);
3803
+ result.put("filesSearched", filesSearched);
3804
+ result.put("truncated", truncated);
3805
+
3806
+ return result;
3807
+ }
3808
+
3679
3809
  /**
3680
3810
  * 清理临时目录
3681
3811
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-dex-editor",
3
- "version": "0.0.67",
3
+ "version": "0.0.68",
4
4
  "description": "Capacitor-plugin-for-editing-DEX-files-in-APK",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",