Repository navigation
manifest 删去 runtime:运行时随 App,包只含页面 #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,7 +3,6 @@ import { looksLikePublicKey } from "./signature.ts"; | |
|
|
||
| /** The signed `<version>/manifest.json` `tinyui bundle` wrote (tinyui docs/updates.md §1.1), the fields this server checks. */ | ||
| export interface Manifest { | ||
| runtime: string[]; | ||
| pages: string[]; | ||
| files: Record<string, string>; | ||
| hashes: Record<string, string>; | ||
|
|
@@ -24,7 +23,7 @@ export function parseManifest(text: string): Manifest { | |
| } | ||
| if (typeof raw !== "object" || raw === null) throw new Error("manifest.json is not an object"); | ||
| const m = raw as Record<string, unknown>; | ||
| const names = (key: "runtime" | "pages"): string[] => { | ||
| const names = (key: "pages"): string[] => { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [建议] |
||
| const list = m[key]; | ||
| if (!Array.isArray(list) || !list.every((x) => typeof x === "string")) throw new Error(`manifest.json ${key} must list module names`); | ||
| return list as string[]; | ||
|
|
@@ -40,7 +39,6 @@ export function parseManifest(text: string): Manifest { | |
| return value; | ||
| }; | ||
| const manifest: Manifest = { | ||
| runtime: names("runtime"), | ||
| pages: names("pages"), | ||
| files: table("files"), | ||
| hashes: table("hashes"), | ||
|
|
@@ -55,11 +53,11 @@ export function parseManifest(text: string): Manifest { | |
| if (!isHostVersion(manifest.hostVersion)) throw new Error("manifest.json hostVersion is not a positive integer"); | ||
| if (instant(manifest.createdAt) === null) throw new Error("manifest.json createdAt is not a real YYYY-MM-DDTHH:MM:SSZ instant"); | ||
| if (!looksLikePublicKey(manifest.publicKey)) throw new Error("manifest.json publicKey is not a P-256 point"); | ||
| const modules = [...manifest.runtime, ...manifest.pages]; | ||
| const modules = manifest.pages; | ||
| if (new Set(modules).size !== modules.length) throw new Error("manifest.json lists a module twice"); | ||
| for (const key of ["files", "hashes"] as const) { | ||
| const keys = Object.keys(manifest[key]).sort(); | ||
| if (keys.join("\n") !== [...modules].sort().join("\n")) throw new Error(`manifest.json ${key} does not cover exactly the modules in runtime and pages`); | ||
| if (keys.join("\n") !== [...modules].sort().join("\n")) throw new Error(`manifest.json ${key} does not cover exactly the modules in pages`); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Require page modules to reference page paths. The new coverage check validates module keys but not their file paths. A manifest can map 🤖 Prompt for AI Agents |
||
| } | ||
| for (const path of Object.values(manifest.files)) { | ||
| if (!isObjectPath(path + ".bin")) throw new Error(`manifest.json files entry ${path} is not a file path`); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk):
parseManifestignores an incomingruntimeproperty instead of rejecting it, because it only reads the required fields and never checks for unknown or forbidden keys. A manifest containingruntimetherefore proceeds whenever itspages,files, andhashesotherwise match, contrary to the new protocol contract that no longer accepts or tolerates that field.Triggers: When a package is produced by a client that still emits
runtimebut does not include runtime modules infiles.Suggested fix: Reject manifests for which
Object.hasOwn(m, "runtime")is true before constructing the parsed manifest.