Bug 473399 - On Git master/1.10, application crashes when word wrap is enabled, selecting text, and refreshing diff
Summary: On Git master/1.10, application crashes when word wrap is enabled, selecting ...
Status: RESOLVED FIXED
Alias: None
Product: kdiff3
Classification: Applications
Component: application (show other bugs)
Version: unspecified
Platform: Other Linux
: NOR crash
Target Milestone: ---
Assignee: michael
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-08-15 07:39 UTC by nyanpasu64
Modified: 2023-08-25 01:32 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In: 1.10.6
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description nyanpasu64 2023-08-15 07:39:24 UTC
SUMMARY
If I open the application to compare two files with word wrap enabled, make a selection, then press F5 or Ctrl+Shift+Y to reload the document, it crashes.

STEPS TO REPRODUCE
1. `kdiff3 1.txt 2.txt` (can be 1 paragraph or more than 1 page, same or different).
2. Check that word wrap is enabled.
3. Double-click the text to select a word.
4. Press F5.

Alternatively enable word wrap, then double-click a word and press Ctrl+Y to add a manual alignment.

OBSERVED RESULT
Crash with SIGABRT: ASSERT failure in QVector<T>::operator[]: "index out of range", file /usr/include/qt/QtCore/qvector.h, line 457

#0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
#1  0x00007ffff568e8a3 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78
#2  0x00007ffff563e668 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x00007ffff56264b8 in __GI_abort () at abort.c:79
#4  0x00007ffff5ea0098 in qt_assert(char const*, char const*, int) () at /usr/lib/libQt5Core.so.5
#5  0x00007ffff5ea0157 in  () at /usr/lib/libQt5Core.so.5
#6  0x0000555555763f60 in QVector<Diff3WrapLine>::operator[](int) (this=0x5555560cc350, i=0) at /usr/include/qt/QtCore/qvector.h:457
#7  0x000055555575b290 in DiffTextWindow::convertLineCoordsToD3LCoords(LineRef, int, int&, int&) const (this=0x5555560cc010, line=..., pos=31, d3LIdx=@0x7fffffffd24c: 3, d3LPos=@0x7fffffffd250: 31) at /home/nyanpasu64/code/kdiff3/src/difftextwindow.cpp:1529
#8  0x000055555575bd04 in DiffTextWindow::convertSelectionToD3LCoords() const (this=0x5555560cc010) at /home/nyanpasu64/code/kdiff3/src/difftextwindow.cpp:1641
#9  0x000055555573cbfe in KDiff3App::recalcWordWrap(int) (this=0x555555a7f660, visibleTextWidthForPrinting=-1) at /home/nyanpasu64/code/kdiff3/src/pdiff.cpp:1477
#10 0x000055555573cb0f in KDiff3App::slotRecalcWordWrap() (this=0x555555a7f660) at /home/nyanpasu64/code/kdiff3/src/pdiff.cpp:1459
#11 0x00005555556f626e in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (KDiff3App::*)()>::call(void (KDiff3App::*)(), KDiff3App*, void**) (f=(void (KDiff3App::*)(class KDiff3App * const)) 0x55555573caf2 <KDiff3App::slotRecalcWordWrap()>, o=0x555555a7f660, arg=0x5555561f16d8) at /usr/include/qt/QtCore/qobjectdefs_impl.h:152
#12 0x00005555556f38fc in QtPrivate::FunctionPointer<void (KDiff3App::*)()>::call<QtPrivate::List<>, void>(void (KDiff3App::*)(), KDiff3App*, void**) (f=(void (KDiff3App::*)(class KDiff3App * const)) 0x55555573caf2 <KDiff3App::slotRecalcWordWrap()>, o=0x555555a7f660, arg=0x5555561f16d8) at /usr/include/qt/QtCore/qobjectdefs_impl.h:185
#13 0x00005555556f16f1 in QtPrivate::QSlotObject<void (KDiff3App::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (which=1, this_=0x55555601c240, r=0x555555a7f660, a=0x5555561f16d8, ret=0x0) at /usr/include/qt/QtCore/qobjectdefs_impl.h:418
#14 0x00007ffff60c4174 in QObject::event(QEvent*) () at /usr/lib/libQt5Core.so.5
#15 0x00007ffff6d7893f in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/libQt5Widgets.so.5
#16 0x00007ffff609c6f8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/libQt5Core.so.5
#17 0x00007ffff60a165b in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () at /usr/lib/libQt5Core.so.5
#18 0x00007ffff60e76d8 in  () at /usr/lib/libQt5Core.so.5
#19 0x00007ffff450fa31 in g_main_context_dispatch () at /usr/lib/libglib-2.0.so.0
#20 0x00007ffff456ccc9 in  () at /usr/lib/libglib-2.0.so.0
#21 0x00007ffff450d0e2 in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0
#22 0x00007ffff60eb51c in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt5Core.so.5
#23 0x00007ffff609b404 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt5Core.so.5
#24 0x00007ffff609c8a3 in QCoreApplication::exec() () at /usr/lib/libQt5Core.so.5
#25 0x00005555556d2cf7 in main(int, char**) (argc=3, argv=0x7fffffffdac8) at /home/nyanpasu64/code/kdiff3/src/main.cpp:210

EXPECTED RESULT
No crash.

SOFTWARE/OS VERSIONS
Operating System: Arch Linux 
KDE Plasma Version: 5.27.7
KDE Frameworks Version: 5.108.0
Qt Version: 5.15.10
Kernel Version: 6.4.9-arch1-1 (64-bit)
Graphics Platform: Wayland
Processors: 12 × AMD Ryzen 5 5600X 6-Core Processor
Memory: 15.5 GiB of RAM
Graphics Processor: AMD Radeon RX 570 Series
Manufacturer: Gigabyte Technology Co., Ltd.
Product Name: B550M DS3H

This bug occurs on kdiff3 1.10+git 06a3487d030ba7fc401fc56280f96129a53c2fea and master bd8ad0d72538bcc2a6490ebb93ce21ced5aa0cc5, but not on the tagged 1.10.5. This could probably be bisected if needed, though that won't necessarily tell *why* the change crashes.

ADDITIONAL INFORMATION
Comment 1 michael 2023-08-25 01:31:31 UTC
Git commit 74792ce8aa795deb7397ca224f63543996b5de15 by Michael Reeves.
Committed on 25/08/2023 at 03:30.
Pushed by mreeves into branch 'master'.

Correct miss-handling of empty m_diff3WrapLineVector

DiffTextWindow::convertLineCoordsToD3LCoords can be called when m_diff3WrapLineVector is empty.
This has always been then case but for some reason hasn't happened previously.
Nothing in the way this function is used suggests it was ever guaranteed to be working with a non-empty
 m_diff3WrapLineVector
 In fact its called in KDiff3App::recalcWordWrap before the new word warp is computed.
 Therefor we can not assume  m_diff3WrapLineVector is non-empty as it is cleared by default.
 FIXED-IN:1.10.6

M  +2    -2    src/difftextwindow.cpp

https://invent.kde.org/sdk/kdiff3/-/commit/74792ce8aa795deb7397ca224f63543996b5de15
Comment 2 michael 2023-08-25 01:32:04 UTC
Git commit 6585c91fea320d2f6d909766c836bcbc0c5b230d by Michael Reeves.
Committed on 25/08/2023 at 03:30.
Pushed by mreeves into branch '1.10'.

Correct mishandling of empty m_diff3WrapLineVector

DiffTextWindow::convertLineCoordsToD3LCoords can be called when m_diff3WrapLineVector is empty.
This has always been then case but for some reason hasn't happened previously.
Nothing in the way this function is used suggests it was ever guaranteed to be working with a non-empty
 m_diff3WrapLineVector
 In fact its called in KDiff3App::recalcWordWrap before the new word warp is computed.
 Therefor we can not assume  m_diff3WrapLineVector is non-empty as it is cleared by default.
 FIXED-IN:1.10.6

M  +2    -2    src/difftextwindow.cpp

https://invent.kde.org/sdk/kdiff3/-/commit/6585c91fea320d2f6d909766c836bcbc0c5b230d