Skip to content

Commit d6fe916

Browse files
TimothyGuevanlucas
authored andcommitted
url: prioritize toString when stringifying
The ES addition operator calls the ToPrimitive() abstract operation without hint String, leading a subsequent OrdinaryToPrimitive() to call valueOf() first on an object rather than the desired toString(). Instead, use template literals which directly call ToString() abstract operation, per Web IDL spec. PR-URL: #12507 Fixes: b610a4d "url: enforce valid UTF-8 in WHATWG parser" Refs: b610a4d#commitcomment-21200056 Refs: https://tc39.github.io/ecma262/#sec-addition-operator-plus-runtime-semantics-evaluation Refs: https://tc39.github.io/ecma262/#sec-template-literals-runtime-semantics-evaluation Reviewed-By: James M Snell <[email protected]>
1 parent 7c9ca0f commit d6fe916

9 files changed

+45
-21
lines changed

‎lib/internal/url.js‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const IteratorPrototype = Object.getPrototypeOf(
2626
constunpairedSurrogateRe=
2727
/([^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])/;
2828
functiontoUSVString(val){
29-
conststr=''+val;
29+
conststr=`${val}`;
3030
// As of V8 5.5, `str.search()` (and `unpairedSurrogateRe[@@search]()`) are
3131
// slower than `unpairedSurrogateRe.exec()`.
3232
constmatch=unpairedSurrogateRe.exec(str);
@@ -215,7 +215,7 @@ function onParseHashComplete(flags, protocol, username, password,
215215
classURL{
216216
constructor(input,base){
217217
// toUSVString is not needed.
218-
input=''+input;
218+
input=`${input}`;
219219
if(base!==undefined&&!(baseinstanceofURL))
220220
base=newURL(base);
221221
parse(this,input,base);
@@ -326,7 +326,7 @@ Object.defineProperties(URL.prototype,{
326326
},
327327
set(input){
328328
// toUSVString is not needed.
329-
input=''+input;
329+
input=`${input}`;
330330
parse(this,input);
331331
}
332332
},
@@ -345,7 +345,7 @@ Object.defineProperties(URL.prototype,{
345345
},
346346
set(scheme){
347347
// toUSVString is not needed.
348-
scheme=''+scheme;
348+
scheme=`${scheme}`;
349349
if(scheme.length===0)
350350
return;
351351
binding.parse(scheme,binding.kSchemeStart,null,this[context],
@@ -360,7 +360,7 @@ Object.defineProperties(URL.prototype,{
360360
},
361361
set(username){
362362
// toUSVString is not needed.
363-
username=''+username;
363+
username=`${username}`;
364364
if(!this.hostname)
365365
return;
366366
constctx=this[context];
@@ -381,7 +381,7 @@ Object.defineProperties(URL.prototype,{
381381
},
382382
set(password){
383383
// toUSVString is not needed.
384-
password=''+password;
384+
password=`${password}`;
385385
if(!this.hostname)
386386
return;
387387
constctx=this[context];
@@ -407,7 +407,7 @@ Object.defineProperties(URL.prototype,{
407407
set(host){
408408
constctx=this[context];
409409
// toUSVString is not needed.
410-
host=''+host;
410+
host=`${host}`;
411411
if(this[cannotBeBase]||
412412
(this[special]&&host.length===0)){
413413
// Cannot set the host if cannot-be-base is set or
@@ -432,7 +432,7 @@ Object.defineProperties(URL.prototype,{
432432
set(host){
433433
constctx=this[context];
434434
// toUSVString is not needed.
435-
host=''+host;
435+
host=`${host}`;
436436
if(this[cannotBeBase]||
437437
(this[special]&&host.length===0)){
438438
// Cannot set the host if cannot-be-base is set or
@@ -457,7 +457,7 @@ Object.defineProperties(URL.prototype,{
457457
},
458458
set(port){
459459
// toUSVString is not needed.
460-
port=''+port;
460+
port=`${port}`;
461461
constctx=this[context];
462462
if(!ctx.host||this[cannotBeBase]||
463463
this.protocol==='file:')
@@ -481,7 +481,7 @@ Object.defineProperties(URL.prototype,{
481481
},
482482
set(path){
483483
// toUSVString is not needed.
484-
path=''+path;
484+
path=`${path}`;
485485
if(this[cannotBeBase])
486486
return;
487487
binding.parse(path,binding.kPathStart,null,this[context],
@@ -530,7 +530,7 @@ Object.defineProperties(URL.prototype,{
530530
set(hash){
531531
constctx=this[context];
532532
// toUSVString is not needed.
533-
hash=''+hash;
533+
hash=`${hash}`;
534534
if(this.protocol==='javascript:')
535535
return;
536536
if(!hash){
@@ -1122,12 +1122,12 @@ function originFor(url, base){
11221122

11231123
functiondomainToASCII(domain){
11241124
// toUSVString is not needed.
1125-
returnbinding.domainToASCII(''+domain);
1125+
returnbinding.domainToASCII(`${domain}`);
11261126
}
11271127

11281128
functiondomainToUnicode(domain){
11291129
// toUSVString is not needed.
1130-
returnbinding.domainToUnicode(''+domain);
1130+
returnbinding.domainToUnicode(`${domain}`);
11311131
}
11321132

11331133
// Utility function that converts a URL object into an ordinary

‎test/parallel/test-whatwg-url-searchparams-append.js‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ test(function(){
5858
params.set('a');
5959
},/^TypeError:"name"and"value"argumentsmustbespecified$/);
6060

61-
constobj={toString(){thrownewError('toString');}};
61+
constobj={
62+
toString(){thrownewError('toString');},
63+
valueOf(){thrownewError('valueOf');}
64+
};
6265
constsym=Symbol();
6366
assert.throws(()=>params.set(obj,'b'),/^Error:toString$/);
6467
assert.throws(()=>params.set('a',obj),/^Error:toString$/);

‎test/parallel/test-whatwg-url-searchparams-constructor.js‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,10 @@ test(() =>{
209209
}
210210

211211
{
212-
constobj={toString(){thrownewError('toString');}};
212+
constobj={
213+
toString(){thrownewError('toString');},
214+
valueOf(){thrownewError('valueOf');}
215+
};
213216
constsym=Symbol();
214217

215218
assert.throws(()=>newURLSearchParams({a: obj}),/^Error:toString$/);

‎test/parallel/test-whatwg-url-searchparams-delete.js‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ test(function(){
5252
params.delete();
5353
},/^TypeError:"name"argumentmustbespecified$/);
5454

55-
constobj={toString(){thrownewError('toString');}};
55+
constobj={
56+
toString(){thrownewError('toString');},
57+
valueOf(){thrownewError('valueOf');}
58+
};
5659
constsym=Symbol();
5760
assert.throws(()=>params.delete(obj),/^Error:toString$/);
5861
assert.throws(()=>params.delete(sym),

‎test/parallel/test-whatwg-url-searchparams-get.js‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ test(function(){
4343
params.get();
4444
},/^TypeError:"name"argumentmustbespecified$/);
4545

46-
constobj={toString(){thrownewError('toString');}};
46+
constobj={
47+
toString(){thrownewError('toString');},
48+
valueOf(){thrownewError('valueOf');}
49+
};
4750
constsym=Symbol();
4851
assert.throws(()=>params.get(obj),/^Error:toString$/);
4952
assert.throws(()=>params.get(sym),

‎test/parallel/test-whatwg-url-searchparams-getall.js‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ test(function(){
4747
params.getAll();
4848
},/^TypeError:"name"argumentmustbespecified$/);
4949

50-
constobj={toString(){thrownewError('toString');}};
50+
constobj={
51+
toString(){thrownewError('toString');},
52+
valueOf(){thrownewError('valueOf');}
53+
};
5154
constsym=Symbol();
5255
assert.throws(()=>params.getAll(obj),/^Error:toString$/);
5356
assert.throws(()=>params.getAll(sym),

‎test/parallel/test-whatwg-url-searchparams-has.js‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ test(function(){
4646
params.has();
4747
},/^TypeError:"name"argumentmustbespecified$/);
4848

49-
constobj={toString(){thrownewError('toString');}};
49+
constobj={
50+
toString(){thrownewError('toString');},
51+
valueOf(){thrownewError('valueOf');}
52+
};
5053
constsym=Symbol();
5154
assert.throws(()=>params.has(obj),/^Error:toString$/);
5255
assert.throws(()=>params.has(sym),

‎test/parallel/test-whatwg-url-searchparams-set.js‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ test(function(){
4444
params.set('a');
4545
},/^TypeError:"name"and"value"argumentsmustbespecified$/);
4646

47-
constobj={toString(){thrownewError('toString');}};
47+
constobj={
48+
toString(){thrownewError('toString');},
49+
valueOf(){thrownewError('valueOf');}
50+
};
4851
constsym=Symbol();
4952
assert.throws(()=>params.append(obj,'b'),/^Error:toString$/);
5053
assert.throws(()=>params.append('a',obj),/^Error:toString$/);

‎test/parallel/test-whatwg-url-setters.js‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,10 @@ startURLSettersTests()
107107

108108
{
109109
consturl=newURL('http://example.com/');
110-
constobj={toString(){thrownewError('toString');}};
110+
constobj={
111+
toString(){thrownewError('toString');},
112+
valueOf(){thrownewError('valueOf');}
113+
};
111114
constsym=Symbol();
112115
constprops=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(url));
113116
for(const[name,{ set }]ofObject.entries(props)){

0 commit comments

Comments
(0)