Skip to content

fix: do not expand empty list or associative array under key operators#85

Open
spokodev wants to merge 1 commit into
bramstein:mainfrom
spokodev:fix-empty-collection-key-operator
Open

fix: do not expand empty list or associative array under key operators#85
spokodev wants to merge 1 commit into
bramstein:mainfrom
spokodev:fix-empty-collection-key-operator

Conversation

@spokodev

Copy link
Copy Markdown

Problem

An empty list or empty associative array expanded under a key operator (?, &, ;) emits a spurious name= pair:

parseTemplate('{?list}').expand({ list: [] });   // "?list="   expected ""
parseTemplate('{&list}').expand({ list: [] });   // "&list="   expected ""
parseTemplate('{;list}').expand({ list: [] });   // ";list="   expected ""
parseTemplate('{?o}').expand({ o: {} });         // "?o="      expected ""

RFC 6570 §2.3: "A variable defined as a list value is considered undefined if the list contains zero members" (likewise an associative array with zero members). An undefined value contributes nothing to an expansion, so the result must be the empty string.

An empty string is different — it is defined — and must still expand to name= per §3.2.8. That case is unaffected.

Cause

In getValues, the non-key branch already guarded with tmp.length !== 0, but the key-operator branch pushed key= unconditionally. For a zero-member collection tmp is empty, so the guard belongs on both branches.

Fix

if (tmp.length !== 0) {
  if (isKeyOperator(operator)) {
    result.push(encodeUnreserved(key) + '=' + tmp.join(','));
  } else {
    result.push(tmp.join(','));
  }
}

Verification

  • The vendored official RFC 6570 suite's "Empty Variables" cases (extended-tests.json) now pass; spec-examples-by-section.json stays at 117/117 and spec-examples.json at 64/64 — zero regression.
  • Two existing assertions in test/url-template-test.js that encoded the old behavior ({?emptylist}?emptylist=, {?emptyobject}?emptyobject=) are corrected to '', alongside new &/; cases. Note these contradicted the same file's own {?emptylist*}'' assertion.

RFC 6570 section 2.3 defines a list or associative array with zero members
as undefined, so an undefined value contributes nothing to an expansion.
The key operators (?, &, ;) emitted a "name=" pair for an empty collection
anyway:

  parseTemplate('{?list}').expand({ list: [] }); // was "?list=", now ""

The non-key branch already guarded on `tmp.length`; the key branch did not.
Guard both. An empty string value stays defined and still expands to
"name=", matching RFC 6570 section 3.2.8.

The official RFC 6570 test suite's "Empty Variables" cases now pass; two
unit-test assertions that encoded the old behavior are corrected.
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