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
Handle NULL buffer when discarding rows #182
Conversation
| @@ -132,6 +132,11 @@ post_process_1pass (j_decompress_ptr cinfo, | |||
| my_post_ptr post = (my_post_ptr) cinfo->post; | |||
| JDIMENSION num_rows, max_rows; | |||
|
|
|||
| /* read_and_discard_scanlines may call it with rows "available", but no buffer */ | |||
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.
That seems kinda iffy of read_and_discard_scanlines. Is it actually intended to do that?
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.
It is iffy, but I don't know that function. I suppose NULL works well for discarding :)
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.
Looking at this, it seems like it's a bit of a hack anyway, so I guess the check is OK. :/
jdpostct.c
Outdated
| @@ -132,6 +132,11 @@ post_process_1pass (j_decompress_ptr cinfo, | |||
| my_post_ptr post = (my_post_ptr) cinfo->post; | |||
| JDIMENSION num_rows, max_rows; | |||
|
|
|||
| /* read_and_discard_scanlines may call it with rows "available", but no buffer */ | |||
| if (!output_buf) { | |||
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.
NIT: libjpeg style is to use (buf == NULL) (probably because of some mythical system where this will fail due to NULL being implementation defined as a a type of zero value).
jquant1.c
Outdated
| @@ -531,6 +531,10 @@ quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, | |||
| JDIMENSION col; | |||
| JDIMENSION width = cinfo->output_width; | |||
|
|
|||
| if (!output_buf && num_rows) { | |||
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.
Ditto.
|
@mattsarett any comments? |
| @@ -531,6 +531,10 @@ quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, | |||
| JDIMENSION col; | |||
| JDIMENSION width = cinfo->output_width; | |||
|
|
|||
| if (output_buf == NULL && num_rows) { | |||
| ERREXIT(cinfo, JERR_BAD_PARAM); | |||
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.
I do not see JERR_BAD_PARAM defined, am I missing something?
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.
Indeed, I forgot to include it in the patch. Fixed.
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!
|
Do I need another commit to fix 1.5.2? https://bugzilla.suse.com/show_bug.cgi?id=1062937#c4 |
|
I'm not sure if that question was for me, but: this PR fixes the issue in the Suse bugzilla. It should be compatible with 1.5.2 release branch, and probably should be cherry-picked to that branch too. |
|
@pornel, apologize I had not been clear. When I apply this patch to 1.5.2, the command does not crash anymore for the first test case. For the second test case though, it still crashes with the backtrace I referenced. |
|
I see. I'll have a look. |
|
Thanks, let me know if I can help. |
|
Hi, guys. I didn't write the feature in question, and apparently the author (a former Google employee) is now working elsewhere. I have a grant from Mozilla that I can use to look into this, but I need to clear some other things from my plate first. It seems like I'm going to need to really dig into the issue and re-examine some aspects of this feature, and probably design better unit tests to guard against this sort of thing in the future. I'll keep you posted. |
|
Thank you, guys. |
|
Your patch was unfortunately insufficient to address all facets of the bug. Now that I have partial image decompression working with GIF output files, I was able to reproduce this bug with all of the various color quantization functions by passing various switches to djpeg. The root cause is that |
- Introduce a partial image decompression regression test script that validates the correctness of jpeg_skip_scanlines() and jpeg_crop_scanlines() for a variety of cropping regions and libjpeg settings. This regression test catches the following issues: #182, fixed in 5bc43c7 #237, fixed in 6e95c08 #244, fixed in 398c1e9 #441, fully fixed in this commit It does not catch the following issues: #194, fixed in 773040f #244 (additional segfault), fixed in 9120a24 - Modify the libjpeg-turbo regression test suite (make test) so that it checks for the issue reported in #441 (segfault in jpeg_skip_scanlines() when used with 4:2:0 merged upsampling/color conversion.) - Fix issues in jpeg_skip_scanlines() that caused incorrect output with h2v2 (4:2:0) merged upsampling/color conversion. The previous commit fixed the segfault reported in #441, but that was a symptom of a larger problem. Because merged 4:2:0 upsampling uses a "spare row" buffer, it is necessary to allow the upsampler to run when skipping rows (fancy 4:2:0 upsampling, which uses context rows, also requires this.) Otherwise, if skipping starts at an odd-numbered row, the output image will be incorrect. - Throw an error if jpeg_skip_scanlines() is called with two-pass color quantization enabled. With two-pass color quantization, the first pass occurs within jpeg_start_decompress(), so subsequent calls to jpeg_skip_scanlines() interfere with the multipass state and prevent the second pass from occurring during subsequent calls to jpeg_read_scanlines().
- Introduce a partial image decompression regression test script that validates the correctness of jpeg_skip_scanlines() and jpeg_crop_scanlines() for a variety of cropping regions and libjpeg settings. This regression test catches the following issues: #182, fixed in 5bc43c7 #237, fixed in 6e95c08 #244, fixed in 398c1e9 #441, fully fixed in this commit It does not catch the following issues: #194, fixed in 773040f #244 (additional segfault), fixed in 9120a24 - Modify the libjpeg-turbo regression test suite (make test) so that it checks for the issue reported in #441 (segfault in jpeg_skip_scanlines() when used with 4:2:0 merged upsampling/color conversion.) - Fix issues in jpeg_skip_scanlines() that caused incorrect output with h2v2 (4:2:0) merged upsampling/color conversion. The previous commit fixed the segfault reported in #441, but that was a symptom of a larger problem. Because merged 4:2:0 upsampling uses a "spare row" buffer, it is necessary to allow the upsampler to run when skipping rows (fancy 4:2:0 upsampling, which uses context rows, also requires this.) Otherwise, if skipping starts at an odd-numbered row, the output image will be incorrect. - Throw an error if jpeg_skip_scanlines() is called with two-pass color quantization enabled. With two-pass color quantization, the first pass occurs within jpeg_start_decompress(), so subsequent calls to jpeg_skip_scanlines() interfere with the multipass state and prevent the second pass from occurring during subsequent calls to jpeg_read_scanlines().
I've got a report about a crash:
mozilla/mozjpeg#268
I've handled in the function that crashed (jquant1.c) as well as up the stack in the function that was the real cause of it (
read_and_discard_scanlinesusesNULLbuffer and expects that to be handled gracefully).