Commit graph

51 commits

Author SHA1 Message Date
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
Andreas Kling
287a9b552a AK: Fix bad parsing of some file:/// URLs with base URL
We were dropping the base URL path components in the resulting URL due
to mistakenly determining the input URL to start with a Windows drive
letter. Fix this, add a spec link, and a test.
2022-09-20 15:38:53 +02:00
sin-ack
3f3f45580a Everywhere: Add sv suffix to strings relying on StringView(char const*)
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).

No functional changes.
2022-07-12 23:11:35 +02:00
DexesTTP
7ceeb74535 AK: Use an enum instead of a bool for String::replace(all_occurences)
This commit has no behavior changes.

In particular, this does not fix any of the wrong uses of the previous
default parameter (which used to be 'false', meaning "only replace the
first occurence in the string"). It simply replaces the default uses by
String::replace(..., ReplaceMode::FirstOnly), leaving them incorrect.
2022-07-06 11:12:45 +02:00
Andreas Kling
79c77debb0 AK: Don't destructively re-encode query strings in the URL parser
We were decoding and then re-encoding the query string in URLs.
This round-trip caused us to lose information about plus ('+')
ASCII characters encoded as "%2B".
2022-04-10 01:37:45 +02:00
Andreas Kling
8b1108e485 Everywhere: Pass AK::StringView by value 2021-11-11 01:27:46 +01:00
Idan Horowitz
d6cfa34667 AK: Make URL::m_port an Optional<u16>, Expose raw port getter
Our current way of signalling a missing port with m_port == 0 was
lacking, as 0 is a valid port number in URLs.
2021-09-14 00:14:45 +02:00
Idan Horowitz
55b67ba7a7 AK: Accept optional url and state override parameters in URLParser
These are required in the specification and used by the web's URL
built-in, this commit also removes the Badge<AK::URL> from URLParser
to allow other classes that need to call the parser directly like the
web's URL built-in to do so.
2021-09-14 00:14:45 +02:00
Idan Horowitz
6704961c82 AK: Replace the mutable String::replace API with an immutable version
This removes the awkward String::replace API which was the only String
API which mutated the String and replaces it with a new immutable
version that returns a new String with the replacements applied. This
also fixes a couple of UAFs that were caused by the use of this API.

As an optimization an equivalent StringView::replace API was also added
to remove an unnecessary String allocations in the format of:
`String { view }.replace(...);`
2021-09-11 20:36:43 +03:00
TheFightingCatfish
4e8e1b7b3a AK: Improve the parsing of data urls
Improve the parsing of data urls in URLParser to bring it more up-to-
spec. At the moment, we cannot parse the components of the MIME type
since it is represented as a string, but the spec requires it to be
parsed as a "MIME type record".
2021-08-06 10:45:17 +02:00
Gunnar Beutner
d476144565 Userland: Allow building SerenityOS with -funsigned-char
Some of the code assumed that chars were always signed while that is
not the case on ARM hosts.

Also, some of the code tried to use EOF (-1) in a way similar to what
fgetc() does, however instead of storing the characters in an int
variable a char was used.

While this seemed to work it also meant that character 0xFF would be
incorrectly seen as an end-of-file.

Careful reading of fgetc() reveals that fgetc() stores character
data in an int where valid characters are in the range of 0-255 and
the EOF value is explicitly outside of that range (usually -1).
2021-06-13 18:52:58 +02:00
Max Wipfli
3b04420490 AK: Don't create Utf8View from temporary String in URLParser
This fixes a bug where a Utf8View was created with data from a temporary
string, which was immediately deleted. This lead to a use-after-free
issue. This also changes most occurences for StringBuilder::to_string in
URLParser to use ::string_view(), as the value is passed as StringView
const& most of the time anyways.

This fixes oss-fuzz issue 34973.
2021-06-08 19:08:02 +02:00
Max Wipfli
2164d8aae8 AK: Stop using U+0000 as end of file code point in URL parser
This changes URL parser to use the 0xFFFFFFFF constant instead of 0 to
indicate end of file. This fixes a bug where inputs containing null
bytes would terminate the parser early, because they were interpreted
as end of file.
2021-06-05 10:53:31 +02:00
Max Wipfli
97425c7dfb AK: Make debugging URLParser easier
This patch adds a state_name method to URLParser to convert a state to a
string. With this, the debugging statements now display the state names.

Furthermore, this fixes a bug where non-ASCII code points were
formatted as characters, which fails an assertion in the formatting
system.
2021-06-05 10:53:31 +02:00
Max Wipfli
99d5555134 AK: Do not trim away non-ASCII bytes when parsing URL
Because non-ASCII code points have negative byte values, trimming away
control characters requires checking for negative bytes values.

This also adds a test case with a URL containing non-ASCII code points.
2021-06-05 10:53:31 +02:00
Max Wipfli
44937e2dfc AK: Update URLParser.{cpp,h} to use east const 2021-06-05 10:53:31 +02:00
DexesTTP
e01f1c949f AK: Do not VERIFY on invalid code point bytes in UTF8View
The previous behavior was to always VERIFY that the UTF-8 bytes were
valid when iterating over the code points of an UTF8View. This change
makes it so we instead output the 0xFFFD 'REPLACEMENT CHARACTER'
code point when encountering invalid bytes, and keep iterating the
view after skipping one byte.

Leaving the decision to the consumer would break symmetry with the
UTF32View API, which would in turn require heavy refactoring and/or
code duplication in generic code such as the one found in
Gfx::Painter and the Shell.

To make it easier for the consumers to detect the original bytes, we
provide a new method on the iterator that returns a Span over the
data that has been decoded. This method is immediately used in the
TextNode::compute_text_for_rendering method, which previously did
this in a ad-hoc waay.

This also add tests for the new behavior in TestUtf8.cpp, as well
as reinforcements to the existing tests to check if the underlying
bytes match up with their expected values.
2021-06-03 18:28:27 +04:30
Max Wipfli
bc8d16ad28 Everywhere: Replace ctype.h to avoid narrowing conversions
This replaces ctype.h with CharacterType.h everywhere I could find
issues with narrowing conversions. While using it will probably make
sense almost everywhere in the future, the most critical places should
have been addressed.
2021-06-03 13:31:46 +02:00
Andreas Kling
c0d1a75881 AK: Strip leading/trailing C0-control-or-space in URLs correctly
We have to stop scanning once we hit a non-strippable character.
Add some tests to cover this.
2021-06-01 13:22:04 +02:00
Andreas Kling
407d6cd9e4 AK: Rename Utf8CodepointIterator => Utf8CodePointIterator 2021-06-01 09:45:52 +02:00
Max Wipfli
0d0ed4962f AK: Add a new, spec-compliant URLParser
This adds a new URL parser, which aims to be compliant with the URL
specification (https://url.spec.whatwg.org/). It also contains a
rudimentary data URL parser.
2021-06-01 09:28:05 +02:00
Max Wipfli
0d41a7d39a AK: Remove URLParser
This removes URLParser, because its two exposed functions, urlencode()
and urldecode(), have been superseded by URL::percent_encode() and
URL::percent_decode(). This is in preparation for the introduction of a
new URL parser.
2021-06-01 09:28:05 +02:00
Brian Gianforcaro
1682f0b760 Everything: Move to SPDX license identifiers in all files.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.

See: https://spdx.dev/resources/use/#identifiers

This was done with the `ambr` search and replace tool.

 ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
2021-04-22 11:22:27 +02:00
Linus Groh
50e3b122c7 AK: Add optional parameter for excluding chars to urlencode() 2021-01-31 19:05:55 +01:00
Conrad Pankoff
13f13a9e59 AK: Fix urlencode() with high byte values
Previously urlencode() would encode bytes above 127 incorrectly, printing
them as negative hex values.
2020-12-12 23:50:23 +01:00
Linus Groh
ba020a5907 AK: Fix logic error in urldecode() percent-decoding
We also need to append the raw consumed value if *either* of the two
characters after the % isn't a hex digit, not only if *both* aren't.

Fixes #4257.
2020-11-30 11:35:01 +01:00
asynts
1d96d5eea4 AK: Use new format functions. 2020-10-08 09:59:55 +02:00
Andreas Kling
fdfda6dec2 AK: Make string-to-number conversion helpers return Optional
Get rid of the weird old signature:

- int StringType::to_int(bool& ok) const

And replace it with sensible new signature:

- Optional<int> StringType::to_int() const
2020-06-12 21:28:55 +02:00