Bug 482615

Summary: Gwenview: segfault in FITSData::calculateMinMax
Product: [Applications] gwenview Reporter: Adam Fontenot <adam.m.fontenot+kde>
Component: generalAssignee: Gwenview Bugs <gwenview-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: aacid, kdelibs-bugs, nate, nicolas.fella
Priority: NOR Keywords: qt6
Version: 24.02.0   
Target Milestone: ---   
Platform: Arch Linux   
OS: Linux   
Latest Commit: Version Fixed In: 24.02.1
Attachments: file that will crash Gwenview when you try to open it
backtrace for crash

Description Adam Fontenot 2024-03-06 23:49:00 UTC
Created attachment 166526 [details]
file that will crash Gwenview when you try to open it

SUMMARY

The file in question is probably corrupt, but this should not segfault Gwenview.

STEPS TO REPRODUCE
1. Open attached file in Gwenview. (Alternatively, if you have a valid PNG file and this file in the same directory, and no other image files, opening the PNG will also crash Gwenview, probably because it tries to pre-load the other file.)

OBSERVED RESULT

Segfault. See backtrace.

EXPECTED RESULT

No segfault.

SOFTWARE/OS VERSIONS
Operating System: Arch Linux 
KDE Plasma Version: 6.0.1
KDE Frameworks Version: 6.0.0
Qt Version: 6.6.2
Kernel Version: 6.7.8-arch1-1 (64-bit)
Graphics Platform: Wayland
Comment 1 Adam Fontenot 2024-03-06 23:49:54 UTC
Created attachment 166527 [details]
backtrace for crash

#0  0x00007ffff7e855a2 in FITSData::calculateMinMax<float> (this=0x7fffcbdff7c0)
    at /usr/src/debug/gwenview/gwenview-24.02.0/lib/imageformats/fitsformat/fitsdata.cpp:327
Comment 2 Nicolas Fella 2024-03-07 16:30:46 UTC
#0  0x00007ffff7e855a2 in FITSData::calculateMinMax<float> (this=0x7fffcbdff7c0)
    at /usr/src/debug/gwenview/gwenview-24.02.0/lib/imageformats/fitsformat/fitsdata.cpp:327
#1  FITSData::calculateMinMax (refresh=false, this=0x7fffcbdff7c0)
    at /usr/src/debug/gwenview/gwenview-24.02.0/lib/imageformats/fitsformat/fitsdata.cpp:278
#2  FITSData::calculateStats (refresh=false, this=0x7fffcbdff7c0)
    at /usr/src/debug/gwenview/gwenview-24.02.0/lib/imageformats/fitsformat/fitsdata.cpp:183
#3  FITSData::loadFITS (this=0x7fffcbdff7c0, buffer=<optimized out>)
    at /usr/src/debug/gwenview/gwenview-24.02.0/lib/imageformats/fitsformat/fitsdata.cpp:164
#4  0x00007ffff7e7ffed in Gwenview::FitsHandler::option (this=<optimized out>, option=<optimized out>)
    at /usr/src/debug/gwenview/gwenview-24.02.0/lib/imageformats/fitshandler.cpp:73
#5  0x00007ffff5d3a9c5 in QImageReader::size (this=<optimized out>)
    at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.2/src/gui/image/qimagereader.cpp:855
#6  QImageReader::size (this=this@entry=0x7fffcbdff978)
    at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.2/src/gui/image/qimagereader.cpp:849
#7  0x00007ffff7de73aa in Gwenview::LoadingDocumentImplPrivate::loadMetaInfo (this=0x555555f5b020)
    at /usr/src/debug/gwenview/gwenview-24.02.0/lib/document/loadingdocumentimpl.cpp:233
#8  0x00007ffff7de0a8f in std::__invoke_impl<bool, bool (Gwenview::LoadingDocumentImplPrivate::*&)(), Gwenview::LoadingDocumentImplPrivate*&> (__f=<synthetic pointer>: <optimized out>, __t=<synthetic pointer>: <optimized out>) at /usr/include/c++/13.2.1/bits/invoke.h:71
#9  std::__invoke<bool (Gwenview::LoadingDocumentImplPrivate::*&)(), Gwenview::LoadingDocumentImplPrivate*&>
    (__fn=<synthetic pointer>: <optimized out>) at /usr/include/c++/13.2.1/bits/invoke.h:96
#10 std::invoke<bool (Gwenview::LoadingDocumentImplPrivate::*&)(), Gwenview::LoadingDocumentImplPrivate*&>
    (__fn=<synthetic pointer>: <optimized out>) at /usr/include/c++/13.2.1/functional:113
#11 QtConcurrent::StoredFunctionCall<bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>::runFunctor()::{lambda(bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*)#1}::operator()(bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*) const
    (args#0=<optimized out>, function=<optimized out>, __closure=<synthetic pointer>)
    at /usr/include/qt6/QtConcurrent/qtconcurrentstoredfunctioncall.h:116
#12 std::__invoke_impl<bool, QtConcurrent::StoredFunctionCall<bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>::runFunctor()::{lambda(bool (Gwenview::LoadingDocumentImplPrivate::* const&)(), Gwenview::LoadingDocumentImplPrivate*)#1}, bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>(std::__invoke_other, QtConcurrent::StoredFunctionCall<bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>::runFunctor()::{lambda(bool (Gwenview::LoadingDocumentImplPrivate::* const&)(), Gwenview::LoadingDocumentImplPrivate*)#1}, bool (Gwenview::LoadingDocumentImplPrivate::*&&)(), Gwenview::LoadingDocumentImplPrivate*&&) (__f=<synthetic pointer>...) at /usr/include/c++/13.2.1/bits/invoke.h:61
#13 std::__invoke<QtConcurrent::StoredFunctionCall<bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>::runFunctor()::{lambda(bool (Gwenview::LoadingDocumentImplPrivate::* const&)(), Gwenview::LoadingDocumentImplPrivate*)#1}, bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>(QtConcurrent::StoredFunctionCall<bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>::runFunctor()::{lambda(bool (Gwenview::LoadingDocumentImplPrivate::* const&)(), Gwenview::LoadingDocumentImplPrivate*)#1}, bool (Gwenview::LoadingDocumentImplPrivate::*&&)(), Gwenview::LoadingDocumentImplPrivate*&&) (__fn=<synthetic pointer>...) at /usr/include/c++/13.2.1/bits/invoke.h:96
#14 std::__apply_impl<QtConcurrent::StoredFunctionCall<bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>::runFunctor()::{lambda(bool (Gwenview::LoadingDocumentImplPrivate::* const&)(), Gwenview::LoadingDocumentImplPrivate*)#1}, std::tuple<bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>, 0ul, 1ul>(QtConcurrent::StoredFunctionCall<bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>::runFunctor()::{lambda(bool (Gwenview::LoadingDocumentImplPrivate::* const&)(), Gwenview::LoadingDocumentImplPrivate*)#1}, std::tuple<bool (Gwenview::LoadingDocumentImplPrivate::*)(), G--Type <RET> for more, q to quit, c to continue without paging--c
wenview::LoadingDocumentImplPrivate*>&&, std::integer_sequence<unsigned long, 0ul, 1ul>) (__t=..., __f=<synthetic pointer>...)
    at /usr/include/c++/13.2.1/tuple:2288
#15 std::apply<QtConcurrent::StoredFunctionCall<bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>::runFunctor()::{lambda(bool (Gwenview::LoadingDocumentImplPrivate::* const&)(), Gwenview::LoadingDocumentImplPrivate*)#1}, std::tuple<bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*> >(QtConcurrent::StoredFunctionCall<bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>::runFunctor()::{lambda(bool (Gwenview::LoadingDocumentImplPrivate::* const&)(), Gwenview::LoadingDocumentImplPrivate*)#1}, std::tuple<bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>&&) (__t=..., __f=<synthetic pointer>...) at /usr/include/c++/13.2.1/tuple:2299
#16 QtConcurrent::StoredFunctionCall<bool (Gwenview::LoadingDocumentImplPrivate::*)(), Gwenview::LoadingDocumentImplPrivate*>::runFunctor (this=0x555555f5a040) at /usr/include/qt6/QtConcurrent/qtconcurrentstoredfunctioncall.h:122
#17 0x00007ffff7de59d9 in QtConcurrent::RunFunctionTaskBase<bool>::run (this=0x555555f5a040)
    at /usr/include/qt6/QtConcurrent/qtconcurrentrunbase.h:83
#18 0x00007ffff58a66e5 in QThreadPoolThread::run (this=0x555555f50e00)
    at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.2/src/corelib/thread/qthreadpool.cpp:66
#19 0x00007ffff58a0bd3 in operator() (__closure=<optimized out>)
    at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.2/src/corelib/thread/qthread_unix.cpp:324
#20 (anonymous namespace)::terminate_on_exception<QThreadPrivate::start(void*)::<lambda()> > (t=<optimized out>)
    at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.2/src/corelib/thread/qthread_unix.cpp:260
#21 QThreadPrivate::start (arg=0x555555f50e00)
    at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.6.2/src/corelib/thread/qthread_unix.cpp:283
#22 0x00007ffff50a955a in start_thread (arg=<optimized out>) at pthread_create.c:447
#23 0x00007ffff5126a3c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Comment 3 Bug Janitor Service 2024-03-07 21:59:25 UTC
A possibly relevant merge request was started @ https://invent.kde.org/graphics/gwenview/-/merge_requests/259
Comment 4 Albert Astals Cid 2024-03-07 22:00:48 UTC
The file is fine fitstopnm will create valid images out of it, sadly we don't understand it
Comment 5 Albert Astals Cid 2024-03-07 22:05:20 UTC
Git commit 1159b35f31b330c701ff23cd5856317e2bf8f43f by Albert Astals Cid.
Committed on 07/03/2024 at 21:58.
Pushed by aacid into branch 'master'.

Don't crash on unsupported fits images

M  +8    -0    lib/imageformats/fitsformat/fitsdata.cpp

https://invent.kde.org/graphics/gwenview/-/commit/1159b35f31b330c701ff23cd5856317e2bf8f43f
Comment 6 Albert Astals Cid 2024-03-07 22:05:57 UTC
Git commit 28ca97c4e03382c06f9630c185c177a65697de72 by Albert Astals Cid.
Committed on 07/03/2024 at 22:05.
Pushed by aacid into branch 'release/24.02'.

Don't crash on unsupported fits images
(cherry picked from commit 1159b35f31b330c701ff23cd5856317e2bf8f43f)

M  +8    -0    lib/imageformats/fitsformat/fitsdata.cpp

https://invent.kde.org/graphics/gwenview/-/commit/28ca97c4e03382c06f9630c185c177a65697de72