-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
fix(wechat_qrcode): Init nBytes after the count value is determined #3480
Conversation
Amazing, too fast |
Orz!! |
amazing |
Cool! |
LGTM |
太猛了哥 |
amazing! |
interesting |
niuwa!!!!mobai dalao! |
ChatGPT 3.5:
|
Amazing! This bug seems to just crash my WeChat client program... |
amazing! |
|
LGTM |
Long live these volunteers! ❤️ |
amazing! |
Too Fast! |
QQ和微信都会crash |
Cool!! Really fast |
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.
lgtm
@opencv-alalek @asmorkalov Would it be possible to review and merge of my pull request? Thank you very much! |
666 |
有品 |
LGTM |
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.
@Konano @GZTimeWalker Hi, thanks for your contribution! Your patch will be the main branch to fix this bug. There are some comments:
- put a test image to
opencv_extra/testdata/cv/qrcode/
- create a new pr to
opencv_extra
which branch name should bepatch-1
inKonano
’s repository. - then update your code in
opencv_contrib
, the CI test will automatically pull the new test data to test your pr - add test code in
modules/wechat_qrcode/test/test_qrcode.cpp
TEST(Objdetect_QRCode_bug, issue_3478) { auto detector = wechat_qrcode::WeChatQRCode(); std::string image_path = findDataFile("qrcode/issue_3478.png"); Mat src = imread(image_path, IMREAD_GRAYSCALE); ASSERT_FALSE(src.empty()) << "Can't read image: " << image_path; std::vector<std::string> outs = detector.detectAndDecode(src); ASSERT_EQ(1, (int) outs.size()); ASSERT_EQ(16, (int) outs[0].size()); ASSERT_EQ("KFCVW50 ", outs[0]); }
- after testing, your method does not pass the test sample on windows platform
- I suggest you add code at Line 202
// issue https://github.com/opencv/opencv_contrib/issues/3478 if (bytes_->empty()) return;
@WanliZhong Thank you for your help! You mentioned that our method did not pass the test sample on windows platform, so I checked the test logs and the error message for test failure is as follows:
It looks like the new test case is not loaded? |
Before runing the test, you should add an env variable to refer the test data |
@WanliZhong All changes are applied, and we updated the branch https://github.com/Konano/opencv_extra/tree/patch-1 The error on windows x64 are caused by the wrong environment variables, we tested the code localy, it works fine. |
Good! Let's check if the test can be passed on all platform |
so fast!! 厉害! |
modules/wechat_qrcode/src/zxing/qrcode/decoder/decoded_bit_stream_parser.cpp
Show resolved
Hide resolved
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 for your contribution! 👍
Please take a look. @asmorkalov, @opencv-alalek, @vpisarev. |
There is a slight difference between |
From my point of view, since the data in the mixed mode of the QRCode is parsed from many segments, a decoder should have to output as many partially correct results as possible. |
size_t nBytes = count; | ||
|
||
ArrayRef<char> bytes_(nBytes); | ||
// issue https://github.com/opencv/opencv_contrib/issues/3478 | ||
if (bytes_->empty()) | ||
return; |
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.
If I understand correctly, bytes_->empty()
should be equivalent to nBytes == 0
. So why not using nBytes == 0
for simplicity and efficiency?
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 think this change would be a more visual indication of the intention to avoid null pointers?
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.
yes
🎉 All test cases on all platform have been passed! |
tql,大佬 |
昨天刚发现. 今天就修复~够速度 . |
Amazing |
It seems that everything is done. Can you please review and merge? @alalek. |
NIU 大佬 |
amazing! |
OrzOrzOrzOrz |
This pr has too much attention on the internet and has been merged, maybe we should lock it to avoid too many pointless comments. @WanliZhong @zihaomu |
Merge with test case: opencv/opencv_extra#1061
A malicious crafted image will crash the wechat_qrcode module by invalid memory access.
The earliest PoC by @GZTimeWalker: https://gist.github.com/GZTimeWalker/3ca70a8af2f5830711e9cccc73fb5270
Sample image:
In
DecodedBitStreamParser::decodeByteSegment
, an attacker can add a byte segment with the Character Count Indicator of non-zero but empty content at the end of the data segment, whereavailable
is 0 andcount
is updated to 0, butnBytes
remains non-zero.opencv_contrib/modules/wechat_qrcode/src/zxing/qrcode/decoder/decoded_bit_stream_parser.cpp
Lines 193 to 200 in 960b3f6
Since
count
is 0, thereadBytes
in L203 is a null pointer.opencv_contrib/modules/wechat_qrcode/src/zxing/qrcode/decoder/decoded_bit_stream_parser.cpp
Lines 202 to 203 in 960b3f6
Then
DecodedBitStreamParser::decodeByteSegment
will callDecodedBitStreamParser::append
, where thenBytes
parameter is not 0.opencv_contrib/modules/wechat_qrcode/src/zxing/qrcode/decoder/decoded_bit_stream_parser.cpp
Line 227 in 960b3f6
Eventually the program will crash at line 108 because it accesses a null pointer.
opencv_contrib/modules/wechat_qrcode/src/zxing/qrcode/decoder/decoded_bit_stream_parser.cpp
Line 108 in 960b3f6
We think the essence of the issue is that
count
was modified without updatingnBytes
, resulting in inconsistent values for the two variables. Unlike #3479, we think that the initialization ofnBytes
should be done after the value ofcount
has been determined, which helps avoid other potential errors.Moreover, we also found some wrong calculations in line 199, which are corrected together in this PR.
Also fixed #3478.
Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.