Commit graph

78 commits

Author SHA1 Message Date
Tim Ledbetter
2a1fc96650 AK: Avoid unnecessary String allocations for URL username and password
Previously, `URLParser` was constructing a new String for every
character of the URL's username and password. This change improves
performance by eliminating those unnecessary String allocations.

A URL with a 100,000 character password can now be parsed in ~30ms vs
~8 seconds previously on my machine.
2023-11-06 09:19:12 +01:00
Shannon Booth
3748f1d290 AK: Check for overflow parsing IPv4 number in URL
Fixes OSS fuzz issue:
https://oss-fuzz.com/download?testcase_id=6045676088459264
2023-10-26 11:11:41 +02:00
Shannon Booth
453dd0cf44 AK: Properly implement steps for shortening a URLs path
Instead of implementing this inline, put it into a function. Use this
new function to correctly implement shortening paths for some places
where this logic was previously missing.

Before these changes, the pathname for the included test was incorrectly
being set to '/' as we were not considering the windows drive letter.
2023-10-26 11:11:41 +02:00
Shannon Booth
bfdf7779ce AK: Correctly set host when parsing URL with a base file:// host
We were completely missing this spec step here. Also leave a FIXME for
the pre-existing implementation of this step, as this doesn't match the
spec.
2023-10-26 11:11:41 +02:00
Shannon Booth
ef27750982 AK: Port URL m_paths to String 2023-10-26 11:11:41 +02:00
Kemal Zebari
369f1d72ba AK/URLParser: Add spec comments to parse_opaque_host() 2023-10-20 12:20:55 -06:00
Kemal Zebari
2d27998f28 AK/URLParser: Complete is_url_code_point() implementation 2023-10-20 12:20:55 -06:00
Kemal Zebari
001abbcd66 AK: Rename URLParser:parse_host() param is_not_special to is_opaque
Since the spec renamed it to make it easier to read.
2023-10-01 14:35:40 +02:00
Shannon Booth
50d8ef94ba AK: Port percent_encode_after_encoding to String 2023-08-31 11:02:18 +02:00
Shannon Booth
cb4c279e90 AK: Percent encode URL fragments when parsed
This fixes URL fragments containing characters in the fragment encoding
set that were not being correctly percent encoded.
2023-08-31 11:02:18 +02:00
Shannon Booth
e233de1e48 AK: Report validation error for URLs with invalid percent encodings
This part of the spec is mostly useful for our debugging for now, but
could eventually be hooked up so that the user can see any reported
validation errors.
2023-08-31 11:02:18 +02:00
Shannon Booth
f53dfdd6ac AK: Write scheme state of URL parsing closer to spec steps
The main change here is that we now follow the spec by asserting the URL
is not special. Previously I could not find a way to enable this without
getting assertions when browsing the web - but that seems to no longer
be the case (probably from some other fixes which have since been made).
2023-08-31 11:02:18 +02:00
Shannon Booth
9d60f23abc AK: Port URL::m_fragment from DeprecatedString to String 2023-08-13 15:03:53 -06:00
Shannon Booth
c25485700a AK: Port URL scheme from DeprecatedString to String 2023-08-13 15:03:53 -06:00
Shannon Booth
21fe86d235 AK: Port URL::m_query from DeprecatedString to String 2023-08-13 15:03:53 -06:00
Shannon Booth
55a01e72ca AK: Port URL username/password from DeprecatedString to String
And for cases that just need to check whether the password/username is
empty, add a raw_{password,username} helper to avoid any allocation.
2023-08-13 15:03:53 -06:00
Timothy Flynn
66e1f8cdab AK: Support serializing opaque hosts
The spec indicates we should support serializing opaque hosts, but we
were assuming the host contained a String. Opaque hosts are represented
with Empty. Return an empty string here instead to prevent crashing on
an invalid variant access.
2023-08-09 05:33:24 +02:00
Shannon Booth
faf9d08371 AK: Fix IPv6 serialization on multiple '0' parts ending in a '0' part
This could happen if a sequence of '0' parts was followed by a longer
sequence of '0' parts at the end of the host. The first sequence was
being used for the compress, and not the second.

For example, [1:1:0:0:1:0:0:0] was being serialized as: [1:1::1:0:0:0]
instead of [1:1:0:0:1::].

Fix this by checking at the end of the loop if we are in the middle of a
sequence of '0' parts that is longer than the current longest.
2023-08-06 10:53:32 +02:00
Shannon Booth
c4d7be100e AK: Directly append URL paths where applicable
This is a little closer to the spec text, and helps us avoid using
the ApplyPercentEncoding flag.
2023-08-06 08:57:23 +02:00
Karol Kosek
eb41f0144b AK: Decode data URLs to separate class (and parse like every other URL)
Parsing 'data:' URLs took it's own route. It never set standard URL
fields like path, query or fragment (except for scheme) and instead
gave us separate methods called `data_payload()`, `data_mime_type()`,
and `data_payload_is_base64()`.

Because parsing 'data:' didn't use standard fields, running the
following JS code:

    new URL('#a', 'data:text/plain,hello').toString()

not only cleared the path as URLParser doesn't check for data from
data_payload() function (making the result be 'data:#a'), but it also
crashes the program because we forbid having an empty MIME type when we
serialize to string.

With this change, 'data:' URLs will be parsed like every other URLs.
To decode the 'data:' URL contents, one needs to call process_data_url()
on a URL, which will return a struct containing MIME type with already
decoded data! :^)
2023-08-01 14:19:05 +02:00
Karol Kosek
58017a0581 AK: Clear buffer after leaving CannotBeABaseUrlPath in URLParser
By not clearing the buffer, we were leaking the path part of a URL into
the query for URLs without an authority component (no '//host').

This could be seen most noticeably in mailto: URLs with header fields
set, as the query part of `mailto:user@example.com?subject=test` was
parsed to `user@example.comsubject=test`.

data: URLs didn't have this problem, because we have a special case for
parsing them.
2023-08-01 10:10:07 +02:00
Shannon Booth
aa7ca80d7c AK: Fix missing step step for serialization of IPv6 hosts
This was resulting in the incorrect host serialization of:

http://[0:1:0:1:0:1:0:1] to [::1:0:1:0:1:0:1]

and:

http://[1:0:1:0:1:0:1:0] to [1::1:0:1:0:1:0]
2023-07-31 14:48:24 +02:00
Shannon Booth
8751be09f9 AK: Serialize URL hosts with 'concept-host-serializer'
In order to follow spec text to achieve this, we need to change the
underlying representation of a host in AK::URL to deserialized format.
Before this, we were parsing the host and then immediately serializing
it again.

Making that change resulted in a whole bunch of fallout.

After this change, callers can access the serialized data through
this concept-host-serializer. The functional end result of this
change is that IPv6 hosts are now correctly serialized to be
surrounded with '[' and ']'.
2023-07-31 05:18:51 +02:00
Shannon Booth
768f070b86 AK: Implement 'concept-host-serializer' in URL spec
This implementation will allow us to fix serialization of IPv6
addresses not being surrounded by '[' and ']'.

Nothing is calling this function yet - this will come in the next
(larger) commit where the underlying host representation inside of
AK::URL is changed from DeprecatedString to URL::Host.
2023-07-31 05:18:51 +02:00
Shannon Booth
803ca8cc80 AK: Make serialize_ipv6_address take a StringBuilder
This will allow us to implement 'concept-host-serializer' without
needing to call String::formatted.
2023-07-31 05:18:51 +02:00
Shannon Booth
0c0117fc86 AK: Add typdefs for host URL definitions
And use them where applicable. This will allow us to store the host in
the deserialized format as the spec specifies.

Ideally these typdefs would instead be the existing AK interfaces, but
in the meantime, we can just use this.
2023-07-31 05:18:51 +02:00
Shannon Booth
177b04dcfc AK: Fix url host parsing check for 'ends in a number'
I misunderstood the spec step for checking whether the host 'ends with a
number'. We can't simply check for it if ends with a number, this check
is actually an algorithm which is required to avoid detecting hosts that
end with a number from an IPv4 host.

Implement this missing step, and add a test to cover this.
2023-07-25 06:43:50 -04:00
Shannon Booth
8d2ccf0f4f AK: Implement IPV4 host URL parsing to specification
This implements both the parsing and serialization IPV4 parts from
the URL spec.
2023-07-24 17:07:16 -04:00
Andreas Kling
f0ec104131 AK: Implement IPv6 host parsing in URLParser
This is just a straight (and fairly inefficient) implementation of IPv6
parsing and serialization from the URL spec.

Note that we don't use AK::IPv6Address here because the URL spec
requires a specific serialization behavior.
2023-07-17 07:47:58 +02:00
Shannon Booth
5625ca5cb9 AK: Rename URLParser::parse to URLParser::basic_parse
To make it more clear that this function implements
'concept-basic-url-parser' instead of 'concept-url-parser'.
2023-07-15 09:45:16 +02:00
Shannon Booth
7ef4689383 AK: Implement steps for state override in URL parser 2023-07-15 09:45:16 +02:00
Shannon Booth
6acce60393 AK: Fix typo in URL basic parse authority state
We weren't actually ever iterating over the buffer, and only what we
were intending to append to (which is empty!).
2023-07-05 11:41:10 +02:00
Shannon Booth
16b43ed03e AK: Correct faulty logic for host state in basic URL parse
The '[' and ']' code points were not being appended to the buffer for
this case.
2023-07-05 11:41:10 +02:00
Shannon Booth
dc27d19b21 AK: Remove superfluous check for file state in URL basic parse
The spec does not mention any of the other checks we were doing.
2023-07-05 11:41:10 +02:00
Shannon Booth
b76972ff32 AK: Correct faulty logic in file slash state in basic URL parsing
We were not correctly decrementing the pointer in the case that either
the base URL was non-null or the base URL's scheme was not a file.
2023-07-05 11:41:10 +02:00
Shannon Booth
a809d1634f AK: Add missing spec assert in relative state basic URL parsing 2023-07-05 11:41:10 +02:00
Shannon Booth
4dd4ff68d3 AK: Correct logic in file state decrementing a path in URL basic parsing 2023-07-05 11:41:10 +02:00
Shannon Booth
983441b67f AK: Check for state override in more places for basic URL parsing 2023-07-05 11:41:10 +02:00
Shannon Booth
c6c424e982 AK: Add spec comments for 'basic URL parser'
By golly, this is a lot more spec comments than I originally thought
I would need to do! This has exposed some bugs in the implementation,
as well as a whole lot of things which we are yet to implement.

No functional changes intended in this commit (already pretty large
as is!).
2023-07-05 11:41:10 +02:00
Shannon Booth
be9fcaf92d AK: Expose URLParser::percent_encode_after_encoding
This function is useful in places outside of the URLParser in LibWeb.
2023-06-25 11:28:32 +02:00
Valtteri Koskivuori
838d586b25 AK: Fix relative file URL parsing in URLParser
The FileSlash state was erroneously copying the base URL host, instead
of the base URL path excluding the last path component. This resulted in
invalid file URLs.
2023-06-18 15:16:08 +02:00
MacDue
5db1eb9961 AK+Everywhere: Replace URL::paths() with path_segment_at_index()
This allows accessing and looping over the path segments in a URL
without necessarily allocating a new vector if you want them percent
decoded too (which path_segment_at_index() has an option for).
2023-04-15 06:37:04 +02:00
MacDue
8283e8b88c AK: Don't store parts of URLs percent decoded
As noted in serval comments doing this goes against the WC3 spec,
and breaks parsing then re-serializing URLs that contain percent
encoded data, that was not encoded using the same character set as
the serializer.

For example, previously if you had a URL like:

https:://foo.com/what%2F%2F (the path is what + '//' percent encoded)

Creating URL("https:://foo.com/what%2F%2F").serialize() would return:

https://foo.com/what//

Which is incorrect and not the same as the URL we passed. This is
because the re-serializing uses the PercentEncodeSet::Path which
does not include '/'.

Only doing the percent encoding in the setters fixes this, which
is required to navigate to Google Street View (which includes a
percent encoded URL in its URL).

Seems to fix #13477 too
2023-04-12 07:40:22 +02:00
networkException
9915fa72fb AK+Everywhere: Use Optional for URLParser::parse's base_url parameter 2023-04-11 16:28:20 +02:00
Andreas Kling
a504ac3e2a Everywhere: Rename equals_ignoring_case => equals_ignoring_ascii_case
Let's make it clear that these functions deal with ASCII case only.
2023-03-10 13:15:44 +01:00
Thiago Henrique Hupner
401bc13776 AK: Use base URL when the specified URL is empty 2023-01-06 13:59:17 -07:00
Linus Groh
57dc179b1f Everywhere: Rename to_{string => deprecated_string}() where applicable
This will make it easier to support both string types at the same time
while we convert code, and tracking down remaining uses.

One big exception is Value::to_string() in LibJS, where the name is
dictated by the ToString AO.
2022-12-06 08:54:33 +01:00
Linus Groh
6e19ab2bbc AK+Everywhere: Rename String to DeprecatedString
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
2022-12-06 08:54:33 +01:00
Ben Wiederhake
dc71e1e264 AK: Fix 'constexpr' attribute on non-constexpr function
is_url_code_point invokes StringView::contains, which never was and
cannot become constexpr.
2022-10-09 10:37:20 -06:00
Ben Wiederhake
3aeb57ed09 AK+Everywhere: Fix data corruption due to code-point-to-char conversion
In particular, StringView::contains(char) is often used with a u32
code point. When this is done, the compiler will for some reason allow
data corruption to occur silently.

In fact, this is one of two reasons for the following OSS Fuzz issue:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49184
This is probably a very old bug.

In the particular case of URLParser, AK::is_url_code_point got confused:
    return /* ... */ || "!$&'()*+,-./:;=?@_~"sv.contains(code_point);
If code_point is a large code point that happens to have the correct
lower bytes, AK::is_url_code_point is then convinced that the given
code point is okay, even if it is actually problematic.

This commit fixes *only* the silent data corruption due to the erroneous
conversion, and does not fully resolve OSS-Fuzz#49184.
2022-10-09 10:37:20 -06:00