mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
fix(apktool): preserve decoded APK Evidence subject (#4771)
Bind shared CLI/MCP Evidence to the digest already computed from the owned APK snapshot. Exercise source mutation during decoding through the shared application workflow and verify subject identity in the real Apktool lane. Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
This commit is contained in:
@@ -52,6 +52,8 @@ select Android's `values-pt-rBR`; Android qualifiers such as `pt-rBR` and
|
||||
|
||||
- **An owned APK snapshot is digested and decoded.** `target.sha256` and
|
||||
`target.bytes` bind the observation to the exact APK that was decoded.
|
||||
The Evidence subject carries the same snapshot digest and caller-selected
|
||||
path, including when the original file changes during decoding.
|
||||
- **Metadata comes from apktool.yml as apktool printed it.** Version codes
|
||||
keep their own spelling (`'7'` versus `7`); `package_name` is read from
|
||||
the decoded manifest, not inferred.
|
||||
|
||||
@@ -33,6 +33,16 @@ const run = async (operation, input) => {
|
||||
failures += 1;
|
||||
return null;
|
||||
}
|
||||
if (operation === "decode_android_resources") {
|
||||
const evidence = result.value;
|
||||
const target = evidence.normalized_result.target;
|
||||
check(
|
||||
"resource Evidence preserves the decoded APK subject identity",
|
||||
evidence.subject?.digest.sha256 === target.sha256 &&
|
||||
evidence.subject?.local_path === target.path &&
|
||||
evidence.subject?.format === "apk",
|
||||
);
|
||||
}
|
||||
return result.value.normalized_result;
|
||||
};
|
||||
|
||||
|
||||
@@ -11,8 +11,12 @@ import { join } from "node:path";
|
||||
import { describe, expect, onTestFinished, test } from "vitest";
|
||||
|
||||
import { ApktoolProvider } from "./ApktoolProvider.js";
|
||||
import { ApktoolResourceAnalysisService } from "../application/apktool/ApktoolResourceAnalysisService.js";
|
||||
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
||||
import { apktoolRequestSchema } from "../domain/apktool/apktoolResourceAnalysis.js";
|
||||
import {
|
||||
apktoolRequestSchema,
|
||||
apktoolResultSchemas,
|
||||
} from "../domain/apktool/apktoolResourceAnalysis.js";
|
||||
import type { ApktoolRequest } from "../domain/apktool/apktoolResourceAnalysis.js";
|
||||
|
||||
const it = test.skipIf(process.platform === "win32");
|
||||
@@ -491,10 +495,26 @@ it("uses an owned APK snapshot and framework cache and resolves regional locales
|
||||
),
|
||||
);
|
||||
const apk = await apkFixture(root);
|
||||
const result = await evidenceResult(providerOver(command), {
|
||||
operation: "decode_android_resources",
|
||||
input: { path: apk.path, include_strings: true, locale: "pt-BR" },
|
||||
const observation = await new ApktoolResourceAnalysisService(
|
||||
providerOver(command),
|
||||
).execute("decode_android_resources", {
|
||||
path: apk.path,
|
||||
include_strings: true,
|
||||
locale: "pt-BR",
|
||||
});
|
||||
if (!observation.ok) throw observation.error;
|
||||
expect(observation.value.subject).toMatchObject({
|
||||
local_path: apk.path,
|
||||
format: "apk",
|
||||
digest: { sha256: apk.sha256 },
|
||||
});
|
||||
expect(observation.value.limitations).not.toContain(
|
||||
"Artifact identity is unavailable for this observation.",
|
||||
);
|
||||
expect(await readFile(apk.path, "utf8")).toBe("changed original");
|
||||
const result = apktoolResultSchemas.decode_android_resources.parse(
|
||||
observation.value.normalized_result,
|
||||
);
|
||||
expect(result.target).toMatchObject({
|
||||
sha256: apk.sha256,
|
||||
bytes: apk.bytes,
|
||||
|
||||
@@ -801,6 +801,7 @@ export class ApktoolProvider {
|
||||
},
|
||||
provider,
|
||||
{
|
||||
subject: { path: input.path, sha256, format: "apk" },
|
||||
limitations: [
|
||||
"Decoding skips smali (--no-src); Java-source recovery belongs to the JADX family",
|
||||
...(input.locale !== undefined &&
|
||||
|
||||
Reference in New Issue
Block a user