Skip to content

Reject string types in choice() and wrapped() when varName is omitted - #325

Merged
keichi merged 1 commit into
masterfrom
fix-choice-wrapped-overwrite-vars
Oct 18, 2026
Merged

keichi merged 1 commit into
masterfrom
fix-choice-wrapped-overwrite-vars

Conversation

@keichi

@keichi keichi commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Problem

When choice() or wrapped() is called without a variable name and the type is a string (an alias registered with namely(), or a primitive type for choice), the generated code assigns the result to vars itself, discarding all previously parsed fields.

Repro

Parser.start().uint8("v").namely("A1");
new Parser().uint8("x").uint8("tag")
  .choice({ tag: "tag", choices: { 1: "A1" } })
  .parse(Buffer.from([9, 1, 7]));
// => { v: 7 }   (x and tag are lost)
// with choices { 1: "uint8" } the result is just the number 7

Same with wrapped({ length: 1, wrapper: (b) => b, type: "A1" }).

Fix

Add build-time validation equivalent to the one nest() already has ("type must be a Parser object if the variable name is omitted."):

  • wrapped(): throw if type is not a Parser object and varName is omitted.
  • choice(): throw if any choice or defaultChoice is a string and varName is omitted.

Validation was chosen over merging with Object.assign because it matches nest()'s existing behavior, and merging cannot work for primitive choices (a number cannot be merged into vars). Regression tests added in test/composite_parser.ts.

@keichi
keichi merged commit cd62b6d into master Oct 18, 2026
8 checks passed
@keichi
keichi deleted the fix-choice-wrapped-overwrite-vars branch October 18, 2026 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant