From 80d3fd40f10dfcabaccec136984db81bb182f009 Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Fri, 23 Oct 2026 18:42:34 +0800 Subject: [PATCH] fix(adb): count Unicode requested permissions Count requested-permission rows containing Unicode names, and keep counting subsequent rows in the same dumpsys section. Fixes #6584 --- docs/adb-device-analysis.md | 2 +- src/adb/AdbProvider.test.ts | 26 ++++++++++++++++++++++++++ src/adb/AdbShellOutput.test.ts | 17 +++++++++++++++++ src/adb/AdbShellOutput.ts | 5 +---- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/docs/adb-device-analysis.md b/docs/adb-device-analysis.md index f9f74c0d34..ac5f475434 100644 --- a/docs/adb-device-analysis.md +++ b/docs/adb-device-analysis.md @@ -90,7 +90,7 @@ existing analysis families directly, for example | `read_adb_logcat` | read | Bounded `logcat -d -t` dump for one buffer, optional pid filter | | `list_adb_packages` | read | `pm list packages -f` with scope; base APK device paths | | `resolve_adb_packages` | read | Case-insensitive package-name substring search with exact-match flag | -| `inspect_adb_package` | read | `dumpsys package` projection: versions, install times, installer, flags, permission count | +| `inspect_adb_package` | read | `dumpsys package` projection: versions, install times, installer, flags, and count of listed requested-permission rows (including Unicode names) | | `list_adb_directory` | read | NUL-framed immediate children, including hidden entries: kinds, permissions, owner, group, sizes, symlink targets | | `pull_adb_package` | read | Complete split APK set from `pm path`, each file digested | | `pull_adb_file` | read | One absolute device path pulled and digested | diff --git a/src/adb/AdbProvider.test.ts b/src/adb/AdbProvider.test.ts index 814b269b68..1312603d17 100644 --- a/src/adb/AdbProvider.test.ts +++ b/src/adb/AdbProvider.test.ts @@ -865,6 +865,32 @@ it("counts requested permissions that the device marks as restricted", async () }); }); +it("counts Unicode requested-permission names and continues through the section", async () => { + const { binary } = await writeAdbStub( + shellStub({ + "dumpsys:package": `Packages: + Package [com.example] (abcdef): + pkg=Package{abcdef com.example} + versionCode=45 minSdk=24 targetSdk=34 + requested permissions: + com.example.permission.FIRST + com.example.permission.ÉCRIRE + android.permission.CAMERA + install permissions: + android.permission.CAMERA: granted=true +`, + }), + ); + const result = await evidenceResult(providerOver(binary), { + operation: "inspect_adb_package", + input: { serial: "emulator-5554", package: "com.example" }, + }); + expect(result).toMatchObject({ + requested_permissions_count: 3, + coverage: "complete", + }); +}); + it("reports an uninstalled package from dumpsys refusal output", async () => { const { binary } = await writeAdbStub( shellStub({ "dumpsys:package": "Unable to find package: com.absent\n" }), diff --git a/src/adb/AdbShellOutput.test.ts b/src/adb/AdbShellOutput.test.ts index 8748eca920..f66a504393 100644 --- a/src/adb/AdbShellOutput.test.ts +++ b/src/adb/AdbShellOutput.test.ts @@ -284,6 +284,23 @@ describe("parseDumpsysPackageOutput", () => { ).requestedPermissions, ).toBe(2); }); + + it("counts Unicode permission names without ending the section", () => { + expect( + parseDumpsysPackageOutput( + [ + "Package [com.example] (abcdef):", + " pkg=Package{abcdef com.example}", + " requested permissions:", + " com.example.permission-First", + " com.example.permission.ÉCRIRE", + " android.permission.CAMERA", + " install permissions:", + " android.permission.CAMERA: granted=true", + ].join("\n"), + ).requestedPermissions, + ).toBe(3); + }); }); describe("parseWmDensityOutput", () => { diff --git a/src/adb/AdbShellOutput.ts b/src/adb/AdbShellOutput.ts index 6ba646611b..45df52e2d3 100644 --- a/src/adb/AdbShellOutput.ts +++ b/src/adb/AdbShellOutput.ts @@ -324,10 +324,7 @@ export const parseDumpsysPackageOutput = ( continue; } // Android 10 and 11 mark restricted entries as "NAME: restricted=true". - if ( - inPermissions && - /^\s{2,}[A-Za-z0-9._$-]+(?:: restricted=true)?$/u.test(line) - ) { + if (inPermissions && /^\s{2,}\S+(?:: restricted=true)?$/u.test(line)) { permissions += 1; continue; }