FoldingWhiteSpace: CRLFAtTheEnd check is unreachable dead code
Bug
In FoldingWhiteSpace::checkCRLFInFWS(), the CRLFAtTheEnd error can never be returned because the exact same condition is checked twice in sequence, with no lexer advancement between them.
Version: 4.0.4
Code
FoldingWhiteSpace.php lines 61–77:
protected function checkCRLFInFWS(): Result
{
if (!$this->lexer->current->isA(EmailLexer::CRLF)) {
return new ValidEmail();
}
if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) {
return new InvalidEmail(new CRLFX2(), $this->lexer->current->value);
}
//this has no coverage. Condition is repeated from above one
if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) {
return new InvalidEmail(new CRLFAtTheEnd(), $this->lexer->current->value);
}
return new ValidEmail();
}Analysis
isNextTokenAny() is read-only — it checks $this->lookahead without advancing the lexer position (confirmed in doctrine/lexer AbstractLexer::isNextTokenAny(), which only reads $this->lookahead->isA()). The only method that advances the lexer is moveNext().
Since both conditions on lines 67 and 72 check the same lookahead token with the same parameters:
- If line 67 is true (next token is NOT SP/HTAB) → returns
CRLFX2, never reaches line 72 - If line 67 is false (next token IS SP/HTAB) → line 72 is also false, so
CRLFAtTheEndis never returned
The existing comment on line 71 confirms this: "this has no coverage. Condition is repeated from above one"
Impact
The CRLFAtTheEnd validation is dead — emails with CRLF at the end of folding whitespace that should be rejected with CRLFAtTheEnd are either rejected with the wrong reason (CRLFX2) or accepted as valid.
A moveNext() call was likely intended between the two checks to advance to the next token.
Source: egulias/EmailValidator