catch stoul exceptions in CanonMakerNote print0x000a/print0x000c (backport #9320) - #9372
catch stoul exceptions in CanonMakerNote print0x000a/print0x000c (backport #9320)#9372mergify[bot] wants to merge 3 commits into
Conversation
|
Cherry-pick of f62ab78 has failed: To fix up this pull request, you can check it out locally. See documentation: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally |
05131c3 to
5502e98
Compare
| is >> l; | ||
| return os << std::setw(4) << std::setfill('0') << std::hex << ((l & 0xffff0000) >> 16) << std::setw(5) | ||
| << std::setfill('0') << std::dec << (l & 0x0000ffff); | ||
| } catch (const std::logic_error&) { |
There was a problem hiding this comment.
std::istringstream seems to throw only std::ios_base::failure, so this should perhaps be the base std::system_error?
There was a problem hiding this comment.
I can't even find any documentation that says what exceptions it might throw! But I did find this, which looks like a simpler solution: https://en.cppreference.com/cpp/io/basic_ios/exceptions. So I think we can just do this and it won't throw any exceptions:
is.exceptions(0);There was a problem hiding this comment.
I can't even find any documentation that says what exceptions it might throw!
See https://en.cppreference.com/cpp/io/ios_base/failure
I'm fine with either masking or catching std::system_error.
There was a problem hiding this comment.
Btw https://cplusplus.com/reference/ios/ios/exceptions/ says the mask is 0 by default, so this PR might even be unnecessary on 0.28.x?
There was a problem hiding this comment.
I just tested it (using #9397) and it looks like std::logic_error is correct. When I tried replacing it with std::system_error the exception didn't get caught.
gdb) run
Starting program: /home/kev/work/exiv2b/build/bin/exiv2 -pa /home/kev/work/exiv2b/test/data/pr_9320.jpg
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, Exiv2::Internal::CanonMakerNote::print0x000c (os=..., value=..., exifData=0x555555628420) at /home/kev/work/exiv2b/src/canonmn_int.cpp:2738
2738 return os << value;
(gdb) p e
$1 = (const std::logic_error &) @0x5555556376a0: <incomplete type>
(gdb)
| is >> l; | ||
| return os << std::setw(4) << std::setfill('0') << std::hex << ((l & 0xffff0000) >> 16) << std::setw(5) | ||
| << std::setfill('0') << std::dec << (l & 0x0000ffff); | ||
| } catch (const std::logic_error&) { |
|
I'm adding a regression test so that we can verify which exception we need to catch here. |
print0x000a and print0x000c call std::stoul(value.toString()), but the stored type of Canon tags 0x000a and 0x000c is not enforced during parsing, so a crafted makernote can hand them a non-numeric ASCII value. stoul then throws std::invalid_argument, which Exifdatum::write does not catch (it only guards std::out_of_range), so it escapes during -pa printing. Catch both and fall back to the raw value, like the existing path in print0x000c.
This is an automatic backport of pull request #9320 done by Mergify.