0

spanify: Adjust url_canon_ip

When arrayified, compilation breaks when one tries to index a
`std::array` with a signed type (in this case, `int`).

*   Change problematic values to be an unsigned type and add
    compile-time assertions that they have suitable range.

*   Don't use `StrictNumeric` and friends for now, since we intend
    on converting the indexees to `std::array`, which will give us
    bounds checks for free.

*   Don't use `std::extent_v` in the `static_asserts` for similar
    reasons, since it will silently fail when indexees are arrayified.
    For example, `std::extent_v<some_std_array>` yields `0` in my build.

Bug: 406029216
Change-Id: Icadb0bd39148da5f58c64878f711052689946ad9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6415469
Reviewed-by: Mike West <mkwst@chromium.org>
Commit-Queue: Kalvin Lee <kdlee@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1440729}
This commit is contained in:
Kalvin Lee
2025-03-31 23:32:51 -07:00
committed by Chromium LUCI CQ
parent df8e3ce2c7
commit 046e403b01

@ -10,6 +10,10 @@
#ifndef URL_URL_CANON_IP_H_
#define URL_URL_CANON_IP_H_
#include <cstdint>
#include <limits>
#include <type_traits>
#include "base/component_export.h"
#include "url/third_party/mozilla/url_parse.h"
#include "url/url_canon.h"
@ -154,7 +158,11 @@ constexpr CanonHostInfo::Family DoIPv4AddressToNumber(
// component, which allows for early exit if the last component isn't a
// number.
uint32_t component_values[4];
int existing_components = 0;
uint8_t existing_components = 0;
// `existing_components` is used to index `component_values`.
// All possible values must be in range.
static_assert(std::numeric_limits<decltype(existing_components)>::max() >=
sizeof(component_values) / sizeof(component_values[0]));
int current_component_end = host.end();
int current_position = current_component_end;
@ -202,7 +210,7 @@ constexpr CanonHostInfo::Family DoIPv4AddressToNumber(
// First, process all components but the last, while making sure each fits
// within an 8-bit field.
for (int i = existing_components - 1; i > 0; i--) {
for (decltype(existing_components) i = existing_components - 1; i > 0; --i) {
if (component_values[i] > std::numeric_limits<uint8_t>::max()) {
return CanonHostInfo::BROKEN;
}
@ -277,7 +285,9 @@ struct IPv6Parsed {
Component hex_components[8];
// The count of hex components present. Ranges from [0,8].
int num_hex_components;
uint8_t num_hex_components;
static_assert(std::numeric_limits<decltype(num_hex_components)>::max() >=
sizeof(hex_components) / sizeof(hex_components[0]));
// The index of the hex component that the "::" contraction precedes, or
// -1 if there is no contraction.
@ -479,7 +489,8 @@ constexpr bool DoIPv6AddressToNumber(const CHAR* spec,
int cur_index_in_address = 0;
// Loop through each hex components, and contraction in order.
for (int i = 0; i <= ipv6_parsed.num_hex_components; ++i) {
for (decltype(ipv6_parsed.num_hex_components) i = 0;
i <= ipv6_parsed.num_hex_components; ++i) {
// Append the contraction if it appears before this component.
if (i == ipv6_parsed.index_of_contraction) {
for (int j = 0; j < num_bytes_of_contraction; ++j) {