abonander / multipart

A backend-agnostic extension for file uploads in HTTP libraries for Rust
MIT License
190 stars 93 forks source link

"\r\n" straddling the buffer end is erroneously sent as part of the part's contents. #139

Open ppentchev opened 2 years ago

ppentchev commented 2 years ago

Hi,

First of all, thanks for writing and maintaining the multipart crate!

I ran into a problem where the checksum calculated over a file sent over HTTP would be wrong. It turned out that warp (which uses multipart) gave me a form field containing two bytes more than expected - the CR/LF at the end of the line before the boundary. It only happened for a certain file, not for many, many others.

I believe that the problem lies in the way multipart performs the "are the two bytes immediately preceding the --boundary sequence CR and LF?" check in the case when the CR has been at the very end of the previous buffer, and the LF is just at the start of this one. In that case, the --boundary sequence is found at position 1, but the CR/LF check fails, so multipart returns the LF as the last character of the form part (just as it had returned the CR at the end of the previous portion).

You can see a demonstration of this problem at https://github.com/ppentchev/multipart/commit/8ac5ed272753a05c9bae11a8ce0e924ec26cea1b; unfortunately, I do not have a patch right now, since I'm not entirely sure what the best way to fix this would be. I believe a possible solution would be to check for CR at the end of a buffer and either hold onto it until the possible LF--boundary arrives next time, or only hold onto the CR itself. If this sounds sensible to you, I could try to implement it, but I'd like to hear your thoughts on it first.

Thanks in advance for looking at this, and keep up the great work!

G'luck, Peter