Skip to content

Commit edb194b

Browse files
jasnelltargos
authored andcommitted
src: prevent URLPattern property accessors from crashing on invalid this
PR-URL: #56877 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]>
1 parent 9624049 commit edb194b

File tree

2 files changed

+63
-9
lines changed

2 files changed

+63
-9
lines changed

src/node_url_pattern.cc

+23-9
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ using v8::Object;
2626
using v8::PropertyAttribute;
2727
using v8::ReadOnly;
2828
using v8::RegExp;
29+
using v8::Signature;
2930
using v8::String;
3031
using v8::Value;
3132

@@ -682,58 +683,71 @@ static void Initialize(Local<Object> target,
682683
auto prototype_template = ctor_tmpl->PrototypeTemplate();
683684
ctor_tmpl->SetClassName(FIXED_ONE_BYTE_STRING(isolate, "URLPattern"));
684685

686+
// The signature is used to prevent the property accessors from being
687+
// called on the wrong receiver object (`this`)
688+
auto signature = Signature::New(isolate, ctor_tmpl);
689+
685690
instance_template->SetInternalFieldCount(URLPattern::kInternalFieldCount);
686691
prototype_template->SetAccessorProperty(
687692
env->protocol_string(),
688-
FunctionTemplate::New(isolate, URLPattern::Protocol),
693+
FunctionTemplate::New(
694+
isolate, URLPattern::Protocol, Local<Value>(), signature),
689695
Local<FunctionTemplate>(),
690696
attributes);
691697

692698
prototype_template->SetAccessorProperty(
693699
env->username_string(),
694-
FunctionTemplate::New(isolate, URLPattern::Username),
700+
FunctionTemplate::New(
701+
isolate, URLPattern::Username, Local<Value>(), signature),
695702
Local<FunctionTemplate>(),
696703
attributes);
697704

698705
prototype_template->SetAccessorProperty(
699706
env->password_string(),
700-
FunctionTemplate::New(isolate, URLPattern::Password),
707+
FunctionTemplate::New(
708+
isolate, URLPattern::Password, Local<Value>(), signature),
701709
Local<FunctionTemplate>(),
702710
attributes);
703711

704712
prototype_template->SetAccessorProperty(
705713
env->hostname_string(),
706-
FunctionTemplate::New(isolate, URLPattern::Hostname),
714+
FunctionTemplate::New(
715+
isolate, URLPattern::Hostname, Local<Value>(), signature),
707716
Local<FunctionTemplate>(),
708717
attributes);
709718

710719
prototype_template->SetAccessorProperty(
711720
env->port_string(),
712-
FunctionTemplate::New(isolate, URLPattern::Port),
721+
FunctionTemplate::New(
722+
isolate, URLPattern::Port, Local<Value>(), signature),
713723
Local<FunctionTemplate>(),
714724
attributes);
715725

716726
prototype_template->SetAccessorProperty(
717727
env->pathname_string(),
718-
FunctionTemplate::New(isolate, URLPattern::Pathname),
728+
FunctionTemplate::New(
729+
isolate, URLPattern::Pathname, Local<Value>(), signature),
719730
Local<FunctionTemplate>(),
720731
attributes);
721732

722733
prototype_template->SetAccessorProperty(
723734
env->search_string(),
724-
FunctionTemplate::New(isolate, URLPattern::Search),
735+
FunctionTemplate::New(
736+
isolate, URLPattern::Search, Local<Value>(), signature),
725737
Local<FunctionTemplate>(),
726738
attributes);
727739

728740
prototype_template->SetAccessorProperty(
729741
env->hash_string(),
730-
FunctionTemplate::New(isolate, URLPattern::Hash),
742+
FunctionTemplate::New(
743+
isolate, URLPattern::Hash, Local<Value>(), signature),
731744
Local<FunctionTemplate>(),
732745
attributes);
733746

734747
prototype_template->SetAccessorProperty(
735748
env->has_regexp_groups_string(),
736-
FunctionTemplate::New(isolate, URLPattern::HasRegexpGroups),
749+
FunctionTemplate::New(
750+
isolate, URLPattern::HasRegexpGroups, Local<Value>(), signature),
737751
Local<FunctionTemplate>(),
738752
attributes);
739753

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict';
2+
3+
require('../common');
4+
5+
const { URLPattern } = require('url');
6+
const { throws } = require('assert');
7+
8+
const pattern = new URLPattern();
9+
const proto = Object.getPrototypeOf(pattern);
10+
11+
// Verifies that attempts to call the property getters on a URLPattern
12+
// with the incorrect `this` will not crash the process.
13+
[
14+
'protocol',
15+
'username',
16+
'password',
17+
'hostname',
18+
'port',
19+
'pathname',
20+
'search',
21+
'hash',
22+
'hasRegExpGroups',
23+
].forEach((i) => {
24+
const prop = Object.getOwnPropertyDescriptor(proto, i).get;
25+
throws(() => prop({}), {
26+
message: 'Illegal invocation',
27+
}, i);
28+
});
29+
30+
// Verifies that attempts to call the exec and test functions
31+
// with the wrong this also throw
32+
33+
const { test, exec } = pattern;
34+
35+
throws(() => test({}), {
36+
message: 'Illegal invocation',
37+
});
38+
throws(() => exec({}), {
39+
message: 'Illegal invocation',
40+
});

0 commit comments

Comments
 (0)