mirror of https://github.com/status-im/qzxing.git
QZXingFilter: Fix crash when destructing QZXingFilter
QZXingFilterRunnable runs QFuture to perform decoder::decodeImage() and stores it in a class var of its owner (QZXingFilter), but when QZXingFilter is destructed it was not canceling that QFuture, making possible to the QFuture to try to access filter->decoder->decodeImage() after filter's are already destructed (dangling pointer). Issue detected when using QZXingFilter QML Element in an Page pushed in a StackView. When the page containing the QZXingFilter is poped from the StackView, (by default) the filter is unloaded/destructed, what makes the app crash without this patch. Signed-off-by: Nick Diego Yamane <nick.diego@gmail.com>
This commit is contained in:
parent
5627d2fbb5
commit
2083f7a805
|
@ -39,6 +39,10 @@ QZXingFilter::QZXingFilter(QObject *parent)
|
|||
|
||||
QZXingFilter::~QZXingFilter()
|
||||
{
|
||||
if(!processThread.isFinished()) {
|
||||
processThread.cancel();
|
||||
processThread.waitForFinished();
|
||||
}
|
||||
if(decoder_p)
|
||||
delete decoder_p;
|
||||
}
|
||||
|
@ -82,6 +86,10 @@ QZXingFilterRunnable::QZXingFilterRunnable(QZXingFilter * filter)
|
|||
{
|
||||
|
||||
}
|
||||
QZXingFilterRunnable::~QZXingFilterRunnable()
|
||||
{
|
||||
filter = nullptr;
|
||||
}
|
||||
|
||||
QVideoFrame QZXingFilterRunnable::run(QVideoFrame * input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
|
||||
{
|
||||
|
@ -261,7 +269,7 @@ void QZXingFilterRunnable::processVideoFrameProbed(SimpleVideoFrame & videoFrame
|
|||
// const QString path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/qrtest/test_" + QString::number(i % 100) + ".png";
|
||||
// qDebug() << "saving image" << i << "at:" << path << image.save(path);
|
||||
|
||||
QString tag = filter->decoder_p->decodeImage(image, image.width(), image.height());
|
||||
QString tag = decode(image);
|
||||
|
||||
const bool tryHarder = filter->decoder_p->getTryHarder();
|
||||
/// The frames we get from the camera may be reflected horizontally or vertically
|
||||
|
@ -269,14 +277,20 @@ void QZXingFilterRunnable::processVideoFrameProbed(SimpleVideoFrame & videoFrame
|
|||
/// TODO: Maybe there is a better way to know this orientation beforehand? Or should we try decoding all of them?
|
||||
if (tag.isEmpty() && tryHarder) {
|
||||
image = image.mirrored(true, false);
|
||||
tag = filter->decoder_p->decodeImage(image, image.width(), image.height());
|
||||
tag = decode(image);
|
||||
}
|
||||
if (tag.isEmpty() && tryHarder) {
|
||||
image = image.mirrored(false, true);
|
||||
tag = filter->decoder_p->decodeImage(image, image.width(), image.height());
|
||||
tag = decode(image);
|
||||
}
|
||||
if (tag.isEmpty() && tryHarder) {
|
||||
image = image.mirrored(true, true);
|
||||
tag = filter->decoder_p->decodeImage(image, image.width(), image.height());
|
||||
tag = decode(image);
|
||||
}
|
||||
}
|
||||
|
||||
QString QZXingFilterRunnable::decode(const QImage &image)
|
||||
{
|
||||
return (filter != nullptr) ?
|
||||
filter->decoder_p->decodeImage(image, image.width(), image.height()) : QString();
|
||||
}
|
||||
|
|
|
@ -103,10 +103,14 @@ class QZXingFilterRunnable : public QObject, public QVideoFilterRunnable
|
|||
|
||||
public:
|
||||
explicit QZXingFilterRunnable(QZXingFilter * filter);
|
||||
virtual ~QZXingFilterRunnable();
|
||||
/// This method is called whenever we get a new frame. It runs in the UI thread.
|
||||
QVideoFrame run(QVideoFrame * input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags);
|
||||
void processVideoFrameProbed(SimpleVideoFrame & videoFrame, const QRect& captureRect);
|
||||
|
||||
private:
|
||||
QString decode(const QImage &image);
|
||||
|
||||
private:
|
||||
QZXingFilter * filter;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue