Sourcemeta Core 0.0.0
Loading...
Searching...
No Matches
IDNA

Internationalized Domain Names in Applications (IDNA2008) utilities. More...

Macros

#define SOURCEMETA_CORE_IDNA_PROPERTY_LIST(X)
#define SOURCEMETA_CORE_IDNA_MAPPING_STATUS_LIST(X)

Enumerations

enum class  sourcemeta::core::IDNALabelKind : std::uint8_t { IDNALabelKind::Ascii = 0 , IDNALabelKind::ALabel = 1 , IDNALabelKind::ULabel = 2 }
enum class  sourcemeta::core::IDNAProperty : std::uint8_t
enum class  sourcemeta::core::IDNAMappingStatus : std::uint8_t

Functions

SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_classify_label (const std::u32string_view label, std::u32string &decoded) -> std::optional< IDNALabelKind >
SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_property (const char32_t codepoint) noexcept -> IDNAProperty
SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_passes_contexto (const std::u32string_view label, const std::size_t position) noexcept -> bool
SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_passes_contextj (const std::u32string_view label, const std::size_t position) noexcept -> bool
SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_passes_bidi_rule (const std::u32string_view label) noexcept -> bool
SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_is_valid_u_label (const std::u32string_view label) -> bool
SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_is_valid_a_label (const std::string_view label) -> bool
SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_uts46_map (const std::u32string_view input) -> std::u32string

Detailed Description

Internationalized Domain Names in Applications (IDNA2008) utilities.

This functionality is included as follows:

#include <sourcemeta/core/idna.h>

Macro Definition Documentation

◆ SOURCEMETA_CORE_IDNA_MAPPING_STATUS_LIST

#define SOURCEMETA_CORE_IDNA_MAPPING_STATUS_LIST ( X)
Value:
X(Valid, "valid") \
X(Ignored, "ignored") \
X(Mapped, "mapped") \
X(Deviation, "deviation") \
X(Disallowed, "disallowed")

Each entry maps an IDNAMappingStatus enum name to its UTS #46 IdnaMappingTable.txt token.

◆ SOURCEMETA_CORE_IDNA_PROPERTY_LIST

#define SOURCEMETA_CORE_IDNA_PROPERTY_LIST ( X)
Value:
X(PValid, "PVALID") \
X(ContextJ, "CONTEXTJ") \
X(ContextO, "CONTEXTO") \
X(Disallowed, "DISALLOWED") \
X(Unassigned, "UNASSIGNED")

Each entry maps an IDNAProperty enum name to its RFC 5892 token.

Enumeration Type Documentation

◆ IDNALabelKind

enum class sourcemeta::core::IDNALabelKind : std::uint8_t
strong

The RFC 5890 §2.3.2 classification of a domain name label.

Enumerator
Ascii 

A pure ASCII label that is not an A-label. The IDNA specification does not validate such labels.

ALabel 

An RFC 5890 §2.3.2.1 A-label (ACE form), validated per RFC 5891 §4.

ULabel 

An RFC 5890 §2.3.2.2 U-label (Unicode form), validated per RFC 5891 §4.

◆ IDNAMappingStatus

enum class sourcemeta::core::IDNAMappingStatus : std::uint8_t
strong

The UTS #46 status of a Unicode codepoint in the mapping table. See https://www.unicode.org/reports/tr46/ for the status definitions.

◆ IDNAProperty

enum class sourcemeta::core::IDNAProperty : std::uint8_t
strong

The RFC 5892 derived property of a Unicode codepoint. See https://www.rfc-editor.org/rfc/rfc5892 for the property's definition.

Function Documentation

◆ idna_classify_label()

SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_classify_label ( const std::u32string_view label,
std::u32string & decoded ) -> std::optional< IDNALabelKind >

Classify label as an Ascii / A-label / U-label per RFC 5890 §2.3.2, validate the A-label and U-label cases per RFC 5891 §4, and write the U-label codepoint form to decoded. Detection of the ACE prefix "xn--" is case-insensitive per RFC 5890 §2.3.2.1. For example:

#include <sourcemeta/core/idna.h>
#include <cassert>
std::u32string decoded;
assert(sourcemeta::core::idna_classify_label(U"\u00DF\u03C2", decoded) ==
assert(sourcemeta::core::idna_classify_label(U"xn--mnchen-3ya", decoded) ==
assert(sourcemeta::core::idna_classify_label(U"example", decoded) ==
SOURCEMETA_CORE_IDNA_EXPORT auto idna_classify_label(const std::u32string_view label, std::u32string &decoded) -> std::optional< IDNALabelKind >
@ ALabel
An RFC 5890 §2.3.2.1 A-label (ACE form), validated per RFC 5891 §4.
Definition idna.h:34
@ Ascii
Definition idna.h:32
@ ULabel
An RFC 5890 §2.3.2.2 U-label (Unicode form), validated per RFC 5891 §4.
Definition idna.h:36

◆ idna_is_valid_a_label()

SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_is_valid_a_label ( const std::string_view label) -> bool

Return whether the given label is a valid A-label per RFC 5891 §4. See https://www.rfc-editor.org/rfc/rfc5891#section-4 for the criteria. A valid A-label starts with the lowercase ACE prefix "xn--", is pure ASCII, is at most 63 octets, has a non-empty Punycode body that decodes to a U-label containing at least one non-ASCII codepoint, and round-trips through Punycode in its canonical form. Both the prefix and the Punycode body are matched case-sensitively, so an uppercase prefix or a mixed-case body is rejected. This is intended for registration-side validation rather than case-folding lookup. For example:

#include <sourcemeta/core/idna.h>
#include <cassert>
// xn--mnchen-3ya decodes to "München"
assert(sourcemeta::core::idna_is_valid_a_label("xn--mnchen-3ya"));
// Missing "xn--" prefix
// Decodes to "abc" (no non-ASCII codepoint)
SOURCEMETA_CORE_IDNA_EXPORT auto idna_is_valid_a_label(const std::string_view label) -> bool

◆ idna_is_valid_u_label()

SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_is_valid_u_label ( const std::u32string_view label) -> bool

Return whether the given label is a valid U-label per RFC 5891 §4. See https://www.rfc-editor.org/rfc/rfc5891#section-4 for the criteria. The Bidi rule is not checked here because Bidi domain detection is a property of the whole domain, not of a single label. A pure-ASCII label that satisfies the structural rules is accepted even though it carries no non-ASCII codepoint, so this check is not on its own a guarantee that the label requires IDNA processing. For example:

#include <sourcemeta/core/idna.h>
#include <cassert>
assert(sourcemeta::core::idna_is_valid_u_label(U"d\u00E9j\u00E0"));
SOURCEMETA_CORE_IDNA_EXPORT auto idna_is_valid_u_label(const std::u32string_view label) -> bool

◆ idna_passes_bidi_rule()

SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_passes_bidi_rule ( const std::u32string_view label) -> bool
noexcept

Return whether the given label satisfies the RFC 5893 Bidi rule. The rule applies to every label of a Bidi domain name (a domain name that contains at least one right-to-left codepoint). The caller is responsible for invoking this only when the domain is a Bidi domain. See https://www.rfc-editor.org/rfc/rfc5893#section-2 for the rule. For example:

#include <sourcemeta/core/idna.h>
#include <cassert>
// Hebrew letter Alef
// Label starting with a digit (Bidi rule condition 1 violated)
SOURCEMETA_CORE_IDNA_EXPORT auto idna_passes_bidi_rule(const std::u32string_view label) noexcept -> bool

◆ idna_passes_contextj()

SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_passes_contextj ( const std::u32string_view label,
const std::size_t position ) -> bool
noexcept

Return whether the codepoint at position within label does not violate any RFC 5892 Appendix A.1 / A.2 contextual rule. Returns true vacuously when the codepoint has no such rule. Returns false when position is out of range, treated as a precondition violation. See https://www.rfc-editor.org/rfc/rfc5892#appendix-A for the rules. For example:

#include <sourcemeta/core/idna.h>
#include <cassert>
// Devanagari KA + VIRAMA + ZWJ
assert(sourcemeta::core::idna_passes_contextj(U"\u0915\u094D\u200D", 2));
// Arabic BEH + ZWNJ + Arabic ALEF
assert(sourcemeta::core::idna_passes_contextj(U"\u0628\u200C\u0627", 1));
// ZWJ not preceded by Virama
SOURCEMETA_CORE_IDNA_EXPORT auto idna_passes_contextj(const std::u32string_view label, const std::size_t position) noexcept -> bool

◆ idna_passes_contexto()

SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_passes_contexto ( const std::u32string_view label,
const std::size_t position ) -> bool
noexcept

Return whether the codepoint at position within label does not violate any RFC 5892 Appendix A.3-A.9 contextual rule. Returns true vacuously when the codepoint has no such rule. Returns false when position is out of range, treated as a precondition violation. See https://www.rfc-editor.org/rfc/rfc5892#appendix-A for the rules. For example:

#include <sourcemeta/core/idna.h>
#include <cassert>
assert(!sourcemeta::core::idna_passes_contexto(U"a\u00B7b", 1));
SOURCEMETA_CORE_IDNA_EXPORT auto idna_passes_contexto(const std::u32string_view label, const std::size_t position) noexcept -> bool

◆ idna_property()

SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_property ( const char32_t codepoint) -> IDNAProperty
noexcept

Return the RFC 5892 derived property of a Unicode codepoint. See https://www.rfc-editor.org/rfc/rfc5892 for the property's definition. For example:

#include <sourcemeta/core/idna.h>
#include <cassert>
sourcemeta::core::IDNAProperty::PValid);
assert(sourcemeta::core::idna_property(U'\u200D') ==
sourcemeta::core::IDNAProperty::ContextJ);
SOURCEMETA_CORE_IDNA_EXPORT auto idna_property(const char32_t codepoint) noexcept -> IDNAProperty

◆ idna_uts46_map()

SOURCEMETA_CORE_IDNA_EXPORT auto sourcemeta::core::idna_uts46_map ( const std::u32string_view input) -> std::u32string

Apply the UTS #46 mapping to input and return the result normalised to NFC. This is the mapping and normalisation half of UTS #46 processing (steps 1 and 2), performed with Nontransitional Processing and UseSTD3ASCIIRules disabled, so the four deviation characters (U+00DF, U+03C2, U+200C, U+200D) map to themselves. Following the UTS #46 Map step, disallowed codepoints are left unchanged rather than removed, so that the later per-label validity check is what rejects them (the same is true of ASCII characters outside the LDH set). Label separation and the per-label validity checks are not performed here. See https://www.unicode.org/reports/tr46/ for the algorithm. For example:

#include <sourcemeta/core/idna.h>
#include <cassert>
// Uppercase is case-folded, fullwidth digits map to ASCII
assert(sourcemeta::core::idna_uts46_map(U"EXAMPLE") == U"example");
assert(sourcemeta::core::idna_uts46_map(U"\uFF11\uFF12\uFF13") == U"123");
// Soft hyphen is ignored
assert(sourcemeta::core::idna_uts46_map(U"a\u00ADb") == U"ab");
// A disallowed codepoint is preserved for validation to reject
assert(sourcemeta::core::idna_uts46_map(U"\u0080") == U"\u0080");
SOURCEMETA_CORE_IDNA_EXPORT auto idna_uts46_map(const std::u32string_view input) -> std::u32string