Pārlūkot izejas kodu

LibWeb: Don't strip leading '?' in query initializing a URL

In our implementation of url-initialize, we were invoking the
constructor of URLSearchParams:

https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams

Instead of the 'initialize' AO:

https://url.spec.whatwg.org/#urlsearchparams-initialize

This has the small difference of stripping any leading '?' from the
query (which we are not meant to be doing!).
Shannon Booth 11 mēneši atpakaļ
vecāks
revīzija
fd4e943e12

+ 22 - 0
Tests/LibWeb/Text/expected/URL/url.txt

@@ -152,6 +152,17 @@ pathname => '/test'
 search => '?test'
 searchParams => 'test='
 hash => ''
+new URL('??a=b&c=d', 'http://example.org/foo/bar')
+protocol => 'http:'
+username => ''
+password => ''
+host => 'example.org'
+hostname => 'example.org'
+port => ''
+pathname => '/foo/bar'
+search => '??a=b&c=d'
+searchParams => '%3Fa=b&c=d'
+hash => ''
 =========================================
 URL.parse('ftp://serenityos.org:21', undefined)
 protocol => 'ftp:'
@@ -307,3 +318,14 @@ pathname => '/test'
 search => '?test'
 searchParams => 'test='
 hash => ''
+URL.parse('??a=b&c=d', 'http://example.org/foo/bar')
+protocol => 'http:'
+username => ''
+password => ''
+host => 'example.org'
+hostname => 'example.org'
+port => ''
+pathname => '/foo/bar'
+search => '??a=b&c=d'
+searchParams => '%3Fa=b&c=d'
+hash => ''

+ 1 - 0
Tests/LibWeb/Text/input/URL/url.html

@@ -36,6 +36,7 @@
             { input: '  \t', base: 'http://ladybird.org/foo/bar' },
             { input: '/c:/foo/bar', base: 'file:///c:/baz/qux' },
             { input: '', base: 'file:///test?test#test' },
+            { input: '??a=b&c=d', base: 'http://example.org/foo/bar' },
         ];
 
         for (url of urls) {

+ 1 - 1
Userland/Libraries/LibWeb/DOMURL/DOMURL.cpp

@@ -59,7 +59,7 @@ JS::NonnullGCPtr<DOMURL> DOMURL::initialize_a_url(JS::Realm& realm, URL::URL con
 
     // 2. Set url’s URL to urlRecord.
     // 3. Set url’s query object to a new URLSearchParams object.
-    auto query_object = MUST(URLSearchParams::construct_impl(realm, query));
+    auto query_object = MUST(URLSearchParams::create(realm, query));
 
     // 4. Initialize url’s query object with query.
     auto result_url = DOMURL::create(realm, url_record, move(query_object));

+ 9 - 1
Userland/Libraries/LibWeb/DOMURL/URLSearchParams.cpp

@@ -124,6 +124,14 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<URLSearchParams>> URLSearchParams::create(J
     return realm.heap().allocate<URLSearchParams>(realm, realm, move(list));
 }
 
+// https://url.spec.whatwg.org/#urlsearchparams-initialize
+WebIDL::ExceptionOr<JS::NonnullGCPtr<URLSearchParams>> URLSearchParams::create(JS::Realm& realm, StringView init)
+{
+    // NOTE: We skip the other steps since we know it is a string at this point.
+    // b. Set query’s list to the result of parsing init.
+    return URLSearchParams::create(realm, MUST(url_decode(init)));
+}
+
 // https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams
 // https://url.spec.whatwg.org/#urlsearchparams-initialize
 WebIDL::ExceptionOr<JS::NonnullGCPtr<URLSearchParams>> URLSearchParams::construct_impl(JS::Realm& realm, Variant<Vector<Vector<String>>, OrderedHashMap<String, String>, String> const& init)
@@ -179,7 +187,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<URLSearchParams>> URLSearchParams::construc
     auto stripped_init = init_string_view.substring_view(init_string_view.starts_with('?'));
 
     // b. Set query’s list to the result of parsing init.
-    return URLSearchParams::create(realm, TRY_OR_THROW_OOM(vm, url_decode(stripped_init)));
+    return URLSearchParams::create(realm, stripped_init);
 }
 
 // https://url.spec.whatwg.org/#dom-urlsearchparams-size

+ 1 - 0
Userland/Libraries/LibWeb/DOMURL/URLSearchParams.h

@@ -24,6 +24,7 @@ class URLSearchParams : public Bindings::PlatformObject {
     JS_DECLARE_ALLOCATOR(URLSearchParams);
 
 public:
+    static WebIDL::ExceptionOr<JS::NonnullGCPtr<URLSearchParams>> create(JS::Realm&, StringView);
     static WebIDL::ExceptionOr<JS::NonnullGCPtr<URLSearchParams>> create(JS::Realm&, Vector<QueryParam> list);
     static WebIDL::ExceptionOr<JS::NonnullGCPtr<URLSearchParams>> construct_impl(JS::Realm&, Variant<Vector<Vector<String>>, OrderedHashMap<String, String>, String> const& init);