fix(javascript): bound primitive string growth and repeated evaluation

This commit is contained in:
morluto
2026-10-09 00:40:22 +08:00
parent 770d2f60aa
commit 4a1837d9d5
10 changed files with 298 additions and 25 deletions
@@ -9,6 +9,7 @@ import { semanticPrimitiveKey } from "./javascriptSemanticProvenance.js";
import { readExactJavaScriptLiteral } from "./javascriptAstValues.js";
import {
SEMANTIC_PRIMITIVE_CANDIDATE_LIMIT,
exceedsSemanticPrimitiveStringByteBudget,
semanticResourceLimitUnknown,
} from "./javascriptSemanticResourceLimits.js";
@@ -23,20 +24,29 @@ export const MAX_SEMANTIC_PRIMITIVE_CANDIDATES =
export const semanticPrimitiveSet = (
values: readonly JavaScriptSemanticPrimitive[],
): JavaScriptSemanticValue => {
const byKey = new Map<string, JavaScriptSemanticPrimitive>();
const uniqueValues = new Set<JavaScriptSemanticPrimitive>();
for (const value of values) {
if (typeof value === "number" && !Number.isFinite(value))
return {
status: "unknown",
reason: "Nonfinite numbers are outside the JSON primitive lattice.",
};
byKey.set(semanticPrimitiveKey(value), value);
if (byKey.size > MAX_SEMANTIC_PRIMITIVE_CANDIDATES)
uniqueValues.add(value);
if (uniqueValues.size > MAX_SEMANTIC_PRIMITIVE_CANDIDATES)
return semanticResourceLimitUnknown("primitive-candidates");
}
const unique = [...byKey.values()].sort((left, right) =>
compareCodePoints(semanticPrimitiveKey(left), semanticPrimitiveKey(right)),
);
if (
exceedsSemanticPrimitiveStringByteBudget(
[...uniqueValues].flatMap((value) =>
typeof value === "string" ? [value] : [],
),
)
)
return semanticResourceLimitUnknown("primitive-bytes");
const unique = [...uniqueValues]
.map((value) => ({ key: semanticPrimitiveKey(value), value }))
.sort((left, right) => compareCodePoints(left.key, right.key))
.map(({ value }) => value);
const only = unique[0];
return unique.length === 1 && only !== undefined
? { status: "literal", value: only }