-
Notifications
You must be signed in to change notification settings - Fork 13
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
Grid.decode() returns InvalidVersion for valid QR codes with high versions #2
Comments
As pointed out in #2, version computation was using grid size as if it were the version itself. this meant that grids larger than 40 modules were rejected. This was fixed by first computing the version used on the module heuristic and only then checking if the value is in the expected range.
Hey! Thanks for the detailed error report with example and also suspect code. You were totally right, this check was broken. I replaced the version computation with a better version which should cover all defined versions. I also add some more derive clauses for The fix is part of the newly released version v0.2.1. |
Thanks! By the way, how about adding a test where a grid looks like a QR code, but is actually a wrong version? I just tried it, and it panics with this traceback:
To reproduce, use this grid I made that looks like a QR code but isn't: Here's the GIMP file I created this from. Essentially what I've done is added 4 modules of width to the QR code, thus making it a version 41 code, which doesn't exist. This sounds like a good time to emit |
By the way, it seems that not many QR decoders can gracefully recover from parsing this grid. My Xiaomi-branded phone has a builtin QR-scanner app that interprets this code as a string of 8 random-ish numbers. Meanwhile, that decoder I linked returned this error (line breaks added):
So, this may be too much to ask for to gracefully handle this case if the venerable ZXing project was unable to. |
Actually I had a check with version v0.2.1 and it already returns This test passes: let gif = image::open("tests/data/full/invalidversion.gif").unwrap().to_luma();
let mut search_img = rqrr::PreparedImage::prepare(gif);
let grids = search_img.detect_grids();
assert_eq!(grids.len(), 1);
let decoded = grids[0].decode();
assert!(decoded.is_err());
let err = decoded.unwrap_err();
assert_eq!(err, rqrr::DeQRError::InvalidVersion); I used the gif you linked above |
All right, I might have been testing with an older version of the library. Still, it seems like it'd be a good idea to add a test for that case -- it just feels prudent to check the error conditions in addition to normal cases, especially when, as in this case, errors in error handling can lead to crashes on maliciously-constructed grids. If you'd like, I can try and invent some more test cases involving errors and package them up into a PR. In particular I'm interested in the |
Contributions are always welcome 😃 |
For instance, this example from Wikipedia is a perfectly cromulent QR code, as evidenced by other QR decoders such as this one.
Here's a copy of it in GIF format:
However, if you try to decode it with this library, you get an error:
(Sidenote: you might want to
#[derive(PartialEq)]
onrqrr::DeQRError
-- thematch
construction is rather unwieldy compared to a simpleassert_eq!
, and thematches!
macro is not yet stable.)As far as I can tell, this happens because this error gets returned when the width of a QR code is greater than 40, not its version. The extreme case, version 40, has 177 modules per side, which is more than 40, but it doesn't mean that the grid itself is invalid. I've cloned the repo and changed this condition, and the rest of the code worked correctly in the version 10 case, so I'm pretty sure this is the one place that needs to be changed.
The text was updated successfully, but these errors were encountered: