mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-25 05:55:13 +00:00
This updates our local ICU overlay port to use ICU 76.1. This includes Unicode 16 and CLDR 46. Upstream vcpkg is not able to supply versions past 74 yet due to various dependency issues, but we are able to use this version ourselves. The overlay port now includes a patch to revert ICU's dependence on autoconf 2.72 for now, as this version is not yet available on all systems. All of the test changes were cross-referenced with Firefox to ensure correctness.
65 lines
2 KiB
C++
65 lines
2 KiB
C++
/*
|
|
* Copyright (c) 2023, Simon Wanner <simon@skyrising.xyz>
|
|
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibUnicode/ICU.h>
|
|
#include <LibUnicode/IDNA.h>
|
|
|
|
#include <unicode/idna.h>
|
|
|
|
namespace Unicode::IDNA {
|
|
|
|
// https://www.unicode.org/reports/tr46/#ToASCII
|
|
ErrorOr<String> to_ascii(Utf8View domain_name, ToAsciiOptions const& options)
|
|
{
|
|
u32 icu_options = 0;
|
|
|
|
if (options.check_bidi == CheckBidi::Yes)
|
|
icu_options |= UIDNA_CHECK_BIDI;
|
|
if (options.check_joiners == CheckJoiners::Yes)
|
|
icu_options |= UIDNA_CHECK_CONTEXTJ;
|
|
if (options.use_std3_ascii_rules == UseStd3AsciiRules::Yes)
|
|
icu_options |= UIDNA_USE_STD3_RULES;
|
|
if (options.transitional_processing == TransitionalProcessing::No)
|
|
icu_options |= UIDNA_NONTRANSITIONAL_TO_ASCII | UIDNA_NONTRANSITIONAL_TO_UNICODE;
|
|
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
|
|
auto idna = adopt_own_if_nonnull(icu::IDNA::createUTS46Instance(icu_options, status));
|
|
if (icu_failure(status))
|
|
return Error::from_string_literal("Unable to create an IDNA instance");
|
|
|
|
StringBuilder builder { domain_name.as_string().length() };
|
|
icu::StringByteSink sink { &builder };
|
|
|
|
icu::IDNAInfo info;
|
|
idna->nameToASCII_UTF8(icu_string_piece(domain_name.as_string()), sink, info, status);
|
|
|
|
auto errors = info.getErrors();
|
|
|
|
if (options.check_hyphens == CheckHyphens::No) {
|
|
errors &= ~UIDNA_ERROR_HYPHEN_3_4;
|
|
errors &= ~UIDNA_ERROR_LEADING_HYPHEN;
|
|
errors &= ~UIDNA_ERROR_TRAILING_HYPHEN;
|
|
}
|
|
|
|
if (options.verify_dns_length == VerifyDnsLength::No) {
|
|
errors &= ~UIDNA_ERROR_EMPTY_LABEL;
|
|
errors &= ~UIDNA_ERROR_LABEL_TOO_LONG;
|
|
errors &= ~UIDNA_ERROR_DOMAIN_NAME_TOO_LONG;
|
|
}
|
|
|
|
if (options.ignore_invalid_punycode == IgnoreInvalidPunycode::Yes) {
|
|
errors &= ~UIDNA_ERROR_PUNYCODE;
|
|
}
|
|
|
|
if (icu_failure(status) || errors != 0)
|
|
return Error::from_string_literal("Unable to convert domain to ASCII");
|
|
|
|
return builder.to_string();
|
|
}
|
|
|
|
}
|