This happens in image::open
No panic
Panic
image::open() the image from this url:
https://cdn.aboutyou.de/file/90084b3edf1b97f95ca05c245721d554?width=2000&height=2000
produces this stack trace:
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `2800000`,
right: `2816000`: destination and source slices have different lengths', /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/macros/mod.rs:23:13
stack backtrace:
0: backtrace::backtrace::libunwind::trace
at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
1: backtrace::backtrace::trace_unsynchronized
at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
2: std::sys_common::backtrace::_print_fmt
at src/libstd/sys_common/backtrace.rs:84
3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
at src/libstd/sys_common/backtrace.rs:61
4: core::fmt::write
at src/libcore/fmt/mod.rs:1025
5: std::io::Write::write_fmt
at src/libstd/io/mod.rs:1426
6: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:65
7: std::sys_common::backtrace::print
at src/libstd/sys_common/backtrace.rs:50
8: std::panicking::default_hook::{{closure}}
at src/libstd/panicking.rs:193
9: std::panicking::default_hook
at src/libstd/panicking.rs:210
10: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:471
11: rust_begin_unwind
at src/libstd/panicking.rs:375
12: core::panicking::panic_fmt
at src/libcore/panicking.rs:84
13: core::slice::<impl [T]>::copy_from_slice
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/macros/mod.rs:21
14: <image::jpeg::decoder::JpegDecoder<R> as image::image::ImageDecoder>::read_image
at /Users/kosta/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.0/./src/jpeg/decoder.rs:82
15: image::image::decoder_to_vec
at /Users/kosta/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.0/./src/image.rs:293
16: image::dynimage::decoder_to_image
at /Users/kosta/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.0/./src/dynimage.rs:878
17: image::dynimage::DynamicImage::from_decoder
at /Users/kosta/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.0/./src/dynimage.rs:185
18: image::io::free_functions::load
at /Users/kosta/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.0/./src/io/free_functions.rs:68
19: image::io::free_functions::open_impl
at /Users/kosta/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.0/./src/io/free_functions.rs:51
20: image::dynimage::open
at /Users/kosta/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.0/./src/dynimage.rs:953
21: image_panic::main
at src/main.rs:2
22: std::rt::lang_start::{{closure}}
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/rt.rs:67
23: std::rt::lang_start_internal::{{closure}}
at src/libstd/rt.rs:52
24: std::panicking::try::do_call
at src/libstd/panicking.rs:292
25: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:78
26: std::panicking::try
at src/libstd/panicking.rs:270
27: std::panic::catch_unwind
at src/libstd/panic.rs:394
28: std::rt::lang_start_internal
at src/libstd/rt.rs:51
29: std::rt::lang_start
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/rt.rs:67
30: image_panic::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
The buffer left has correct size (1,400px 脳 2,000px) so the fault is likely in jpeg-decoder.
The issue #1165 identified that in this function the clone_from_slice fails. The prior assert_eq appears to validate that sizes match but apparently the size of the final decode block does not equal the one calculated from total_bytes.
Note that jpeg is split into blocks of 8x8 pixels. My current best guess would be that some function incorrectly calculates the number of such blocks for some images. Note that the difference between the expected sizes in both this issue and in #1165 is divisble by 64.
@kosta Is this your image, i.e. do you have some clarify on copyright? We'd like to add it as a test case to jpeg-decoder if possible.
I'm sorry this is an image from a german online shop that I tried to process. I don't have any insights on their copyright.
Thanks for the clarification then, that's what I expected.
I tried to reproduce this issue but I can't. The image for the link above (sha1: 293b2f338204fc398ecbcc9ee06aa1d6f806d58a) is decoded correctly by both image-rs and the underlying jpeg-decoder. Is there something I am missing ?
Given the size of the image, it would have been affected by https://github.com/image-rs/jpeg-decoder/issues/148 if it were encoded as a grayscale JPEG with a horizontal sampling factor of 2. The bug would then have returned a buffer of size ceil(1400/16)*16 脳 2,000 = 2816000, which is exactly what is reported here.
And since the image contains no color, imagemagick defaults to encoding it as grayscale when it goes through it...
So, there is no proof, but I would bet that the exact image file that caused this bug is not the one referenced...
@lovasoa The image has indeed changed, the original broken image has a sha1 of 4873b0d65e3cc096b95e667bd637fb1835d37376 while now the linked image has a sha1 of 293b2f338204fc398ecbcc9ee06aa1d6f806d58a.
Because of copyright issues, I can't provide a copy of the original affected image. Is there something I can do myself to confirm your suspicions. Maybe provide me with a list of information about the image I can collect?
Also there is a second image that seems to trigger a similar bug, but definitely has color. Not sure if it's the same issue. But same copyright problem there sadly.
Thanks for replying. What may be helpful is to paste the result of identify -verbose yourimage.jpg together with the exact error message and stack trace returned by image-rs.
Apparently I was incorrect about assuming that the second image had colors ...
$ identify broken.jpg
broken.jpg JPEG 1400x2000 1400x2000+0+0 8-bit Gray 256c 525431B 0.000u 0:00.000
$ identify broken2.jpg
broken2.jpg JPEG 1400x2000 1400x2000+0+0 8-bit Gray 256c 51833B 0.000u 0:00.000
Sorry, forgot the -verbose: https://gist.github.com/FSMaxB-dooshop/378a8e59a394e601eedb9744227a6c6d
Backtrace 1 (broken.jpg):
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `2800000`,
right: `2816000`: destination and source slices have different lengths', /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libcore/macros/mod.rs:18:13
stack backtrace:
0: 0x55df5c409f04 - backtrace::backtrace::libunwind::trace::h5ae3454ebe40b621
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.44/src/backtrace/libunwind.rs:86
1: 0x55df5c409f04 - backtrace::backtrace::trace_unsynchronized::hbf6f267a483fb2c0
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.44/src/backtrace/mod.rs:66
2: 0x55df5c409f04 - std::sys_common::backtrace::_print_fmt::h37755015d94b9085
at src/libstd/sys_common/backtrace.rs:78
3: 0x55df5c409f04 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h0561c8cd3569b40d
at src/libstd/sys_common/backtrace.rs:59
4: 0x55df5c425c7c - core::fmt::write::h86a597a35d48a212
at src/libcore/fmt/mod.rs:1063
5: 0x55df5c407803 - std::io::Write::write_fmt::h73d9dc0f29eefe48
at src/libstd/io/mod.rs:1426
6: 0x55df5c40c6f5 - std::sys_common::backtrace::_print::h6c60c5ee09af0233
at src/libstd/sys_common/backtrace.rs:62
7: 0x55df5c40c6f5 - std::sys_common::backtrace::print::hf9d1db01634f9b2a
at src/libstd/sys_common/backtrace.rs:49
8: 0x55df5c40c6f5 - std::panicking::default_hook::{{closure}}::h1db9298dd213ae95
at src/libstd/panicking.rs:204
9: 0x55df5c40c442 - std::panicking::default_hook::h3272faf6cc91fd2e
at src/libstd/panicking.rs:224
10: 0x55df5c40cd52 - std::panicking::rust_panic_with_hook::hb976084785e50594
at src/libstd/panicking.rs:470
11: 0x55df5c40c93b - rust_begin_unwind
at src/libstd/panicking.rs:378
12: 0x55df5c424ff1 - core::panicking::panic_fmt::h45f7d6868edb5678
at src/libcore/panicking.rs:85
13: 0x55df5c2e1c80 - core::slice::<impl [T]>::copy_from_slice::h166b79d1c4b27124
at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libcore/macros/mod.rs:16
14: 0x55df5c23b7ff - <image::jpeg::decoder::JpegDecoder<R> as image::image::ImageDecoder>::read_image::h79d5a5931f91c3fb
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/jpeg/decoder.rs:84
15: 0x55df5c228a3e - image::image::decoder_to_vec::hab4af7f73b5a1974
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/image.rs:309
16: 0x55df5c1d6c43 - image::dynimage::decoder_to_image::hdc56dfa8c4592235
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/dynimage.rs:898
17: 0x55df5c1c6e6c - image::dynimage::DynamicImage::from_decoder::h0793d3f0f2e6489f
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/dynimage.rs:190
18: 0x55df5c1880ab - image::io::free_functions::load::h16d4e161c556e230
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/io/free_functions.rs:70
19: 0x55df5c187906 - image::io::free_functions::open_impl::he343f2731c808c48
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/io/free_functions.rs:53
20: 0x55df5c17f5cc - image::dynimage::open::h6447dcc9ffd80969
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/dynimage.rs:978
21: 0x55df5c17f310 - reproducer::main::hec48884307718fca
at src/main.rs:2
22: 0x55df5c17f55b - std::rt::lang_start::{{closure}}::hbad75d72ef3b83e5
at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libstd/rt.rs:67
23: 0x55df5c40c813 - std::rt::lang_start_internal::{{closure}}::hc0a1280e68ffc5da
at src/libstd/rt.rs:52
24: 0x55df5c40c813 - std::panicking::try::do_call::h1d43a4d29f303ef5
at src/libstd/panicking.rs:303
25: 0x55df5c40f617 - __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:86
26: 0x55df5c40d33c - std::panicking::try::h5ef738612ab0072d
at src/libstd/panicking.rs:281
27: 0x55df5c40d33c - std::panic::catch_unwind::h1df9a04c7f1c6fc3
at src/libstd/panic.rs:394
28: 0x55df5c40d33c - std::rt::lang_start_internal::h97d4af4643f4b0e4
at src/libstd/rt.rs:51
29: 0x55df5c17f537 - std::rt::lang_start::h4d6f8107305c5feb
at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libstd/rt.rs:67
30: 0x55df5c17f38a - main
31: 0x7fd3054bc023 - __libc_start_main
32: 0x55df5c17f15e - _start
33: 0x0 - <unknown>
broken2.jpg:
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `2800000`,
right: `2816000`: destination and source slices have different lengths', /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libcore/macros/mod.rs:18:13
stack backtrace:
0: 0x55b47b213f04 - backtrace::backtrace::libunwind::trace::h5ae3454ebe40b621
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.44/src/backtrace/libunwind.rs:86
1: 0x55b47b213f04 - backtrace::backtrace::trace_unsynchronized::hbf6f267a483fb2c0
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.44/src/backtrace/mod.rs:66
2: 0x55b47b213f04 - std::sys_common::backtrace::_print_fmt::h37755015d94b9085
at src/libstd/sys_common/backtrace.rs:78
3: 0x55b47b213f04 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h0561c8cd3569b40d
at src/libstd/sys_common/backtrace.rs:59
4: 0x55b47b22fc7c - core::fmt::write::h86a597a35d48a212
at src/libcore/fmt/mod.rs:1063
5: 0x55b47b211803 - std::io::Write::write_fmt::h73d9dc0f29eefe48
at src/libstd/io/mod.rs:1426
6: 0x55b47b2166f5 - std::sys_common::backtrace::_print::h6c60c5ee09af0233
at src/libstd/sys_common/backtrace.rs:62
7: 0x55b47b2166f5 - std::sys_common::backtrace::print::hf9d1db01634f9b2a
at src/libstd/sys_common/backtrace.rs:49
8: 0x55b47b2166f5 - std::panicking::default_hook::{{closure}}::h1db9298dd213ae95
at src/libstd/panicking.rs:204
9: 0x55b47b216442 - std::panicking::default_hook::h3272faf6cc91fd2e
at src/libstd/panicking.rs:224
10: 0x55b47b216d52 - std::panicking::rust_panic_with_hook::hb976084785e50594
at src/libstd/panicking.rs:470
11: 0x55b47b21693b - rust_begin_unwind
at src/libstd/panicking.rs:378
12: 0x55b47b22eff1 - core::panicking::panic_fmt::h45f7d6868edb5678
at src/libcore/panicking.rs:85
13: 0x55b47b0ebc80 - core::slice::<impl [T]>::copy_from_slice::h166b79d1c4b27124
at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libcore/macros/mod.rs:16
14: 0x55b47b0457ff - <image::jpeg::decoder::JpegDecoder<R> as image::image::ImageDecoder>::read_image::h79d5a5931f91c3fb
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/jpeg/decoder.rs:84
15: 0x55b47b032a3e - image::image::decoder_to_vec::hab4af7f73b5a1974
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/image.rs:309
16: 0x55b47afe0c43 - image::dynimage::decoder_to_image::hdc56dfa8c4592235
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/dynimage.rs:898
17: 0x55b47afd0e6c - image::dynimage::DynamicImage::from_decoder::h0793d3f0f2e6489f
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/dynimage.rs:190
18: 0x55b47af920ab - image::io::free_functions::load::h16d4e161c556e230
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/io/free_functions.rs:70
19: 0x55b47af91906 - image::io::free_functions::open_impl::he343f2731c808c48
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/io/free_functions.rs:53
20: 0x55b47af895cc - image::dynimage::open::h6447dcc9ffd80969
at /home/max/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.4/./src/dynimage.rs:978
21: 0x55b47af89310 - reproducer::main::hec48884307718fca
at src/main.rs:2
22: 0x55b47af8955b - std::rt::lang_start::{{closure}}::hbad75d72ef3b83e5
at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libstd/rt.rs:67
23: 0x55b47b216813 - std::rt::lang_start_internal::{{closure}}::hc0a1280e68ffc5da
at src/libstd/rt.rs:52
24: 0x55b47b216813 - std::panicking::try::do_call::h1d43a4d29f303ef5
at src/libstd/panicking.rs:303
25: 0x55b47b219617 - __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:86
26: 0x55b47b21733c - std::panicking::try::h5ef738612ab0072d
at src/libstd/panicking.rs:281
27: 0x55b47b21733c - std::panic::catch_unwind::h1df9a04c7f1c6fc3
at src/libstd/panic.rs:394
28: 0x55b47b21733c - std::rt::lang_start_internal::h97d4af4643f4b0e4
at src/libstd/rt.rs:51
29: 0x55b47af89537 - std::rt::lang_start::h4d6f8107305c5feb
at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libstd/rt.rs:67
30: 0x55b47af8938a - main
31: 0x7fda2a63f023 - __libc_start_main
32: 0x55b47af8915e - _start
33: 0x0 - <unknown>
Good news: I just used Cargo's patch feature to confirm that the latest master of jpeg-decoder doesn't have the issue anymore! (https://github.com/image-rs/jpeg-decoder.git#0920c4c506d2efbc58c5a1a03879e0eb66eb1200).
Marking as fixed then, with release 0.1.19. Run cargo update -p jpeg-decoder to receive the fix.
Thanks a lot!
Sorry for being such a bad bug reporter - but thank you for fixing this bug!
Most helpful comment
Good news: I just used
Cargo'spatchfeature to confirm that the latest master ofjpeg-decoderdoesn't have the issue anymore! (https://github.com/image-rs/jpeg-decoder.git#0920c4c506d2efbc58c5a1a03879e0eb66eb1200).