-
Notifications
You must be signed in to change notification settings - Fork 76
Fix SIGPIPE when piping large data in magic.rs #134
Conversation
As alternative we may use / could try the library https://github.com/aahancoc/tree_magic for detecting the mime types. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for discovering and fixing this issue.
Would you mind to add this to CHANGELOG.md
and also perhaps write some little smoke tests? I think one test that calls this function with a zero-buffer of exactly the maximum buffer size and another that calls it with lets say a 2 MiB buffer of zeros, and check that neither fails, would be sufficient.
And please do rebase onto master
to fix the lint issue and make the PR build succeed.
@lunaryorn I’ll do rebasing and add some smoke tests. That makes sense for me, too. 👍 |
The method `write_all` fail with "Broken pipe (os error 32)" when the data being piped is large enough to be terminated due to SIGPIPE as the file command reads maximum 1048576 bytes from the data. See MAGIC_PARAM_BYTES_MAX in manpage libmagic(3). To workaround we extract only the first 1mb of interesting bytes that's sufficient for determining the mime-type of the image.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please edit the commit message and wrap all text at 72 or at most 80 characters, see eg these guidelines
Currently it's one long line without line breaks, and that's just impossible to read sanely in git log
.
@@ -7,6 +7,8 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html | |||
To publish a new release run `scripts/release` from the project directory. | |||
|
|||
## [Unreleased] | |||
### Fixed | |||
- Fix SIGPIPE if rendering large image >1MB (see [GH-134]). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick, it's "MiB`, because it's a binary quantity, not a decimal.
I just tried this code, and can reproduce the test failure, and it turns out that I misunderstood what this code fixes. I assumed If so I'd prefer if we just kept writing the whole buffer and specifically ignored the broken pipe error from the |
Oh. Next time I should give more attention on the formatting of my commit message. |
Yes. Also it's good to know that Rust doesn't let the application crash :-)
I can offer an alternative implementation to workaround the problem by bypassing the process
.stdin
.as_mut()
.expect("Forgot to pipe stdin?")
.write_all(buffer)
.or_else(|e| {
match e.kind() {
ErrorKind::BrokenPipe => Ok(()),
_ => Err(e)
}
})?; It doesn't rely on the magic variables anymore. If you dislike the alternative, I'd appreciate to hear your reason and feel free to close the PR according. Thanks. |
@fspillner Yes, that's what I meant; I think I like this more :) |
Some file implementations, notably the libmagic one typically installed on Linux, close their stdin when they read enough data to determine the file type. This triggers a broken pipe error on the rust side which we can ignore. That's safer and less complicated than figuring out how much data we can pipe safely to file. See GH-134
Some file implementations, notably the libmagic one typically installed on Linux, close their stdin when they read enough data to determine the file type. This triggers a broken pipe error on the rust side which we can ignore. That's safer and less complicated than figuring out how much data we can pipe safely to file. See GH-134
Hi.
Here the second separate PR to fix the rendering of large image files, if the large image (>1MB) is piped through the file command in
src/magic.rs
:The method
write_all
fail with the error "Broken pipe (os error 32)", when the data being piped is large enough to be terminated due to SIGPIPE. To workaround, we just extract only the first 4kb of interesting bytes that's sufficient for determining the mime-type of the image.I could reproduce the behavior in my fish shell:
and with a large image (>1MB):
A
SIGPIPE
signal is sent by Kernel and the command is terminated with pipe status 141. My wild guess is that the commandfile
closes the stdin after reading the 1MB bytes. I need more research on the topic around pipes.WDYT?
Fabian
Update:
Running
strace
on file command and found out that the commandfile
stops reading the bytes at 1048576 bytes, here a extract from strace output:In the man of
libmagic
you find the documentation:So, the
file
command reads while theMAGIC_PARAM_BYTES_MAX
is reached and closes the file descriptor.