DomainLiteral: duplicate S_OPENBRACKET in isNextTokenAny check (missing S_CLOSEBRACKET)

Author: ruttydmCreated Apr 9, 2026Updated Apr 9, 2026

Bug

In DomainLiteral::parse(), the nested-bracket check uses S_OPENBRACKET twice instead of S_OPENBRACKET, S_CLOSEBRACKET, so it only detects nested [ but not ] within domain literals.

Version: 4.0.4

Code

DomainLiteral.php line 49:

php
if ($this->lexer->isNextTokenAny(array(EmailLexer::S_OPENBRACKET, EmailLexer::S_OPENBRACKET))) {
    return new InvalidEmail(new ExpectingDTEXT(), $this->lexer->current->value);
}

S_OPENBRACKET (91, [) appears twice. S_CLOSEBRACKET (93, ]) is defined at EmailLexer.php line 42 and is used correctly elsewhere in the codebase (e.g., DomainPart.php line 236).

Expected

php
if ($this->lexer->isNextTokenAny(array(EmailLexer::S_OPENBRACKET, EmailLexer::S_CLOSEBRACKET))) {

Impact

This check sits inside the do { } while() loop that parses domain literal content (between [ and ]). It's meant to reject nested brackets appearing in the literal. Because S_CLOSEBRACKET is missing, a stray ] inside the domain literal content may not be caught by this check, potentially allowing malformed domain literals through validation.