Add a Gitter chat badge to README.md#1
Closed
gitter-badger wants to merge 1 commit intoSlySven:developmentfrom
Closed
Add a Gitter chat badge to README.md#1gitter-badger wants to merge 1 commit intoSlySven:developmentfrom
gitter-badger wants to merge 1 commit intoSlySven:developmentfrom
Conversation
SlySven
pushed a commit
that referenced
this pull request
Mar 23, 2015
(release 30 try4)exit map fix
SlySven
added a commit
that referenced
this pull request
Apr 15, 2016
…ata() (where XXXX is Room or Area!) I have realised that the functionality could usefully be included in the existing functions and be utilised by invoking those with NO arguments. This avoids the addition of yet another pair of functions (and Mudlet versions WITH this functionality can be detected by script writers by the fact that existing code will raise an error about a bad argument #1 {being "nil"} if a new script tries to use the function on an older version.) Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
SlySven
added a commit
that referenced
this pull request
Apr 16, 2016
…ata() (where XXXX is Room or Area!) I have realised that the functionality could usefully be included in the existing functions and be utilised by invoking those with NO arguments. This avoids the addition of yet another pair of functions (and Mudlet versions WITH this functionality can be detected by script writers by the fact that existing code will raise an error about a bad argument #1 {being "nil"} if a new script tries to use the function on an older version.) Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
SlySven
pushed a commit
that referenced
this pull request
May 6, 2018
Revise: polish up some aspects of AlysCole's PR
SlySven
pushed a commit
that referenced
this pull request
May 6, 2018
- Rebase onto Stephen Lyons's PR #1. - When dlgProfilePreferences::slot_logFileNameFormatChange() and initWithHost() are called, set lineEdit_logFileName to visible depending on the selected option in comboBox_logFileNameFormat. The lineEdit should only be visible when comboBox_logFileNameFormat is set to 'Named file'. - Use QString rather than QDir to take the return value of QFileDialog::getExistingDirectory. This will allow us to check whether the return value is NULL (which happens when a user presses 'Cancel' within the file dialog). - When initWithHost() is called, set the text property of pushButton_whereToLog to contain the user's current log directory. When the button is pushed and another directory selected, set the text property to the selected directory, whether or not it is saved. - Move pushButton_whereToLog->setToolTip(...), comboBox_logFileNameFormat->addItem(...), and all lines setting the properties of the log options above the call to initWithHost() so the adding of Qt properties goes before the properties being set in line with the values within Host.
SlySven
pushed a commit
that referenced
this pull request
May 24, 2018
Update Contributors outstanding PR
SlySven
added a commit
that referenced
this pull request
Apr 1, 2020
* Adds an option for variables to be included in searches, which is disabled by default now. This option is in the search menu on the left side of the search bar, positioned with the Case Sensitivity option. * Revise: add "with-variables" icons & persistent storage of search options Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Update copyright stamp #1 * Update copyright date #2 * Trim tooltip to UX standard Co-authored-by: Stephen Lyons <slysven@virginmedia.com> Co-authored-by: Vadim Peretokin <vperetokin@gmail.com>
SlySven
pushed a commit
that referenced
this pull request
Jun 22, 2020
BugFix: CorTheWin's development branch
SlySven
pushed a commit
that referenced
this pull request
Jun 22, 2020
SlySven
pushed a commit
that referenced
this pull request
Nov 12, 2023
Change the way the osx installer is created
SlySven
added a commit
that referenced
this pull request
Dec 15, 2024
<!-- Keep the title short & concise so anyone non-technical can
understand it,
the title appears in PTB changelogs -->
#### Brief overview of PR changes/additions
Fixes Mudlet crash with IRC open when closing a profile
#### Motivation for adding to Mudlet
Mudlet should never crash
#### Other info (issues closed, discussion etc)
Closes Mudlet#7293. I'll fix other
cases of `Host* mpHost;` after this PR so we have consistency in the
codebase.
Running the provided test case through
[AddressSanitizer](https://wiki.mudlet.org/w/Compiling_Mudlet#Checking_memory_leaks_.26_other_issues_.28sanitizers.29_3)
revealed that mpHost was being used after it was deleted:
```
=================================================================
==17843==ERROR: AddressSanitizer: heap-use-after-free on address 0x623000025e58 at pc 0x5555560abe75 bp 0x7fffffff7460 sp 0x7fffffff7450
READ of size 8 at 0x623000025e58 thread T0
#0 0x5555560abe74 in QWeakPointer<QObject>::internalData() const /usr/include/x86_64-linux-gnu/qt6/QtCore/qsharedpointer_impl.h:711
#1 0x5555562c15ad in QPointer<dlgIRC>::data() const /usr/include/x86_64-linux-gnu/qt6/QtCore/qpointer.h:77
#2 0x5555562bd715 in QPointer<dlgIRC>::operator dlgIRC*() const /usr/include/x86_64-linux-gnu/qt6/QtCore/qpointer.h:85
#3 0x555556296c13 in dlgIRC::~dlgIRC() /home/vadi/Programs/Mudlet/src/dlgIRC.cpp:109
#4 0x555556296e1f in dlgIRC::~dlgIRC() /home/vadi/Programs/Mudlet/src/dlgIRC.cpp:112
#5 0x7ffff6ba04a0 in QObject::event(QEvent*) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x1a04a0)
...
```
This helped pinpoint the cause of the crash.
---------
Co-authored-by: Stephen Lyons <slysven@virginmedia.com>
Co-authored-by: Vadim Peretokin <vadi2@users.noreply.github.com>
SlySven
pushed a commit
that referenced
this pull request
Oct 18, 2025
<!-- Keep the title short & concise so anyone non-technical can
understand it,
the title appears in PTB changelogs -->
#### Brief overview of PR changes/additions
Fix
```
Direct leak of 4000 byte(s) in 50 object(s) allocated from:
#0 0x7f21286b61e7 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99
#1 0x5652d10ed62c in TriggerHighlighter::setTheme(QString const&) (/home/runner/work/Mudlet/Mudlet/src/mudlet+0x202562c)
#2 0x5652d10ecba7 in TriggerHighlighter::TriggerHighlighter(QTextDocument*) (/home/runner/work/Mudlet/Mudlet/src/mudlet+0x2024ba7)
#3 0x5652d0998ef2 in SingleLineTextEdit::SingleLineTextEdit(QWidget*) (/home/runner/work/Mudlet/Mudlet/src/mudlet+0x18d0ef2)
#4 0x5652d05f581a in Ui_trigger_pattern_edit::setupUi(QWidget*) (/home/runner/work/Mudlet/Mudlet/src/mudlet+0x152d81a)
#5 0x5652d05f2792 in dlgTriggerPatternEdit::dlgTriggerPatternEdit(QWidget*) (/home/runner/work/Mudlet/Mudlet/src/mudlet+0x152a792)
#6 0x5652d044b2a2 in dlgTriggerEditor::dlgTriggerEditor(Host*) (/home/runner/work/Mudlet/Mudlet/src/mudlet+0x13832a2)
#7 0x5652d08479a9 in mudlet::addConsoleForNewHost(Host*) (/home/runner/work/Mudlet/Mudlet/src/mudlet+0x177f9a9)
#8 0x5652d086efcb in mudlet::slot_connectionDialogueFinished(QString const&, bool) (/home/runner/work/Mudlet/Mudlet/src/mudlet+0x17a6fcb)
```
#### Motivation for adding to Mudlet
Better app quality
#### Other info (issues closed, discussion etc)
Discovered when running Mudlet with cmake.
SlySven
pushed a commit
that referenced
this pull request
Dec 4, 2025
…rocessing (Mudlet#8571) <!-- Keep the title short & concise so anyone non-technical can understand it, the title appears in PTB changelogs --> #### Brief overview of PR changes/additions Fix: heap-use-after-free when cleanup runs during alias/trigger/key processing #### Motivation for adding to Mudlet Fixes crash when running Mudlet#8559 (comment) benchmark on Linux. #### Other info (issues closed, discussion etc) ==617553==ERROR: AddressSanitizer: heap-use-after-free on address 0x51200086e6d0 at pc 0x589b650367f6 bp 0x7ffc44dbc700 sp 0x7ffc44dbc6f8 READ of size 8 at 0x51200086e6d0 thread T0 #0 0x589b650367f5 in Tree<TAlias>::isActive() const (/home/vadi/Programs/Mudlet/build/src/mudlet+0xe8a7f5) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #1 0x589b65d81408 in TAlias::match(QString const&) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1bd5408) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #2 0x589b6560c156 in AliasUnit::processDataStream(QString const&) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1460156) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #3 0x589b65c872b4 in Host::send(QString, bool, bool) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1adb2b4) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #4 0x589b65d96517 in TCommandLine::enterCommand(QKeyEvent*) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1bea517) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #5 0x589b65d93095 in TCommandLine::event(QEvent*) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1be7095) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #6 0x7ac668391c8a in QApplicationPrivate::notify_helper(QObject*, QEvent*) /home/qt/work/qt/qtbase/src/widgets/kernel/qapplication.cpp:3307:31 #7 0x7ac66839b2f0 in QApplication::notify(QObject*, QEvent*) /home/qt/work/qt/qtbase/src/widgets/kernel/qapplication.cpp:2725:39 #8 0x7ac668b83f7f in QCoreApplication::notifyInternal2(QObject*, QEvent*) /home/qt/work/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1109:24 #9 0x7ac66840cc0b in QWidgetWindow::event(QEvent*) /home/qt/work/qt/qtbase/src/widgets/kernel/qwidgetwindow.cpp:285:23 #10 0x7ac668391c8a in QApplicationPrivate::notify_helper(QObject*, QEvent*) /home/qt/work/qt/qtbase/src/widgets/kernel/qapplication.cpp:3307:31 #11 0x7ac668b83f7f in QCoreApplication::notifyInternal2(QObject*, QEvent*) /home/qt/work/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1109:24 #12 0x7ac6677ee8e2 in QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent*) /home/qt/work/qt/qtbase/src/gui/kernel/qguiapplication.cpp:2609:46 #13 0x7ac655cf9a04 in QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher*) /home/qt/work/qt/qtbase/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp:523:57 #14 0x7ac668be8b74 in QtPrivate::QSlotObjectBase::call(QObject*, void**) /home/qt/work/qt/qtbase/src/corelib/kernel/qobjectdefs_impl.h:461:57 #15 0x7ac668be8b74 in void doActivate<false>(QObject*, int, void**) /home/qt/work/qt/qtbase/src/corelib/kernel/qobject.cpp:4255:30 #16 0x7ac6671e5142 in void QMetaObject::activate<void, QDBusPendingCallWatcher*>(QObject*, QMetaObject const*, int, void*, QDBusPendingCallWatcher* const&) /home/qt/work/qt/qtbase/src/corelib/kernel/qobjectdefs.h:319:17 #17 0x7ac6671e5142 in QDBusPendingCallWatcher::finished(QDBusPendingCallWatcher*) /home/qt/work/qt/qtbase_build/src/dbus/DBus_autogen/include/moc_qdbuspendingcall.cpp:137:32 #18 0x7ac668bdd56b in QObject::event(QEvent*) /home/qt/work/qt/qtbase/src/corelib/kernel/qobject.cpp:1411:31 #19 0x7ac668391c8a in QApplicationPrivate::notify_helper(QObject*, QEvent*) /home/qt/work/qt/qtbase/src/widgets/kernel/qapplication.cpp:3307:31 #20 0x7ac668b83f7f in QCoreApplication::notifyInternal2(QObject*, QEvent*) /home/qt/work/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1109:24 #21 0x7ac668b879e4 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) /home/qt/work/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1904:36 #22 0x7ac668e7d416 in postEventSourceDispatch /home/qt/work/qt/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:246:39 #23 0x7ac6667145c4 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5d5c4) (BuildId: 1eb6131419edb83b2178b682829a6913cf682d75) #24 0x7ac666773736 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0xbc736) (BuildId: 1eb6131419edb83b2178b682829a6913cf682d75) #25 0x7ac666713a62 in g_main_context_iteration (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5ca62) (BuildId: 1eb6131419edb83b2178b682829a6913cf682d75) #26 0x7ac668e7caad in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) /home/qt/work/qt/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:399:43 #27 0x7ac668b9002a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) /home/qt/work/qt/qtbase/src/corelib/kernel/qeventloop.cpp:186:22 #28 0x7ac668b8ba59 in QCoreApplication::exec() /home/qt/work/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1452:36 #29 0x589b64ab0675 in main (/home/vadi/Programs/Mudlet/build/src/mudlet+0x904675) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #30 0x7ac66602a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 #31 0x7ac66602a28a in __libc_start_main csu/../csu/libc-start.c:360:3 #32 0x589b649c1d04 in _start (/home/vadi/Programs/Mudlet/build/src/mudlet+0x815d04) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) 0x51200086e6d0 is located 16 bytes inside of 296-byte region [0x51200086e6c0,0x51200086e7e8) freed by thread T0 here: #0 0x589b64a9b9f1 in operator delete(void*) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x8ef9f1) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #1 0x589b65d80711 in TAlias::~TAlias() (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1bd4711) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #2 0x589b6560eefc in AliasUnit::doCleanup() (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1462efc) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #3 0x589b65c8e88d in Host::incomingStreamProcessor(QString const&, int) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1ae288d) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #4 0x589b651b73b5 in TMainConsole::runTriggers(int) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x100b3b5) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #5 0x589b64e39c4b in TBuffer::commitLine(char, unsigned long&) (/home/vadi/Programs/Mudlet/build/src/mudlet+0xc8dc4b) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #6 0x589b64e28d4e in TBuffer::translateToPlainText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, bool) (/home/vadi/Programs/Mudlet/build/src/mudlet+0xc7cd4e) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #7 0x589b651b638d in TMainConsole::printOnDisplay(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, bool) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x100a38d) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #8 0x589b64f9ed5b in TLuaInterpreter::feedTriggers(lua_State*) (/home/vadi/Programs/Mudlet/build/src/mudlet+0xdf2d5b) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #9 0x7ac66942ffa0 in luaD_precall /build/lua5.1-rMDsVj/lua5.1-5.1.5/src/ldo.c:320:10 #10 0x7ac66943ad7a in luaV_execute /build/lua5.1-rMDsVj/lua5.1-5.1.5/src/lvm.c:591:17 #11 0x7ac66942e96c in luaD_call /build/lua5.1-rMDsVj/lua5.1-5.1.5/src/ldo.c:378:5 #12 0x7ac66942af70 in luaD_rawrunprotected /build/lua5.1-rMDsVj/lua5.1-5.1.5/src/ldo.c:116:3 #13 0x7ac66942bb94 in luaD_pcall /build/lua5.1-rMDsVj/lua5.1-5.1.5/src/ldo.c:464:12 #14 0x7ac66942bce0 in lua_pcall /build/lua5.1-rMDsVj/lua5.1-5.1.5/src/lapi.c:821:12 #15 0x589b64fd65f1 in TLuaInterpreter::call(QString const&, QString const&, bool) (/home/vadi/Programs/Mudlet/build/src/mudlet+0xe2a5f1) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #16 0x589b65d84d31 in TAlias::execute() (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1bd8d31) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #17 0x589b65d84577 in TAlias::match(QString const&) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1bd8577) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #18 0x589b6560c156 in AliasUnit::processDataStream(QString const&) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1460156) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #19 0x589b65c872b4 in Host::send(QString, bool, bool) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1adb2b4) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #20 0x589b65d96517 in TCommandLine::enterCommand(QKeyEvent*) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1bea517) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #21 0x589b65d93095 in TCommandLine::event(QEvent*) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1be7095) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #22 0x7ac668391c8a in QApplicationPrivate::notify_helper(QObject*, QEvent*) /home/qt/work/qt/qtbase/src/widgets/kernel/qapplication.cpp:3307:31 previously allocated by thread T0 here: #0 0x589b64a9b171 in operator new(unsigned long) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x8ef171) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #1 0x589b6500f595 in TLuaInterpreter::startTempAlias(QString const&, QString const&) (/home/vadi/Programs/Mudlet/build/src/mudlet+0xe63595) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #2 0x589b6512c41d in TLuaInterpreter::tempAlias(lua_State*) (/home/vadi/Programs/Mudlet/build/src/mudlet+0xf8041d) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #3 0x7ac66942ffa0 in luaD_precall /build/lua5.1-rMDsVj/lua5.1-5.1.5/src/ldo.c:320:10 #4 0x7ac66943ad7a in luaV_execute /build/lua5.1-rMDsVj/lua5.1-5.1.5/src/lvm.c:591:17 #5 0x7ac66942e96c in luaD_call /build/lua5.1-rMDsVj/lua5.1-5.1.5/src/ldo.c:378:5 #6 0x7ac66942af70 in luaD_rawrunprotected /build/lua5.1-rMDsVj/lua5.1-5.1.5/src/ldo.c:116:3 #7 0x7ac66942bb94 in luaD_pcall /build/lua5.1-rMDsVj/lua5.1-5.1.5/src/ldo.c:464:12 #8 0x7ac66942bce0 in lua_pcall /build/lua5.1-rMDsVj/lua5.1-5.1.5/src/lapi.c:821:12 #9 0x589b64fd65f1 in TLuaInterpreter::call(QString const&, QString const&, bool) (/home/vadi/Programs/Mudlet/build/src/mudlet+0xe2a5f1) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #10 0x589b65d84d31 in TAlias::execute() (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1bd8d31) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #11 0x589b65d84577 in TAlias::match(QString const&) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1bd8577) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #12 0x589b6560c156 in AliasUnit::processDataStream(QString const&) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1460156) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #13 0x589b65c872b4 in Host::send(QString, bool, bool) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1adb2b4) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #14 0x589b65d96517 in TCommandLine::enterCommand(QKeyEvent*) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1bea517) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #15 0x589b65d93095 in TCommandLine::event(QEvent*) (/home/vadi/Programs/Mudlet/build/src/mudlet+0x1be7095) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) #16 0x7ac668391c8a in QApplicationPrivate::notify_helper(QObject*, QEvent*) /home/qt/work/qt/qtbase/src/widgets/kernel/qapplication.cpp:3307:31 SUMMARY: AddressSanitizer: heap-use-after-free (/home/vadi/Programs/Mudlet/build/src/mudlet+0xe8a7f5) (BuildId: c98a5e4208b6daa52aa1b083c4ee6c4ab4552cc4) in Tree<TAlias>::isActive() const Shadow bytes around the buggy address: 0x51200086e400: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x51200086e480: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa 0x51200086e500: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd 0x51200086e580: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x51200086e600: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa =>0x51200086e680: fa fa fa fa fa fa fa fa fd fd[fd]fd fd fd fd fd 0x51200086e700: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x51200086e780: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa 0x51200086e800: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd 0x51200086e880: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x51200086e900: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==617553==ABORTING Co-authored-by: Vadim Peretokin <vadi2@users.noreply.github.com>
SlySven
pushed a commit
that referenced
this pull request
Dec 4, 2025
…gers (Mudlet#8567) #### Brief overview of PR changes/additions Fixed a heap-use-after-free crash in TBuffer destructor by converting the raw `mTagWatchdog` pointer to `std::unique_ptr<QTimer>` and implementing proper copy constructor and copy assignment operator. #### Motivation for adding to Mudlet The crash occurred when closing a profile (e.g., using "Close Profile" menu item on Medievia MUD) that had been actively receiving data and running triggers. The issue was caused by TBuffer objects being copied without properly handling the ownership of the `mTagWatchdog` QTimer. When temporary TBuffer objects were created during copy operations (like in `TConsole::copy()`), both the original and copied instances shared the same QTimer pointer. When one instance was destroyed, it deleted the timer, leaving the other with a dangling pointer that caused a crash on subsequent destruction. AddressSanitizer trace showed: ``` ERROR: AddressSanitizer: heap-use-after-free on address 0x602000915670 READ of size 8 at 0x602000915670 thread T0 #0 in TBuffer::TBuffer()+0x88 #1 in TBuffer::TBuffer()+0x18 #2 in TMainConsole::~TMainConsole()+0x5a8 ``` The fix ensures each TBuffer instance owns its own QTimer through a unique_ptr, preventing double-deletion and use-after-free errors. #### Other info (issues closed, discussion etc) This resolves crashes that occurred during profile shutdown when the copy() Lua function was used in triggers processing incoming game data.
SlySven
pushed a commit
that referenced
this pull request
Feb 6, 2026
Mudlet#8694) (Mudlet#8751) ## Summary Fixes Mudlet#8694 - `table.update` would error when the first table had a non-table value (number, string, boolean) at a key where the second table had a table value. **Example that crashed:** ```lua table.update({ x = 1 }, { x = { y = 2 } }) -- Error: bad argument #1 to 'pairs' (table expected, got number) ``` **Root cause:** The recursion logic `tbl[k] = table.update(tbl[k] or {}, v)` only checked for nil/false before recursing, not for other non-table types. **Fix:** Check `type(existing) == "table"` before passing to recursive call. ## Test plan - [x] Added 5 new test cases in `TableUtils_spec.lua`: - Replace number with table - Replace table with number - Merge nested tables (both tables) - Replace string with table - Replace boolean with table - [x] Verified fix works: `luajit -e "dofile('...TableUtils.lua'); print(table.update({x=1}, {x={y=2}}).x.y)"` outputs `2` ## Notes Tests require running inside Mudlet with `runTests` command (uses Busted framework loaded by Mudlet). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Vadim Peretokin <vperetokin@hey.com>
SlySven
pushed a commit
that referenced
this pull request
Feb 7, 2026
…gers (Mudlet#8567) #### Brief overview of PR changes/additions Fixed a heap-use-after-free crash in TBuffer destructor by converting the raw `mTagWatchdog` pointer to `std::unique_ptr<QTimer>` and implementing proper copy constructor and copy assignment operator. #### Motivation for adding to Mudlet The crash occurred when closing a profile (e.g., using "Close Profile" menu item on Medievia MUD) that had been actively receiving data and running triggers. The issue was caused by TBuffer objects being copied without properly handling the ownership of the `mTagWatchdog` QTimer. When temporary TBuffer objects were created during copy operations (like in `TConsole::copy()`), both the original and copied instances shared the same QTimer pointer. When one instance was destroyed, it deleted the timer, leaving the other with a dangling pointer that caused a crash on subsequent destruction. AddressSanitizer trace showed: ``` ERROR: AddressSanitizer: heap-use-after-free on address 0x602000915670 READ of size 8 at 0x602000915670 thread T0 #0 in TBuffer::TBuffer()+0x88 #1 in TBuffer::TBuffer()+0x18 #2 in TMainConsole::~TMainConsole()+0x5a8 ``` The fix ensures each TBuffer instance owns its own QTimer through a unique_ptr, preventing double-deletion and use-after-free errors. #### Other info (issues closed, discussion etc) This resolves crashes that occurred during profile shutdown when the copy() Lua function was used in triggers processing incoming game data. (cherry picked from commit d56c6c2)
SlySven
pushed a commit
that referenced
this pull request
Feb 7, 2026
Mudlet#8694) (Mudlet#8751) ## Summary Fixes Mudlet#8694 - `table.update` would error when the first table had a non-table value (number, string, boolean) at a key where the second table had a table value. **Example that crashed:** ```lua table.update({ x = 1 }, { x = { y = 2 } }) -- Error: bad argument #1 to 'pairs' (table expected, got number) ``` **Root cause:** The recursion logic `tbl[k] = table.update(tbl[k] or {}, v)` only checked for nil/false before recursing, not for other non-table types. **Fix:** Check `type(existing) == "table"` before passing to recursive call. ## Test plan - [x] Added 5 new test cases in `TableUtils_spec.lua`: - Replace number with table - Replace table with number - Merge nested tables (both tables) - Replace string with table - Replace boolean with table - [x] Verified fix works: `luajit -e "dofile('...TableUtils.lua'); print(table.update({x=1}, {x={y=2}}).x.y)"` outputs `2` ## Notes Tests require running inside Mudlet with `runTests` command (uses Busted framework loaded by Mudlet). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Vadim Peretokin <vperetokin@hey.com> (cherry picked from commit c9e560b)
SlySven
pushed a commit
that referenced
this pull request
Apr 8, 2026
<!-- Keep the title short & concise so anyone non-technical can
understand it,
the title appears in PTB changelogs -->
#### Brief overview of PR changes/additions
Fixes memory leaks from playing sounds, opening the room exits dialog,
opening Preferences, right-clicking the console, connecting to MUDs with
compression, and viewing changelogs
#### Motivation for adding to Mudlet
Better memory management.
#### Other info (issues closed, discussion etc)
##### 3. TMediaPlayer destructor leaks TMediaPlaylist + QAudioOutput
```
playSoundFile() [TLuaInterpreterMedia.cpp:703]
→ TMedia::playMedia() [TMedia.cpp:47] → play() [TMedia.cpp:1485]
→ getMediaPlayer() [TMedia.cpp:1150]
→ make_shared<TMediaPlayer>(mpHost, mediaData) [TMedia.cpp:1193]
→ constructor: mPlaylist(new TMediaPlaylist) ← LEAK #1 [TMedia.h:47]
→ constructor: setAudioOutput(new QAudioOutput()) ← LEAK #2 [TMedia.h:50]
→ updateMediaPlayerList() [TMedia.cpp:1102]
→ purgeStoppedMediaPlayers() [TMedia.cpp:1056] (when list > 25)
→ shared_ptr destroyed → ~TMediaPlayer() = default ← NEVER DELETES [TMedia.h:52]
```
##### 6. dlgRoomExits TExit objects never freed
```
Right-click room → "Set exits..." [RoomContextMenuHandler.cpp:196]
→ T2DMap::slot_setExits() [T2DMap.cpp:4271]
→ new dlgRoomExits(...) [T2DMap.cpp:4278] + setAttribute(WA_DeleteOnClose) [T2DMap.cpp:4280]
→ init() [dlgRoomExits.cpp:279]
→ initExit() x12 [dlgRoomExits.cpp:1633-1775]
→ originalExits[dir] = makeExitFromControls(dir) [dlgRoomExits.cpp:1599]
→ new TExit() [dlgRoomExits.cpp:1968] ← ALLOCATED
→ new TExit() per special exit [dlgRoomExits.cpp:1782] → originalSpecialExits[dir] [line 1848]
User closes → ~dlgRoomExits() [dlgRoomExits.cpp:285] ← EMPTY, never deletes TExit objects
```
##### 7. dlgProfilePreferences QKeySequence* leak (no destructor)
```
mudlet::showOptionsDialog() [mudlet.cpp:3578]
→ new dlgProfilePreferences(this, pHost) [mudlet.cpp:3585]
→ setAttribute(WA_DeleteOnClose) [mudlet.cpp:3603]
→ constructor loop [dlgProfilePreferences.cpp:1394-1399]:
new QKeySequence(*pHost->profileShortcuts.value(key)) [line 1398]
currentShortcuts.insert(key, sequence) [line 1399] ← 17 raw pointers stored
User closes → WA_DeleteOnClose triggers delete
→ implicit ~dlgProfilePreferences() ← NO DESTRUCTOR EXISTS
→ QMap destroyed, pointer values NOT deleted
```
##### 10. ctelnet missing inflateEnd in destructor
```
Server sends WILL COMPRESS2 → processSocketData [ctelnet.cpp:4876-4880]
→ mNeedDecompression = true → initStreamDecompressor()
→ inflateInit(&mZstream) [ctelnet.cpp:4514] ← allocates ~256KB
Connection drops → slot_socketDisconnected() [ctelnet.cpp:627]
→ mNeedDecompression = false [line 663] ← NO inflateEnd()
→ reset() [line 664] ← NO inflateEnd()
→ ~cTelnet() [line 158] ← NO inflateEnd()
(only inflateEnd is in decompressBuffer:4532, on Z_STREAM_END from server)
```
##### 11. ctelnet QNetworkReply leak on file error paths
```
slot_replyFinished() [ctelnet.cpp:1365]
→ reply->error() == NoError [line 1398]
→ file.open() fails [line 1400] → return ← LEAK (no reply->deleteLater())
→ file.commit() fails [line 1409] → return ← LEAK (no reply->deleteLater())
(compare: error path at line 1393 correctly calls reply->deleteLater())
```
##### 15. TTextEdit QAction accumulation (5-10 per right-click)
```
Right-click on console → mouseReleaseEvent [TTextEdit.cpp:2287]
→ new QAction(tr("Copy"), this) [line 2374] ← parented to TTextEdit, not QMenu
→ new QAction(tr("Copy HTML"), this) [line 2385]
→ new QAction(tr("Copy as image"), this) [line 2389]
→ new QAction(tr("Select all"), this) [line 2392]
→ new QAction(tr("Search on %1"), this) [line 2397]
→ (+ conditional actions at 2416, 2434, 2438, 2448, 2465)
→ popup = new QMenu(this) + WA_DeleteOnClose [line 2406-2407]
→ Menu closes → QMenu deleted, but QActions survive as TTextEdit children ← ACCUMULATE
```
##### 17. Updater changelog dialogs leaked
```
Help → Show changelog → Updater::showChangelog() [updater.cpp:202]
→ new dblsqd::UpdateDialog(feed, ...) ← no parent [line 202]
→ changelogDialog->show() [line 204] ← non-blocking, pointer lost at scope end
(no WA_DeleteOnClose set; same at showFullChangelog:218)
```
##### 20. ModernGLWidget mTexCoordBuffer.destroy() missing
```
initializeGL() → setupBuffers() [modern_glwidget.cpp:146]
→ mTexCoordBuffer.create() [line 183]
~ModernGLWidget() → cleanup() [line 70]
→ mVertexBuffer.destroy() [line 78] ✓
→ mColorBuffer.destroy() [line 79] ✓
→ mNormalBuffer.destroy() [line 80] ✓
→ mIndexBuffer.destroy() [line 81] ✓
→ mInstanceBuffer.destroy() [line 82] ✓
→ mTexCoordBuffer.destroy() ← MISSING between lines 82 and 83
→ mVAO.destroy() [line 83] ✓
```
##### 21. dlgComposer context menu + Hunspell suggestions
```
Right-click in composer → slot_contextMenu() [dlgComposer.cpp:226]
→ createStandardContextMenu() [line 228] ← returns new QMenu*, no parent
→ fillSpellCheckList() [line 233] → Hunspell_suggest() [line 331,335] ← allocates lists
→ popup->popup() [line 237] ← non-blocking, pointer lost
← QMenu leaked (no WA_DeleteOnClose, no deleteLater)
← If dismissed without selection: Hunspell_free_list() never called [only at line 468,472]
```
##### 22-24. Lower-impact (also in this branch)
```
dlgColorTrigger after exec() [dlgTriggerEditor.cpp:12469,12532]:
→ new dlgColorTrigger(this, ...) → exec() → no delete pD
Hunspell shared dictionary [mudlet.cpp:4768]:
→ mpHunspell_sharedDictionary = nullptr ← missing Hunspell_destroy() before
ExitsTreeWidget takeTopLevelItem [exitstreewidget.cpp:45]:
→ takeTopLevelItem(indexOfTopLevelItem(pItem)) ← return value discarded, never deleted
```
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SlySven/Mudlet now has a Chat Room on Gitter
@SlySven has just created a chat room. You can visit it here: https://gitter.im/SlySven/Mudlet.
This pull-request adds this badge to your README.md:

Happy chatting.
PS: Click here if you would prefer not to receive automatic pull-requests from Gitter in future.