mirror of
https://github.com/morluto/rea
synced 2026-10-26 14:25:49 -04:00
fix(javascript): bound primitive string growth and repeated evaluation
This commit is contained in:
@@ -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 }
|
||||
|
||||
Reference in New Issue
Block a user