Today I've received an email without body part causing following Error (exception):
Error: Typed property ZBateson\MailMimeParser\Parser\PartBuilder::$streamPartEndPos must not be accessed before initialization
The error is reproducible with this test message:
Return-Path: <test@host.tld>
Message-ID: id
And this unit Test (if added to \ZBateson\MailMimeParser\IntegrationTests\EmailFunctionalTest) and stored as invalid-no-body.txt:
public function testParseEmailInvalidNoBody() : void
{
$messagePath = $this->messageDir . '/invalid-no-body.txt';
$handle = \fopen($messagePath, 'r');
$message = $this->parser->parse($handle, true);
self::assertEquals(file_get_contents($messagePath), (string) $message);
}
It throws the error at (string) $message. I tried to find the root cause, but I couldn't. The parsing flow is kinda complex and nested. But that's what I figured out so far:
- The message is identified as non-mime-message and in the
\ZBateson\MailMimeParser\Parser\NonMimeParserService::parseContent() method the resource handle becomes empty and thus has neither $streamPartEndPos nor $streamPartStartPos initiated.
- The resource handle is not always empty, but it somehow seems to become empty in the
\ZBateson\MailMimeParser\Parser\Part\ParserPartStreamContainer::requestParsedStream() method, when $this->parserProxy->parseAll() is called.
My first fix attempt was to make sure that $streamPartEndPos and $streamPartStartPos have 0 as default value and thus cannot be null. To be honest, these properties should be part of the constructor, because they should never be null. This also would help finding the root cause of this issue easier. However, making sure that $streamPartEndPos and $streamPartStartPos are never null fixed that the Error was thrown, but the empty stream resulted in an empty message, which doesn't fix the bug. The main issue is that the resource handle becomes empty in the parsing process.
My mail server had no problem handling those "broken" mime messages without body part via IMAP. But I store them as .eml files on my disk and index them in my application and that's when I encounter the described error. Emails without body are also sometimes attached in mailer daemons. In other words, these "broken" emails exist in the real world and should be parsable as mime messages with an empty body and valid headers. At least the latter is the case.
Maybe some maintainer with better understanding of the codebase and parsing workflow can help me to find the root cause to fix the issue? I didn't want to add workarounds like checking if the resource handle is empty, and if so to generate a new handle from the initial stream. This feels like a dirty hack and shouldn't be the solution.
Thank you in advance!
Today I've received an email without body part causing following Error (exception):
The error is reproducible with this test message:
And this unit Test (if added to
\ZBateson\MailMimeParser\IntegrationTests\EmailFunctionalTest) and stored asinvalid-no-body.txt:It throws the error at
(string) $message. I tried to find the root cause, but I couldn't. The parsing flow is kinda complex and nested. But that's what I figured out so far:\ZBateson\MailMimeParser\Parser\NonMimeParserService::parseContent()method the resource handle becomes empty and thus has neither $streamPartEndPos nor $streamPartStartPos initiated.\ZBateson\MailMimeParser\Parser\Part\ParserPartStreamContainer::requestParsedStream()method, when$this->parserProxy->parseAll()is called.My first fix attempt was to make sure that
$streamPartEndPosand$streamPartStartPoshave 0 as default value and thus cannot be null. To be honest, these properties should be part of the constructor, because they should never be null. This also would help finding the root cause of this issue easier. However, making sure that$streamPartEndPosand$streamPartStartPosare never null fixed that the Error was thrown, but the empty stream resulted in an empty message, which doesn't fix the bug. The main issue is that the resource handle becomes empty in the parsing process.My mail server had no problem handling those "broken" mime messages without body part via IMAP. But I store them as
.emlfiles on my disk and index them in my application and that's when I encounter the described error. Emails without body are also sometimes attached in mailer daemons. In other words, these "broken" emails exist in the real world and should be parsable as mime messages with an empty body and valid headers. At least the latter is the case.Maybe some maintainer with better understanding of the codebase and parsing workflow can help me to find the root cause to fix the issue? I didn't want to add workarounds like checking if the resource handle is empty, and if so to generate a new handle from the initial stream. This feels like a dirty hack and shouldn't be the solution.
Thank you in advance!