mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
JPEGLoader: Fix infinite loop on incomplete data
If the image data to decode is incomplete, e.g. a corrupt image missing its last scanlines the decoder would previously keep looping for ever. By breaking out of the loop if no more scanlines were produced we can at least display the partial image up to that point.
This commit is contained in:
parent
02da288413
commit
6923008a55
Notes:
github-actions[bot]
2024-10-12 17:21:54 +00:00
Author: https://github.com/0x4261756D Commit: https://github.com/LadybirdBrowser/ladybird/commit/6923008a555 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1746
1 changed files with 17 additions and 3 deletions
|
@ -90,18 +90,29 @@ ErrorOr<void> JPEGLoadingContext::decode()
|
||||||
}
|
}
|
||||||
|
|
||||||
jpeg_start_decompress(&cinfo);
|
jpeg_start_decompress(&cinfo);
|
||||||
|
bool could_read_all_scanlines = true;
|
||||||
|
|
||||||
if (cinfo.out_color_space == JCS_EXT_BGRX) {
|
if (cinfo.out_color_space == JCS_EXT_BGRX) {
|
||||||
rgb_bitmap = TRY(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, { static_cast<int>(cinfo.output_width), static_cast<int>(cinfo.output_height) }));
|
rgb_bitmap = TRY(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, { static_cast<int>(cinfo.output_width), static_cast<int>(cinfo.output_height) }));
|
||||||
while (cinfo.output_scanline < cinfo.output_height) {
|
while (cinfo.output_scanline < cinfo.output_height) {
|
||||||
auto* row_ptr = (u8*)rgb_bitmap->scanline(cinfo.output_scanline);
|
auto* row_ptr = (u8*)rgb_bitmap->scanline(cinfo.output_scanline);
|
||||||
jpeg_read_scanlines(&cinfo, &row_ptr, 1);
|
auto out_size = jpeg_read_scanlines(&cinfo, &row_ptr, 1);
|
||||||
|
if (cinfo.output_scanline < cinfo.output_height && out_size == 0) {
|
||||||
|
dbgln("JPEG Warning: Decoding produced no more scanlines in scanline {}/{}.", cinfo.output_scanline, cinfo.output_height);
|
||||||
|
could_read_all_scanlines = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cmyk_bitmap = TRY(CMYKBitmap::create_with_size({ static_cast<int>(cinfo.output_width), static_cast<int>(cinfo.output_height) }));
|
cmyk_bitmap = TRY(CMYKBitmap::create_with_size({ static_cast<int>(cinfo.output_width), static_cast<int>(cinfo.output_height) }));
|
||||||
while (cinfo.output_scanline < cinfo.output_height) {
|
while (cinfo.output_scanline < cinfo.output_height) {
|
||||||
auto* row_ptr = (u8*)cmyk_bitmap->scanline(cinfo.output_scanline);
|
auto* row_ptr = (u8*)cmyk_bitmap->scanline(cinfo.output_scanline);
|
||||||
jpeg_read_scanlines(&cinfo, &row_ptr, 1);
|
auto out_size = jpeg_read_scanlines(&cinfo, &row_ptr, 1);
|
||||||
|
if (cinfo.output_scanline < cinfo.output_height && out_size == 0) {
|
||||||
|
dbgln("JPEG Warning: Decoding produced no more scanlines in scanline {}/{}.", cinfo.output_scanline, cinfo.output_height);
|
||||||
|
could_read_all_scanlines = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +124,10 @@ ErrorOr<void> JPEGLoadingContext::decode()
|
||||||
free(icc_data_ptr);
|
free(icc_data_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (could_read_all_scanlines)
|
||||||
jpeg_finish_decompress(&cinfo);
|
jpeg_finish_decompress(&cinfo);
|
||||||
|
else
|
||||||
|
jpeg_abort_decompress(&cinfo);
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress(&cinfo);
|
||||||
|
|
||||||
if (cmyk_bitmap && !rgb_bitmap)
|
if (cmyk_bitmap && !rgb_bitmap)
|
||||||
|
|
Loading…
Reference in a new issue