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
This commit is contained in:
morluto
2026-10-23 18:42:34 +08:00
parent 55185abec8
commit 80d3fd40f1
4 changed files with 45 additions and 5 deletions
+1 -1
View File
@@ -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 |
+26
View File
@@ -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" }),
+17
View File
@@ -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", () => {
+1 -4
View File
@@ -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;
}