Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 24 additions & 16 deletions AK/IPv6Address.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#pragma once

#include <AK/BitCast.h>
#include <AK/Endian.h>
#include <AK/Format.h>
#include <AK/IPv4Address.h>
Expand Down Expand Up @@ -36,6 +37,13 @@ class [[gnu::packed]] IPv6Address {
m_data[i] = data[i];
}

constexpr IPv6Address(Array<u16, 8> const& data)
{
u16* pieces = reinterpret_cast<u16*>(m_data);
for (size_t i = 0; i < 8; i++)
pieces[i] = bit_cast<u16>(NetworkOrdered<u16>(data[i]));
}

template<SameAs<char const*> T>
constexpr IPv6Address(T const&) = delete; // Disable implicit conversion of char const* -> ipv4 -> ipv6

Expand All @@ -50,7 +58,7 @@ class [[gnu::packed]] IPv6Address {
m_data[15] = ipv4_address[3];
}

constexpr u16 operator[](int i) const { return group(i); }
constexpr u16 operator[](size_t i) const { return piece(i); }

ErrorOr<String> to_string() const
{
Expand All @@ -68,13 +76,13 @@ class [[gnu::packed]] IPv6Address {
Optional<int> longest_zero_span_start;
int zero_span_length = 0;
for (int i = 0; i < 8;) {
if (group(i) != 0) {
if (piece(i) != 0) {
i++;
continue;
}
int contiguous_zeros = 1;
for (int j = i + 1; j < 8; j++) {
if (group(j) != 0)
if (piece(j) != 0)
break;
contiguous_zeros++;
}
Expand All @@ -98,9 +106,9 @@ class [[gnu::packed]] IPv6Address {
}

if (i == 0)
TRY(builder.try_appendff("{:x}", group(i)));
TRY(builder.try_appendff("{:x}", piece(i)));
else
TRY(builder.try_appendff(":{:x}", group(i)));
TRY(builder.try_appendff(":{:x}", piece(i)));

i++;
}
Expand Down Expand Up @@ -186,8 +194,8 @@ class [[gnu::packed]] IPv6Address {
}

in6_addr_t addr {};
int group = 0;
int have_groups = 0;
int piece = 0;
int have_pieces = 0;
bool found_compressed = false;
for (size_t i = 0; i < parts.size();) {
auto trimmed_part = parts[i].trim_whitespace();
Expand Down Expand Up @@ -216,10 +224,10 @@ class [[gnu::packed]] IPv6Address {
return {};
}

int remaining_parts = parts.size() - empty_parts - have_groups;
int remaining_parts = parts.size() - empty_parts - have_pieces;
found_compressed = true;
group = 8 - remaining_parts;
VERIFY(group >= 0);
piece = 8 - remaining_parts;
VERIFY(piece >= 0);
i += empty_parts;
continue;
} else {
Expand All @@ -229,13 +237,13 @@ class [[gnu::packed]] IPv6Address {
if (!part.has_value() || part.value() > 0xffff)
return {};

if (++have_groups > 8)
if (++have_pieces > 8)
return {};

VERIFY(group < 8);
addr[group * sizeof(u16)] = (u8)(part.value() >> 8);
addr[group * sizeof(u16) + 1] = (u8)part.value();
group++;
VERIFY(piece < 8);
addr[piece * sizeof(u16)] = (u8)(part.value() >> 8);
addr[piece * sizeof(u16) + 1] = (u8)part.value();
piece++;
}

return IPv6Address(addr);
Expand Down Expand Up @@ -278,7 +286,7 @@ class [[gnu::packed]] IPv6Address {
}

private:
constexpr u16 group(unsigned i) const
constexpr u16 piece(size_t i) const
{
VERIFY(i < 8);
return ((u16)m_data[i * sizeof(u16)] << 8) | m_data[i * sizeof(u16) + 1];
Expand Down
6 changes: 3 additions & 3 deletions Libraries/LibCore/Proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ struct ProxyData {
SOCKS5,
} type { Type::Direct };

u32 host_ipv4 { 0 };
IPv4Address host_ipv4;
int port { 0 };

bool operator==(ProxyData const& other) const = default;
Expand All @@ -33,9 +33,9 @@ struct ProxyData {

proxy_data.type = ProxyData::Type::SOCKS5;

if (!url.host().has_value() || !url.host()->has<URL::IPv4Address>())
if (!url.host().has_value() || !url.host()->has<IPv4Address>())
return Error::from_string_literal("Invalid proxy host, must be an IPv4 address");
proxy_data.host_ipv4 = url.host()->get<URL::IPv4Address>();
proxy_data.host_ipv4 = url.host()->get<IPv4Address>();

auto port = url.port();
if (!port.has_value())
Expand Down
18 changes: 17 additions & 1 deletion Libraries/LibIPC/Decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* SPDX-License-Identifier: BSD-2-Clause
*/

#include <AK/IPv4Address.h>
#include <AK/IPv6Address.h>
#include <AK/JsonValue.h>
#include <AK/NumericLimits.h>
#include <AK/Utf16String.h>
Expand Down Expand Up @@ -87,6 +89,20 @@ ErrorOr<UnixDateTime> decode(Decoder& decoder)
return AK::UnixDateTime::from_nanoseconds_since_epoch(nanoseconds);
}

template<>
ErrorOr<IPv4Address> decode(Decoder& decoder)
{
auto ipv4 = TRY(decoder.decode<u32>());
return IPv4Address(ipv4);
}

template<>
ErrorOr<IPv6Address> decode(Decoder& decoder)
{
auto ipv6 = TRY(decoder.decode<Array<u8, 16>>());
return IPv6Address(ipv6);
}

template<>
ErrorOr<URL::URL> decode(Decoder& decoder)
{
Expand Down Expand Up @@ -152,7 +168,7 @@ template<>
ErrorOr<Core::ProxyData> decode(Decoder& decoder)
{
auto type = TRY(decoder.decode<Core::ProxyData::Type>());
auto host_ipv4 = TRY(decoder.decode<u32>());
auto host_ipv4 = IPv4Address(TRY(decoder.decode<u32>()));
auto port = TRY(decoder.decode<int>());

return Core::ProxyData { type, host_ipv4, port };
Expand Down
6 changes: 6 additions & 0 deletions Libraries/LibIPC/Decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ ErrorOr<AK::Duration> decode(Decoder&);
template<>
ErrorOr<UnixDateTime> decode(Decoder&);

template<>
ErrorOr<IPv4Address> decode(Decoder&);

template<>
ErrorOr<IPv6Address> decode(Decoder&);

template<>
ErrorOr<URL::URL> decode(Decoder&);

Expand Down
13 changes: 13 additions & 0 deletions Libraries/LibIPC/Encoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,19 @@ ErrorOr<void> encode(Encoder& encoder, UnixDateTime const& value)
return encoder.encode(value.nanoseconds_since_epoch());
}

template<>
ErrorOr<void> encode(Encoder& encoder, IPv4Address const& ipv4)
{
return encoder.encode(ipv4.to_u32());
}

template<>
ErrorOr<void> encode(Encoder& encoder, IPv6Address const& ipv6)
{
auto const& data = ipv6.to_in6_addr_t();
return encoder.encode(ReadonlySpan<u8>(data));
}

template<>
ErrorOr<void> encode(Encoder& encoder, URL::URL const& value)
{
Expand Down
7 changes: 7 additions & 0 deletions Libraries/LibIPC/Encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <AK/Concepts.h>
#include <AK/HashMap.h>
#include <AK/IPv4Address.h>
#include <AK/StdLibExtras.h>
#include <AK/Variant.h>
#include <LibCore/Forward.h>
Expand Down Expand Up @@ -108,6 +109,12 @@ ErrorOr<void> encode(Encoder&, AK::Duration const&);
template<>
ErrorOr<void> encode(Encoder&, UnixDateTime const&);

template<>
ErrorOr<void> encode(Encoder&, IPv4Address const&);

template<>
ErrorOr<void> encode(Encoder&, IPv6Address const&);

template<>
ErrorOr<void> encode(Encoder&, URL::URL const&);

Expand Down
6 changes: 3 additions & 3 deletions Libraries/LibURL/Host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static String serialize_ipv4_address(IPv4Address address)
Array<u8, 4> output;

// 2. Let n be the value of address.
u32 n = address;
u32 n = address.to_u32();

// 3. For each i in the range 1 to 4, inclusive:
for (size_t i = 0; i <= 3; ++i) {
Expand Down Expand Up @@ -64,7 +64,7 @@ static Optional<size_t> find_the_ipv6_address_compressed_piece_index(IPv6Address
size_t found_size = 0;

// 5. For each pieceIndex of address’s pieces’s indices:
for (size_t piece_index = 0; piece_index < address.size(); ++piece_index) {
for (size_t piece_index = 0; piece_index < 8; ++piece_index) {
// 1. If address’s pieces[pieceIndex] is not 0:
if (address[piece_index] != 0) {
// 1. If foundSize is greater than longestSize, then set longestIndex to foundIndex and longestSize to foundSize.
Expand Down Expand Up @@ -110,7 +110,7 @@ static void serialize_ipv6_address(IPv6Address const& address, StringBuilder& ou
auto ignore0 = false;

// 4. For each pieceIndex of address’s pieces’s indices:
for (size_t piece_index = 0; piece_index < address.size(); ++piece_index) {
for (size_t piece_index = 0; piece_index < 8; ++piece_index) {
// 1. If ignore0 is true and address[pieceIndex] is 0, then continue.
if (ignore0 && address[piece_index] == 0)
continue;
Expand Down
13 changes: 2 additions & 11 deletions Libraries/LibURL/Host.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,13 @@
#pragma once

#include <AK/Array.h>
#include <AK/IPv4Address.h>
#include <AK/IPv6Address.h>
#include <AK/String.h>
#include <AK/Types.h>

namespace URL {

// https://url.spec.whatwg.org/#concept-ipv4
// An IPv4 address is a 32-bit unsigned integer that identifies a network address. [RFC791]
// FIXME: It would be nice if this were an AK::IPv4Address
using IPv4Address = u32;

// https://url.spec.whatwg.org/#concept-ipv6
// An IPv6 address is a 128-bit unsigned integer that identifies a network address. For the purposes of this standard
// it is represented as a list of eight 16-bit unsigned integers, also known as IPv6 pieces. [RFC4291]
// FIXME: It would be nice if this were an AK::IPv6Address
using IPv6Address = Array<u16, 8>;

// https://url.spec.whatwg.org/#concept-host
// A host is a domain, an IP address, an opaque host, or an empty host. Typically a host serves as a network address,
// but it is sometimes used as opaque identifier in URLs where a network address is not necessary.
Expand Down
6 changes: 4 additions & 2 deletions Libraries/LibURL/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <AK/ByteString.h>
#include <AK/CharacterTypes.h>
#include <AK/Debug.h>
#include <AK/IPv4Address.h>
#include <AK/IPv6Address.h>
#include <AK/IntegralMath.h>
#include <AK/Optional.h>
#include <AK/SourceLocation.h>
Expand Down Expand Up @@ -226,7 +228,7 @@ static Optional<IPv4Address> parse_ipv4_address(StringView input)
}

// 13. Return ipv4.
return ipv4;
return IPv4Address(ipv4);
}

// https://url.spec.whatwg.org/#concept-ipv6-parser
Expand Down Expand Up @@ -455,7 +457,7 @@ static Optional<IPv6Address> parse_ipv6_address(StringView input)
}

// 9. Return address.
return address;
return IPv6Address(address);
}

// https://url.spec.whatwg.org/#ends-in-a-number-checker
Expand Down
2 changes: 1 addition & 1 deletion Libraries/LibWeb/MixedContent/AbstractOperations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void upgrade_a_mixed_content_request_to_a_potentially_trustworthy_url_if_appropr
SecureContexts::is_url_potentially_trustworthy(request.url()) == SecureContexts::Trustworthiness::PotentiallyTrustworthy

// 2. request’s URL’s host is an IP address.
|| (request.url().host().has_value() && (request.url().host()->has<URL::IPv4Address>() || request.url().host()->has<URL::IPv6Address>()))
|| (request.url().host().has_value() && (request.url().host()->has<IPv4Address>() || request.url().host()->has<IPv6Address>()))

// 3. § 4.3 Does settings prohibit mixed security contexts? returns "Does Not Restrict Mixed Security Contents" when applied to request’s client.
|| does_settings_prohibit_mixed_security_contexts(request.client()) == ProhibitsMixedSecurityContexts::DoesNotRestrictMixedSecurityContexts
Expand Down
12 changes: 5 additions & 7 deletions Libraries/LibWeb/SecureContexts/AbstractOperations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,12 @@ Trustworthiness is_origin_potentially_trustworthy(URL::Origin const& origin)
return Trustworthiness::PotentiallyTrustworthy;

// 4. If origin’s host matches one of the CIDR notations 127.0.0.0/8 or ::1/128 [RFC4632], return "Potentially Trustworthy".
// FIXME: This would be nicer if URL::IPv4Address and URL::IPv6Address were instances of AK::IPv4Address and AK::IPv6Address
if (origin.host().has<URL::IPv4Address>()) {
if ((origin.host().get<URL::IPv4Address>() & 0xff000000) != 0)
if (origin.host().has<IPv4Address>()) {
if ((origin.host().get<IPv4Address>().to_u32() & 0xff000000) != 0)
return Trustworthiness::PotentiallyTrustworthy;
} else if (origin.host().has<URL::IPv6Address>()) {
auto ipv6_address = origin.host().get<URL::IPv6Address>();
static constexpr URL::IPv6Address loopback { 0, 0, 0, 0, 0, 0, 0, 1 };
if (ipv6_address == loopback)
} else if (origin.host().has<IPv6Address>()) {
auto ipv6_address = origin.host().get<IPv6Address>();
if (ipv6_address == IPv6Address::loopback())
return Trustworthiness::PotentiallyTrustworthy;
}

Expand Down
Loading