Skip to content

Fix double encoding of URI template parameter names for list/associative-array values - #5280

Open
iscai-msft wants to merge 3 commits into
Azure:mainfrom
iscai-msft:iscai-msft-double-url-encoding-repro
Open

Fix double encoding of URI template parameter names for list/associative-array values#5280
iscai-msft wants to merge 3 commits into
Azure:mainfrom
iscai-msft:iscai-msft-double-url-encoding-repro

Conversation

@iscai-msft

Copy link
Copy Markdown
Member

Summary

Fixes #5278

Query parameter names are pre-encoded by the emitter (e.g. $Select%24Select) before being passed as URI template variable names. The scalar-value expansion path in expandUrlTemplate already accounted for this and skipped re-encoding the variable name, but the array-expansion path (getExpandedValue) and the associative-array/list path (getNonExpandedValue) still called encodeURIComponent/encodeComponent on varName, causing it to be encoded twice (e.g. %24Select becoming %2524Select).

Fix

Removed the redundant re-encoding of varName in both getExpandedValue and getNonExpandedValue in packages/typespec-ts/static/static-helpers/urlTemplate.ts, matching the existing (correct) behavior of the scalar-value path.

Testing

Added repro tests in packages/typespec-ts/test/modular-unit/static/url-template.test.ts covering scalar, list, and associative-array query parameter values with a pre-encoded parameter name (%24Select). Verified the new list/associative-array tests fail on main with the exact reported symptom (%2524Select) and pass with this fix. All 67 tests in the file pass.

Also ran pnpm lint on the touched package (clean).

iscai-msft and others added 3 commits April 30, 2025 16:17
…ive-array values

The scalar-value path in expandUrlTemplate already preserved a pre-encoded
variable name, but the array/list path (getExpandedValue) and the
non-expanded/associative-array path (getNonExpandedValue) still called
encodeComponent/encodeURIComponent on varName, causing double encoding
(e.g. "%24Select" becoming "%2524Select").

Fixes Azure#5278

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

📦 Package size report

✅ No notable package size changes compared to the base branch.

13 package(s) with no notable change
Package Packed (base → head) Δ Packed Unpacked (base → head) Δ Unpacked
@azure-tools/typespec-java 13.51 MB → 13.51 MB +148 B (+0.0%) 15.03 MB → 15.03 MB
@azure-tools/typespec-ts 527.17 KB → 527.16 KB -7 B (-0.0%) 2.54 MB → 2.54 MB +87 B (+0.0%)
@azure-tools/azure-http-specs 146.63 KB → 146.63 KB 1.16 MB → 1.16 MB
@azure-tools/typespec-autorest 80.93 KB → 80.93 KB 395.06 KB → 395.06 KB
@azure-tools/typespec-autorest-canonical 7.42 KB → 7.42 KB 26.00 KB → 26.00 KB
@azure-tools/typespec-azure-core 129.43 KB → 129.43 KB 702.77 KB → 702.77 KB
@azure-tools/typespec-azure-portal-core 42.40 KB → 42.40 KB 192.91 KB → 192.91 KB
@azure-tools/typespec-azure-resource-manager 171.92 KB → 171.92 KB 1.04 MB → 1.04 MB
@azure-tools/typespec-azure-rulesets 5.16 KB → 5.16 KB 32.09 KB → 32.09 KB
@azure-tools/typespec-client-generator-core 229.25 KB → 229.25 KB 1.23 MB → 1.23 MB
@azure-tools/typespec-go 258.44 KB → 258.44 KB 1.32 MB → 1.32 MB
@azure-tools/typespec-metadata 15.91 KB → 15.91 KB 62.26 KB → 62.26 KB
@azure-tools/typespec-python 42.22 KB → 42.22 KB 164.91 KB → 164.91 KB

Packed = gzipped .tgz published to npm. Unpacked = total extracted size. 🆕 added, 🗑️ removed. Packages from the core/ submodule are not included.
🔴 grew · 🟢 shrank — only changes of at least 512 B and 0.5% are marked.

@azure-sdk-automation

Copy link
Copy Markdown
Contributor

You can try these changes here

🛝 Playground 🌐 Website

@maorleger Maor Leger (maorleger) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix LGTM but I'd love to get confirmation from the emitter folks

Thanks for putting that together!

});
assert("{?%24Select*}", "?name=value");
assert("{?%24Select}", "?%24Select=name,value");
});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth adding a test that combines encoded name with values requiring encoding?

Example (I think):

const assert = createAssertion({
  "%24Select": ["a b", "x=y", "*"],
});
assert(
  "{?%24Select*}",
  "?%24Select=a%20b&%24Select=x%3Dy&%24Select=%2A",
);

Or something similar? just a test that shows that we continue to encode the values even when preserving the already-encoded name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:typescript Issues for @azure-tools/typespec-ts emitter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Double encoding of URL Template parameters in JS

2 participants