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
CRLFAtTheEnd is 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.
Bug
In
FoldingWhiteSpace::checkCRLFInFWS(), theCRLFAtTheEnderror 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.phplines 61–77:Analysis
isNextTokenAny()is read-only — it checks$this->lookaheadwithout advancing the lexer position (confirmed indoctrine/lexerAbstractLexer::isNextTokenAny(), which only reads$this->lookahead->isA()). The only method that advances the lexer ismoveNext().Since both conditions on lines 67 and 72 check the same lookahead token with the same parameters:
CRLFX2, never reaches line 72CRLFAtTheEndis never returnedThe existing comment on line 71 confirms this: "this has no coverage. Condition is repeated from above one"
Impact
The
CRLFAtTheEndvalidation is dead — emails with CRLF at the end of folding whitespace that should be rejected withCRLFAtTheEndare 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.