fix(apple): reject empty caches and bind digests to resolution traces

This commit is contained in:
morluto 2026-10-08 16:06:51 +08:00
parent d5921db039
commit e1597a6f3d
3 changed files with 17 additions and 9 deletions

View File

@ -187,6 +187,7 @@ const readHeader = async (file: CacheFile): Promise<ParsedHeader> => {
if (
mappingOffset < 0x20 ||
mappingOffset > MAX_HEADER_BYTES ||
mappingCount === 0 ||
mappingCount > MAX_MAPPINGS
)
throw new ArtifactReaderFailure(

View File

@ -148,19 +148,24 @@ export const traceDylibResolution = async (options: {
"integrity",
`Active target digest changed: expected ${options.targetSha256}, observed ${targetDigest}`,
);
// Bind the trace to the cache bytes that produced it: a replaced cache
// can retain header UUID/architecture while changing resolutions.
const cacheIdentity =
cache === undefined || parsed.data.shared_cache === undefined
? null
: {
path: resolve(parsed.data.shared_cache),
uuid: cache.header.uuid,
architecture: cache.header.architecture,
os_version: cache.header.os_version,
main_file_sha256: await cache.mainSha256(options.signal),
subcache_sha256: await cache.subcacheSha256(options.signal),
};
return dylibResolutionResultSchema.parse({
...trace,
root_path: options.rootPath,
target_sha256: options.targetSha256,
shared_cache:
cache === undefined || parsed.data.shared_cache === undefined
? null
: {
path: resolve(parsed.data.shared_cache),
uuid: cache.header.uuid,
architecture: cache.header.architecture,
os_version: cache.header.os_version,
},
shared_cache: cacheIdentity,
images: trace.images.map((image) => ({
...image,
sha256: digests.get(image.path),

View File

@ -169,6 +169,8 @@ export const dylibResolutionResultSchema = z.strictObject({
uuid: z.string(),
architecture: z.string(),
os_version: z.string().nullable(),
main_file_sha256: digestSchema,
subcache_sha256: z.record(z.string(), digestSchema).default({}),
})
.nullable(),
roots: z.array(