StringUtils

Git Source

Title: String Utilities Library

Provides string manipulation utilities for DotNS contracts.

Extends OpenZeppelin's Strings library with additional UTF-8 and conversion helpers.

Note: security-contact: admin@parity.io

Constants

LITE_SUFFIX_DIGITS

Number of digits in a lite-person PoP label's suffix.

The count the gateway emits, and an exact requirement here: the separator sits at a fixed offset from the end, so a one or three digit suffix is rejected. The gateway reads its own minimum, so widening it there does not widen this.

uint256 internal constant LITE_SUFFIX_DIGITS = 2

MAX_DNS_LABEL_OCTETS

Maximum number of octets in a single DNS label.

RFC 1035 caps each label at 63 octets. Enforced inside @custom:function _isDnsLabel so every public validator (@custom:function isSingleLabel, @custom:function isNamePath,

Note: function: isLitePersonLabel) inherits the bound and oversized labels never reach the registrar. A lite label bounds its stem rather than the whole string, so it reaches MAX_DNS_LABEL_OCTETS + LITE_SUFFIX_DIGITS + 1 octets. Its stem is bounded here but checked in @custom:function _isLitePersonLabel, which is stricter on charset than a DNS label: letters only.

uint256 internal constant MAX_DNS_LABEL_OCTETS = 63

LABEL_SEPARATOR

ASCII full stop separating a lite label's stem from its digit suffix.

A lite label is the only label shape in DotNS that carries a separator;

Note: function: _isDnsLabel rejects it everywhere else.

bytes1 internal constant LABEL_SEPARATOR = 0x2e

Functions

strlen

Computes the character length of a UTF-8 encoded string.

Counts Unicode code points, not bytes. Handles multi-byte UTF-8 sequences:

  • 1 byte: 0x00-0x7F (ASCII)
  • 2 bytes: 0xC0-0xDF
  • 3 bytes: 0xE0-0xEF
  • 4 bytes: 0xF0-0xF7
  • 5 bytes: 0xF8-0xFB (rare, outside Unicode standard)
  • 6 bytes: 0xFC-0xFD (rare, outside Unicode standard)
function strlen(string memory value) internal pure returns (uint256 len);

Parameters

NameTypeDescription
valuestringThe UTF-8 encoded string to measure.

Returns

NameTypeDescription
lenuint256The number of Unicode characters in the string.

isSingleLabel

Validates that s is a single canonical DNS label.

Lowercase ASCII letters, digits, and hyphen only; hyphen may not be the first or last character; length must be in (0, MAX_DNS_LABEL_OCTETS]. No dots allowed; use

Note: function: isNamePath for dotted forms. Mirrors the label rules enforced at the registrar.

function isSingleLabel(string calldata value) internal pure returns (bool isValid);

Parameters

NameTypeDescription
valuestringCandidate label.

Returns

NameTypeDescription
isValidboolTrue if value is a canonical DNS label.

isSingleLabelMemory

Memory-location helper for @custom:function isSingleLabel, used where the candidate label is produced by an upstream string transformation (e.g. the output of

Note: function: stripDigits) so callers do not need a calldata round-trip.

function isSingleLabelMemory(string memory value) internal pure returns (bool isValid);

Parameters

NameTypeDescription
valuestringCandidate label held in memory.

Returns

NameTypeDescription
isValidboolTrue if value is a canonical DNS label.

isLitePersonLabel

Validates the lite-person PoP label format: <stem>.<digits>.

A lite-person label is a stem of lowercase ASCII letters, one

Notes:

  • constant: LABEL_SEPARATOR, then exactly

  • constant: LITE_SUFFIX_DIGITS digits (e.g. joseph.42). Letters only, because the stem is the name a person chose, which is restricted to letters. How short a stem may be is policy rather than format, so it is left to the governance-reserved band in

  • function: IPopRules.classifyName. It is the only label shape in DotNS permitted to carry a separator, which is what reserves the dotted space to the gateway. A digit suffix is not exclusive: an ordinary label may end in digits, but it is measured as written and so classifies by its full length. Cross-flow priority is arbitrated on the stem, not on the whole label: a lite label's stem is reserved as a base name through

  • function: IPopRules.reserveBaseNameForPop, so joseph.42 contends with joseph. There is no flat spelling of a lite label for it to contend with.

function isLitePersonLabel(string calldata value) internal pure returns (bool isValid);

Parameters

NameTypeDescription
valuestringCandidate label.

Returns

NameTypeDescription
isValidboolTrue if value is a stem of lowercase ASCII letters followed by a separator and exactly @custom:constant LITE_SUFFIX_DIGITS digits.

isLitePersonLabelMemory

Memory-location helper for @custom:function isLitePersonLabel.

For callers holding the label in memory rather than calldata: the controller reads it back from a struct before deriving the node, and the lens reads it out of a store. Same predicate, different data location.

function isLitePersonLabelMemory(string memory value) internal pure returns (bool isValid);

Parameters

NameTypeDescription
valuestringCandidate label held in memory.

Returns

NameTypeDescription
isValidboolTrue if value is a stem of lowercase ASCII letters followed by a separator and exactly @custom:constant LITE_SUFFIX_DIGITS digits.

_isLitePersonLabel

function _isLitePersonLabel(bytes memory raw) private pure returns (bool isValid);

isPersonLabel

Validates that value is a name a person chose: lowercase ASCII letters only.

Matches the gateway's full-person label rule, which admits no digits and no hyphens, so a label outside this shape cannot have been issued. Stricter than @custom:function isSingleLabel, and it is the same rule

Note: function: isLitePersonLabel applies to a lite stem. How short a name may be is policy rather than format, so no floor is applied here.

function isPersonLabel(string calldata value) internal pure returns (bool isValid);

Parameters

NameTypeDescription
valuestringCandidate label.

Returns

NameTypeDescription
isValidboolTrue if every octet of value is a lowercase ASCII letter.

_isPersonLabel

function _isPersonLabel(
    bytes memory raw,
    uint256 start,
    uint256 end
)
    private
    pure
    returns (bool isValid);

splitLiteLabel

Splits a lite-person label <stem>.<digits> into its stem and digit suffix.

Splits at the first @custom:constant LABEL_SEPARATOR. A lite label carries exactly one separator, so the caller is expected to have run @custom:function isLitePersonLabelMemory first; a label with no separator returns the whole input as the stem and an empty suffix, which the caller's later label checks reject.

function splitLiteLabel(string memory value)
    internal
    pure
    returns (string memory stem, string memory suffix);

Parameters

NameTypeDescription
valuestringLite label held in memory, for example alice.01.

Returns

NameTypeDescription
stemstringThe label before the separator, for example alice.
suffixstringThe digit suffix after the separator, for example 01.

isNamePath

Validates that s is a dot-separated path of canonical DNS labels.

Each segment between dots must satisfy @custom:function isSingleLabel. Empty segments (leading, trailing, or consecutive dots) fail. Used when callers submit multi-label paths (e.g. alice.dot) rather than bare labels.

function isNamePath(string calldata value) internal pure returns (bool isValid);

Parameters

NameTypeDescription
valuestringCandidate name path.

Returns

NameTypeDescription
isValidboolTrue if every dot-separated segment is a canonical DNS label.

_isDnsLabel

function _isDnsLabel(
    bytes memory label,
    uint256 start,
    uint256 end
)
    private
    pure
    returns (bool isValid);

uintToString

Converts a uint256 to its decimal string representation.

Wraps OpenZeppelin's Strings.toString().

function uintToString(uint256 value) internal pure returns (string memory);

Parameters

NameTypeDescription
valueuint256The unsigned integer to convert.

Returns

NameTypeDescription
<none>stringThe decimal string representation.

addressToHex

Converts an address to its checksummed hexadecimal string representation.

Wraps OpenZeppelin's Strings.toHexString(). Returns lowercase hex with "0x" prefix.

function addressToHex(address account) internal pure returns (string memory);

Parameters

NameTypeDescription
accountaddressThe address to convert.

Returns

NameTypeDescription
<none>stringThe hexadecimal string representation (42 characters including "0x").

bytes32ToString

Converts a bytes32 value to a string, treating it as a null-terminated ASCII string.

Reads bytes until the first null byte (0x00) or end of bytes32. Useful for converting short strings stored in bytes32 back to string type.

function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory);

Parameters

NameTypeDescription
_bytes32bytes32The bytes32 value containing a null-terminated ASCII string.

Returns

NameTypeDescription
<none>stringThe extracted string (up to 32 characters).