Skip to content

Commit 6e13a7b

Browse files
aduh95anonrig
authored andcommitted
http: remove prototype primordials
Co-authored-by: Yagiz Nizipli <yagiz@nizipli.com> PR-URL: #53698 Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io> Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
1 parent 99f96eb commit 6e13a7b

9 files changed

Lines changed: 60 additions & 96 deletions

File tree

‎doc/contributing/primordials.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ later look these up from the global proxy, which can be mutated by users.
77
For some area of the codebase, performance and code readability are deemed more
88
important than reliability against prototype pollution:
99

10+
*`node:http`
1011
*`node:http2`
1112

1213
Usage of primordials should be preferred for new code in other areas, but

‎lib/_http_agent.js‎

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,10 @@
2222
'use strict';
2323

2424
const{
25-
ArrayPrototypeIncludes,
26-
ArrayPrototypeIndexOf,
27-
ArrayPrototypePop,
28-
ArrayPrototypePush,
29-
ArrayPrototypeShift,
30-
ArrayPrototypeSome,
31-
ArrayPrototypeSplice,
32-
FunctionPrototypeCall,
3325
NumberParseInt,
3426
ObjectKeys,
3527
ObjectSetPrototypeOf,
3628
ObjectValues,
37-
RegExpPrototypeExec,
38-
StringPrototypeIndexOf,
39-
StringPrototypeSplit,
40-
StringPrototypeStartsWith,
41-
StringPrototypeSubstring,
4229
Symbol,
4330
}=primordials;
4431

@@ -92,7 +79,7 @@ function Agent(options) {
9279
if(!(thisinstanceofAgent))
9380
returnnewAgent(options);
9481

95-
FunctionPrototypeCall(EventEmitter,this);
82+
EventEmitter.call(this);
9683

9784
this.defaultPort=80;
9885
this.protocol='http:';
@@ -139,7 +126,7 @@ function Agent(options) {
139126

140127
constrequests=this.requests[name];
141128
if(requests&&requests.length){
142-
constreq=ArrayPrototypeShift(requests);
129+
constreq=requests.shift();
143130
constreqAsyncRes=req[kRequestAsyncResource];
144131
if(reqAsyncRes){
145132
// Run request within the original async context.
@@ -185,7 +172,7 @@ function Agent(options) {
185172
this.removeSocket(socket,options);
186173

187174
socket.once('error',freeSocketErrorListener);
188-
ArrayPrototypePush(freeSockets,socket);
175+
freeSockets.push(socket);
189176
});
190177

191178
// Don't emit keylog events unless there is a listener for them.
@@ -264,11 +251,11 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
264251
letsocket;
265252
if(freeSockets){
266253
while(freeSockets.length&&freeSockets[0].destroyed){
267-
ArrayPrototypeShift(freeSockets);
254+
freeSockets.shift();
268255
}
269256
socket=this.scheduling==='fifo' ?
270-
ArrayPrototypeShift(freeSockets) :
271-
ArrayPrototypePop(freeSockets);
257+
freeSockets.shift() :
258+
freeSockets.pop();
272259
if(!freeSockets.length)
273260
deletethis.freeSockets[name];
274261
}
@@ -280,7 +267,7 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
280267
asyncResetHandle(socket);
281268
this.reuseSocket(socket,req);
282269
setRequestSocket(this,req,socket);
283-
ArrayPrototypePush(this.sockets[name],socket);
270+
this.sockets[name].push(socket);
284271
}elseif(sockLen<this.maxSockets&&
285272
this.totalSocketCount<this.maxTotalSockets){
286273
debug('call onSocket',sockLen,freeLen);
@@ -303,7 +290,7 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
303290
// Used to capture the original async context.
304291
req[kRequestAsyncResource]=newAsyncResource('QueuedRequest');
305292

306-
ArrayPrototypePush(this.requests[name],req);
293+
this.requests[name].push(req);
307294
}
308295
};
309296

@@ -326,7 +313,7 @@ Agent.prototype.createSocket = function createSocket(req, options, cb) {
326313
if(!this.sockets[name]){
327314
this.sockets[name]=[];
328315
}
329-
ArrayPrototypePush(this.sockets[name],s);
316+
this.sockets[name].push(s);
330317
this.totalSocketCount++;
331318
debug('sockets',name,this.sockets[name].length,this.totalSocketCount);
332319
installListeners(this,s,options);
@@ -357,16 +344,16 @@ function calculateServerName(options, req) {
357344
// abc:123 => abc
358345
// [::1] => ::1
359346
// [::1]:123 => ::1
360-
if(StringPrototypeStartsWith(hostHeader,'[')){
361-
constindex=StringPrototypeIndexOf(hostHeader,']');
347+
if(hostHeader.startsWith('[')){
348+
constindex=hostHeader.indexOf(']');
362349
if(index===-1){
363350
// Leading '[', but no ']'. Need to do something...
364351
servername=hostHeader;
365352
}else{
366-
servername=StringPrototypeSubstring(hostHeader,1,index);
353+
servername=hostHeader.substring(1,index);
367354
}
368355
}else{
369-
servername=StringPrototypeSplit(hostHeader,':',1)[0];
356+
servername=hostHeader.split(':',1)[0];
370357
}
371358
}
372359
// Don't implicitly set invalid (IP) servernames.
@@ -398,9 +385,7 @@ function installListeners(agent, s, options) {
398385
// Destroy if in free list.
399386
// TODO(ronag): Always destroy, even if not in free list.
400387
constsockets=agent.freeSockets;
401-
if(ArrayPrototypeSome(ObjectKeys(sockets),(name)=>
402-
ArrayPrototypeIncludes(sockets[name],s),
403-
)){
388+
if(ObjectKeys(sockets).some((name)=>sockets[name].includes(s))){
404389
returns.destroy();
405390
}
406391
}
@@ -432,15 +417,15 @@ Agent.prototype.removeSocket = function removeSocket(s, options) {
432417

433418
// If the socket was destroyed, remove it from the free buffers too.
434419
if(!s.writable)
435-
ArrayPrototypePush(sets,this.freeSockets);
420+
sets.push(this.freeSockets);
436421

437422
for(letsk=0;sk<sets.length;sk++){
438423
constsockets=sets[sk];
439424

440425
if(sockets[name]){
441-
constindex=ArrayPrototypeIndexOf(sockets[name],s);
426+
constindex=sockets[name].indexOf(s);
442427
if(index!==-1){
443-
ArrayPrototypeSplice(sockets[name],index,1);
428+
sockets[name].splice(index,1);
444429
// Don't leak
445430
if(sockets[name].length===0)
446431
deletesockets[name];
@@ -493,7 +478,7 @@ Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) {
493478
constkeepAliveHint=socket._httpMessage.res.headers['keep-alive'];
494479

495480
if(keepAliveHint){
496-
consthint=RegExpPrototypeExec(/^timeout=(\d+)/,keepAliveHint)?.[1];
481+
consthint=/^timeout=(\d+)/.exec(keepAliveHint)?.[1];
497482

498483
if(hint){
499484
constserverHintTimeout=NumberParseInt(hint)*1000;

‎lib/_http_client.js‎

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,13 @@ const {
2525
ArrayIsArray,
2626
Boolean,
2727
Error,
28-
FunctionPrototypeCall,
2928
NumberIsFinite,
3029
ObjectAssign,
3130
ObjectKeys,
3231
ObjectSetPrototypeOf,
3332
ReflectApply,
34-
RegExpPrototypeExec,
3533
String,
36-
StringPrototypeCharCodeAt,
37-
StringPrototypeIncludes,
38-
StringPrototypeIndexOf,
39-
StringPrototypeToUpperCase,
4034
Symbol,
41-
TypedArrayPrototypeSlice,
4235
}=primordials;
4336

4437
constnet=require('net');
@@ -139,7 +132,7 @@ class HTTPClientAsyncResource {
139132
}
140133

141134
functionClientRequest(input,options,cb){
142-
FunctionPrototypeCall(OutgoingMessage,this);
135+
OutgoingMessage.call(this);
143136

144137
if(typeofinput==='string'){
145138
consturlStr=input;
@@ -184,7 +177,7 @@ function ClientRequest(input, options, cb) {
184177

185178
if(options.path){
186179
constpath=String(options.path);
187-
if(RegExpPrototypeExec(INVALID_PATH_REGEX,path)!==null){
180+
if(INVALID_PATH_REGEX.test(path)){
188181
debug('Path contains unescaped characters: "%s"',path);
189182
thrownewERR_UNESCAPED_CHARACTERS('Request path');
190183
}
@@ -225,7 +218,7 @@ function ClientRequest(input, options, cb) {
225218
if(!checkIsHttpToken(method)){
226219
thrownewERR_INVALID_HTTP_TOKEN('Method',method);
227220
}
228-
method=this.method=StringPrototypeToUpperCase(method);
221+
method=this.method=method.toUpperCase();
229222
}else{
230223
method=this.method='GET';
231224
}
@@ -307,10 +300,10 @@ function ClientRequest(input, options, cb) {
307300
// For the Host header, ensure that IPv6 addresses are enclosed
308301
// in square brackets, as defined by URI formatting
309302
// https://tools.ietf.org/html/rfc3986#section-3.2.2
310-
constposColon=StringPrototypeIndexOf(hostHeader,':');
303+
constposColon=hostHeader.indexOf(':');
311304
if(posColon!==-1&&
312-
StringPrototypeIncludes(hostHeader,':',posColon+1)&&
313-
StringPrototypeCharCodeAt(hostHeader,0)!==91/* '[' */){
305+
hostHeader.includes(':',posColon+1)&&
306+
hostHeader.charCodeAt(0)!==91/* '[' */){
314307
hostHeader=`[${hostHeader}]`;
315308
}
316309

@@ -383,7 +376,7 @@ ObjectSetPrototypeOf(ClientRequest.prototype, OutgoingMessage.prototype);
383376
ObjectSetPrototypeOf(ClientRequest,OutgoingMessage);
384377

385378
ClientRequest.prototype._finish=function_finish(){
386-
FunctionPrototypeCall(OutgoingMessage.prototype._finish,this);
379+
OutgoingMessage.prototype._finish.call(this);
387380
if(hasObserver('http')){
388381
startPerf(this,kClientRequestStatistics,{
389382
type: 'http',
@@ -574,7 +567,7 @@ function socketOnData(d) {
574567
parser.finish();
575568
freeParser(parser,req,socket);
576569

577-
constbodyHead=TypedArrayPrototypeSlice(d,bytesParsed,d.length);
570+
constbodyHead=d.slice(bytesParsed,d.length);
578571

579572
consteventName=req.method==='CONNECT' ? 'connect' : 'upgrade';
580573
if(req.listenerCount(eventName)>0){

‎lib/_http_common.js‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
const{
2525
MathMin,
2626
Symbol,
27-
RegExpPrototypeExec,
2827
}=primordials;
2928
const{ setImmediate }=require('timers');
3029

@@ -210,7 +209,7 @@ const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/;
210209
* See https://tools.ietf.org/html/rfc7230#section-3.2.6
211210
*/
212211
functioncheckIsHttpToken(val){
213-
returnRegExpPrototypeExec(tokenRegExp,val)!==null;
212+
returntokenRegExp.test(val);
214213
}
215214

216215
constheaderCharRegex=/[^\t\x20-\x7e\x80-\xff]/;
@@ -221,7 +220,7 @@ const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
221220
* field-vchar = VCHAR / obs-text
222221
*/
223222
functioncheckInvalidHeaderChar(val){
224-
returnRegExpPrototypeExec(headerCharRegex,val)!==null;
223+
returnheaderCharRegex.test(val);
225224
}
226225

227226
functioncleanParser(parser){

‎lib/_http_incoming.js‎

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
const{
2525
ObjectDefineProperty,
2626
ObjectSetPrototypeOf,
27-
StringPrototypeCharCodeAt,
28-
StringPrototypeSlice,
29-
StringPrototypeToLowerCase,
3027
Symbol,
3128
}=primordials;
3229

@@ -370,7 +367,7 @@ function matchKnownFields(field, lowercased) {
370367
if(lowercased){
371368
return'\u0000'+field;
372369
}
373-
returnmatchKnownFields(StringPrototypeToLowerCase(field),true);
370+
returnmatchKnownFields(field.toLowerCase(),true);
374371
}
375372
// Add the given (field, value) pair to the message
376373
//
@@ -384,9 +381,9 @@ function matchKnownFields(field, lowercased) {
384381
IncomingMessage.prototype._addHeaderLine=_addHeaderLine;
385382
function_addHeaderLine(field,value,dest){
386383
field=matchKnownFields(field);
387-
constflag=StringPrototypeCharCodeAt(field,0);
384+
constflag=field.charCodeAt(0);
388385
if(flag===0||flag===2){
389-
field=StringPrototypeSlice(field,1);
386+
field=field.slice(1);
390387
// Make a delimited list
391388
if(typeofdest[field]==='string'){
392389
dest[field]+=(flag===0 ? ', ' : '; ')+value;
@@ -418,7 +415,7 @@ function _addHeaderLine(field, value, dest) {
418415

419416
IncomingMessage.prototype._addHeaderLineDistinct=_addHeaderLineDistinct;
420417
function_addHeaderLineDistinct(field,value,dest){
421-
field=StringPrototypeToLowerCase(field);
418+
field=field.toLowerCase();
422419
if(!dest[field]){
423420
dest[field]=[value];
424421
}else{

0 commit comments

Comments
 (0)