fix: scope the value ceiling to the names a template references
Addresses Copilot's round-19 review on #2035 -- a divergence introduced by
my own round-14 guard rather than by the original code.
The SDK validated a value inside `encodeValue`, i.e. only after looking one
up by a DECLARED name. The restored guard checked the caller's whole map, so
an unrelated entry failed a template that never mentions it. Measured on
9caac43d:
tryExpandUriTemplate("x://{id}", { id: "7", stale: "a".repeat(1_000_001) })
=> error: The value for "stale" exceeds the 1000000-character limit
RFC 6570 ignores an extra variable, so this refused a perfectly valid read.
`valueLengthError` now takes the names to consider and both callers pass the
template's declared set.
Copilot's second half is worth taking on its own: strict expansion parsed
the template THREE times -- inside `templateError`, again for the name list,
again to expand -- and the template is server-controlled and may be 1 MB.
It is now parsed once and reused, with validation split into
`sdkTemplateError` (the constructor's unclosed-brace and length/count
limits) and `partsError` (this module's own grammar), so `templateError` and
strict expansion share both halves rather than duplicating either.
npm run ci passes.
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
9caac43da4
commit
7bcf155e06
1 changed files with 91 additions and 14 deletions
|
|
@ -880,6 +880,27 @@ describe("the per-value length ceiling", () => {
|
|||
);
|
||||
});
|
||||
|
||||
it("ignores an oversized value the template never references", () => {
|
||||
// RFC 6570 ignores an extra variable, and the SDK path this replaced
|
||||
// validated a value only after looking one up by declared name -- so
|
||||
// checking the whole map refused `x://{id}` over a stale key beside it.
|
||||
expect(
|
||||
tryExpandUriTemplate("x://{id}", {
|
||||
id: "7",
|
||||
stale: "a".repeat(1_000_001),
|
||||
}).uri,
|
||||
).toBe("x://7");
|
||||
});
|
||||
|
||||
it("scopes valueLengthError to the names it is given", () => {
|
||||
const values = { id: "7", stale: "a".repeat(1_000_001) };
|
||||
expect(valueLengthError(values, ["id"])).toBeNull();
|
||||
expect(valueLengthError(values, ["id", "stale"])).not.toBeNull();
|
||||
// Unscoped, every entry is examined -- the behavior the preview and the
|
||||
// read both moved off.
|
||||
expect(valueLengthError(values)).not.toBeNull();
|
||||
});
|
||||
|
||||
it("names the offending variable", () => {
|
||||
expect(
|
||||
tryExpandUriTemplate("x://{a}/{b}", { a: "1", b: "b".repeat(1_000_001) })
|
||||
|
|
|
|||
Loading…
Reference in a new issue