Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: binary files as part are corrupted when stripping carriage returns #26

Open
wants to merge 2 commits into
base: 2.9.x
Choose a base branch
from

Conversation

pgmillon
Copy link

@pgmillon pgmillon commented Apr 4, 2022

Q A
Documentation no
Bugfix yes
BC Break no
New Feature no
RFC no
QA no

Description

When using a simple PNG binary as part of a message, the carriage return characters are ripped off, corrupting the binary.
Not ripping the carriage return characters have an impact in the parts splitting that was updated to use preg_match + PREG_OFFSET_CAPTURE as a replacement to strpos.
This was done the support either \r\n or \n with a regex rather than a more complex approach.
Working with a binary file highlighted the line feed that is added while reading each part, this was removed too a/ to avoid binary corruption and b/ a mime with no line feed shouldn't magically have one when reading.
A unit test was added to ensure further support of binaries.

Copy link
Member

@Ocramius Ocramius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lacking the ability to evaluate this diff, will ask for a review by other maintainers

test/MimeTest.php Show resolved Hide resolved
. 'Content-Type: text/plain; charset=UTF-8' . "\n"
. 'Content-Transfer-Encoding: ' . $encoding . "\n"
. "\n"
. $result . "\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above: changes to pre-existing test probably hiding a BC break 🤔

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand your concern, but don't have a clear answer.
Ripping-off carriage returns is harmful to binaries but people might have built solutions of their own to mitigate it and this fix might break them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH, if that's how things are, that would be an https://xkcd.com/1172/ :D

workflow_2x

I just want a second review by somebody else, but if it's really like that, the bugfix is valid, and to be merged with the test changes too 👍

@Ocramius Ocramius added Bug Something isn't working Awaiting Maintainer Response labels Apr 4, 2022
@Ocramius Ocramius added this to the 2.10.0 milestone Apr 4, 2022
@Ocramius
Copy link
Member

Ocramius commented Apr 4, 2022

@pgmillon it's possible that this, being a bugfix, should go to 2.9.x

@Ocramius Ocramius requested a review from a team April 4, 2022 16:26
@pgmillon
Copy link
Author

pgmillon commented Apr 4, 2022

Hi,
I wasn't sure how you deal with bugfixes, sorry.
If you pull bugfixes from "legacy" branches into the main branch or if you "backport" from main into legacy branches.
I can update this PR for 2.9.x, as you prefer.

@Ocramius
Copy link
Member

Ocramius commented Apr 4, 2022

We merge up from oldstable branches to latest branches.

Since the last release is 2.9.1, I'd expect this to land in 2.9.2, therefore 2.9.x target branch.

We don't merge regular bugs into older branches, since they need to be security issues, in order to qualify for that :)

EDIT: I changed the base branch, but your commit will need to probably be cherry-picked on top of that, and then force-pushed here, so extraneous commits are gone.

@Ocramius Ocramius changed the base branch from 2.10.x to 2.9.x April 4, 2022 16:32
@Ocramius Ocramius modified the milestones: 2.10.0, 2.9.2 Apr 4, 2022
@pgmillon
Copy link
Author

pgmillon commented Apr 4, 2022

Should be fine for 2.9.x now.

@pgmillon
Copy link
Author

pgmillon commented Apr 4, 2022

Wait, I just found another bug : if the message sender uses \r\n to generate the message rather than just \n, then the splitMime is not working correctly and leaving a lonely \r.

@pgmillon
Copy link
Author

pgmillon commented Apr 4, 2022

There we go : in my original fix I assumed sender's EOL was \n but when testing with a server that was using \r\n, I noticed the intend to prevent binaries corruption was not met because of a trailing \r.
I added a sender EOL detection to fix the parts splitting which now works fine with binaries.

@pgmillon
Copy link
Author

Hi,
any chance to get that fix merged ? I'm waiting for it to cut a new release of a library I work on.
Thanks.

Copy link
Member

@weierophinney weierophinney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes make sense to me. While I have concerns about the test changes, your arguments for making them make sense, and the liklihood of breakage for users is limited to those who are already pre-processing parts on their own — which will primarily be limited to those trying to fix this very issue.

My main feedback is that I think you should make a few changes to make the "what" more clear: what you are capturing, what behavior you are testing, etc.

throw new Exception\RuntimeException('Not a valid Mime Message: End Missing');
}

// the remaining part also needs to be parsed:
$res[] = substr($body, $start, $p - $start);
$res[] = substr($body, $start, $matches[0][1] - $start - strlen($serverEOL));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does $matches[0][1] represent? Can you memoize it into a variable with a descriptive name, please?

@@ -205,4 +205,20 @@ public function testSetContentRaisesInvalidArgumentExceptionForInvalidContentTyp
$this->expectException(Mime\Exception\InvalidArgumentException::class);
$part->setContent($content);
}

public function testBinaryPart()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give this a better name: testBinaryPartsAreCreatedAndParsedWithoutLoss() or similar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting Author Updates Bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants