@tiangong-lca/pcr 0.4.7 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -526,13 +526,17 @@ function parseWithStatus (uri, opts) {
526
526
  malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP)
527
527
  }
528
528
 
529
- if (!schemeHandler || (schemeHandler && !schemeHandler.skipNormalize)) {
530
- if (uri.indexOf('%') !== -1) {
531
- if (parsed.host !== undefined && !malformedIPLiteral) {
532
- const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true)
533
- parsed.host = reescapeHostDelimiters(host, isIP)
534
- }
529
+ if (uri.indexOf('%') !== -1 && parsed.host !== undefined && !malformedIPLiteral) {
530
+ let host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true)
531
+ if (!isIP) {
532
+ // Fold reg-name case after decoding unreserved octets. The second
533
+ // pass only restores uppercase hex in escapes that remain encoded.
534
+ host = normalizePercentEncoding(host.toLowerCase())
535
535
  }
536
+ parsed.host = reescapeHostDelimiters(host, isIP)
537
+ }
538
+
539
+ if (!schemeHandler || (schemeHandler && !schemeHandler.skipNormalize)) {
536
540
  if (parsed.path) {
537
541
  parsed.path = normalizePathEncoding(parsed.path)
538
542
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fast-uri",
3
3
  "description": "Dependency-free RFC 3986 URI toolbox",
4
- "version": "3.1.7",
4
+ "version": "3.1.8",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
7
7
  "types": "types/index.d.ts",
@@ -126,6 +126,44 @@ test('hostname normalization decodes only current unreserved escapes', (t) => {
126
126
  t.end()
127
127
  })
128
128
 
129
+ test('scheme-relative hostname normalization folds decoded ASCII case', (t) => {
130
+ const encodedHost = '//%41.com'
131
+ const normalizedHost = fastURI.normalize(encodedHost)
132
+ const encodedMetadata = '//%4Detadata.internal/private'
133
+ const literalMetadata = '//metadata.internal/private'
134
+
135
+ t.equal(fastURI.parse(encodedHost).host, 'a.com', 'parse folds an encoded uppercase host letter')
136
+ t.equal(normalizedHost, '//a.com', 'normalize emits a lowercase host')
137
+ t.equal(fastURI.normalize(normalizedHost), normalizedHost, 'host normalization is idempotent')
138
+ t.equal(fastURI.equal(encodedHost, '//a.com'), true, 'encoded and literal host spellings compare equal')
139
+ t.equal(fastURI.equal(encodedMetadata, literalMetadata), true, 'encoded metadata host compares equal')
140
+ t.equal(
141
+ fastURI.resolve('x://trusted.example/', encodedMetadata),
142
+ fastURI.resolve('x://trusted.example/', literalMetadata),
143
+ 'encoded and literal metadata hosts resolve identically'
144
+ )
145
+ t.equal(
146
+ fastURI.normalize('//example.com%2fpath'),
147
+ '//example.com%2Fpath',
148
+ 'reserved host escapes remain encoded with uppercase hex'
149
+ )
150
+ t.equal(fastURI.normalize('//%2541.com'), '//%2541.com', 'nested host escapes are not decoded twice')
151
+ t.equal(fastURI.equal('//User@%41.com/path', '//user@a.com/path'), false, 'userinfo remains case-sensitive')
152
+ t.equal(fastURI.equal('//%41.com/Path', '//a.com/path'), false, 'path remains case-sensitive')
153
+ t.equal(fastURI.equal('//%41.com/?Token=Value', '//a.com/?token=value'), false, 'query remains case-sensitive')
154
+ t.end()
155
+ })
156
+
157
+ test('host normalization applies to schemes that skip path normalization', (t) => {
158
+ const encodedHost = 'mailto://%41.com'
159
+ const literalHost = 'mailto://a.com'
160
+
161
+ t.equal(fastURI.parse(encodedHost).host, fastURI.parse(literalHost).host, 'parse results have consistent hosts')
162
+ t.equal(fastURI.normalize(encodedHost), fastURI.normalize(literalHost), 'normalize results are consistent')
163
+ t.equal(fastURI.equal(encodedHost, literalHost), true, 'encoded and literal hosts compare equal')
164
+ t.end()
165
+ })
166
+
129
167
  test('host conversion failures are not treated as comparable URLs', (t) => {
130
168
  const malformedHost = 'http://trusted.test%2540evil.test/'
131
169
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiangong-lca/pcr",
3
- "version": "0.4.7",
3
+ "version": "0.4.8",
4
4
  "type": "module",
5
5
  "description": "Offline PCR consumer CLI and agent Skill",
6
6
  "license": "MIT",
@@ -37,7 +37,7 @@
37
37
  "type": "git",
38
38
  "url": "git+https://github.com/tiangong-lca/pcr.git"
39
39
  },
40
- "gitHead": "176c63d6b115f3116a2ceda7172833ef0f83f7df",
40
+ "gitHead": "6883ac60fba9106de1532c153241fb0076423a07",
41
41
  "publishConfig": {
42
42
  "access": "public",
43
43
  "registry": "https://registry.npmjs.org"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema": 1,
3
- "version": "0.4.7",
4
- "tag": "v0.4.7",
5
- "sourceCommit": "176c63d6b115f3116a2ceda7172833ef0f83f7df",
6
- "sourceFingerprint": "sha256:545e8d7b4641ad26e700b46a94ba828b18e51a6ef4daeae71cc8d1b485cbccfb"
3
+ "version": "0.4.8",
4
+ "tag": "v0.4.8",
5
+ "sourceCommit": "6883ac60fba9106de1532c153241fb0076423a07",
6
+ "sourceFingerprint": "sha256:af2d5b0e5c3248b4e01223a444e9c7a00268d062274141358a082a5d5ea94d68"
7
7
  }