cleanup: 6 safety fixes from clang-tidy worklist - #773
Merged
mrjimenez merged 1 commit intoMay 30, 2026
Conversation
…mule-project#770) Fixes the medium-priority cluster from the lint worklist that's surfaced by the .clang-tidy baseline in amule-project#770. Each is a small, isolated safety guard: - src/utils/cas/html.c:89 -- fopen(template,"r") result wasn't NULL- checked before fgetc() dereferenced it; a missing template file crashed the CGI helper. Add the NULL-check + perror+exit to match the existing calloc/fstat error-handling shape in this file. - src/PartFile.cpp:3341, 3420 -- loop variable promoted from uint16 to uint32 to match `partCount` (declared uint32 at line 3193). GetPartCount() currently returns uint16 so today's behaviour is unchanged, but a future widening wouldn't silently truncate the iteration above 65535. Fires bugprone-too-small-loop-variable. - src/utils/aLinkCreator/src/ed2khash.cpp:114 -- user-cancel path (progress hook returning false) freed `buf` but leaked the realloc()-grown `tmpCharHash`. Hash of every mid-run cancelled file leaked the cumulative parthash buffer. Free both. Fires clang-analyzer-unix.Malloc. - src/kademlia/kademlia/Search.cpp:241 -- `(time_t)(uint32 + 3) > time(NULL)` did the addition in uint32 before the cast, so the comparison would reorder near the 2106 32-bit time wraparound. Cast first, add second. Eighty years out, but cheap to write correctly. Fires bugprone-misplaced-widening-cast. - src/ED2KLinkParser.cpp:107 -- `string(getenv("HOME"))` is UB if HOME is unset (rare but possible). Mirror the existing macOS-branch pattern further up the same function: `string(home ? home : "")`. Fires clang-analyzer-cplusplus.StringChecker. - src/BitVector.h:144 -- SetBuffer() ran memcpy(m_vector, src, m_bytes) unconditionally. After clear(), m_vector is NULL and m_bytes is 0, so the call reduces to memcpy(NULL, src, 0), which is C-standard UB even though real libcs no-op it. Guard on m_bytes (matches SetAllTrue() above). Fires clang-analyzer-core.NonNullParamChecker. All builds clean across amule, amuled, amulegui, cas, alc on macOS. Re-run of clang-tidy with the amule-project#770 baseline confirms each of the above sites no longer fires; no new warnings introduced.
Closed
got3nks
added a commit
to got3nks/amule
that referenced
this pull request
Aug 3, 2026
… s (amule-project#773) The poll handler walks a round-robin, one step per timer tick, so at a 1000 ms tick across three steps any one step -- the stats request, or the active page's data -- came round only every ~3 s. The tick halves to 500 ms and the round-robin loses a step that did nothing but advance the index, whose body went away in 255dd95 once the stats packet started carrying the connection state. The tick had to move because the handler only runs on a tick boundary: a wall-clock guard can only round up to the next one, so on a 1000 ms tick the achievable intervals were 1000, 2000, 3000 and nothing between. This is a 3x increase in poll rate for those two requests. It is affordable because they are now incremental updates against the daemon's value maps, so a poll with nothing to report costs a near-empty reply. The daemon-side cost of serving EC_OP_GET_UPDATE does not shrink with the reply -- it still walks the file and client lists to compute the diff -- and at 0.34-2.05 ms measured on a production daemon that is roughly 0.03-0.2% of a core at 1 Hz. Unaffected: the statistics tree still honours GetStatsInterval() and the ED2K link scan still runs at 1 s, both being wall-clock guarded; the reconnect timer is a separate wxTimer; the 30 s reply watchdog is wall-clock based. The round-robin stays because two of its properties are load-bearing. It emits at most one step's worth of requests per tick, so independently-scheduled concerns cannot drift into alignment and burst against a request FIFO whose threshold is 20. And the fifo-full early return sits above the switch, so back-pressure pauses the cycle in place rather than leaving every concern overdue to fire at once on recovery. That matters most for EC_OP_STAT_REQ, EC_OP_GET_SERVERINFO and EC_OP_GET_CHAT_MESSAGES, which go out through SendRequest rather than DoRequery and so have no in-flight guard of their own.
mrjimenez
pushed a commit
to mrjimenez/amule
that referenced
this pull request
Aug 8, 2026
…den (amule-project#817) Losing the EC link put a modal reconnect dialog on screen whether or not the window was there to be seen. Minimised to the taskbar or hidden to the tray it appeared over whatever the user was actually doing and took focus, to explain a frozen window they could not see. The dialog earns its intrusion by explaining that frozen window, so it now waits until there is one. With the window out of sight the retry loop runs exactly as before -- every attempt logged, the countdown ticking, the same 5 s spacing -- and simply draws nothing. Reconnect while minimised and the dialog is never created: the link comes back, polling resumes, nobody is interrupted. Return to the window mid-reconnect and it appears, opening on whatever the loop is doing rather than on "attempt 1", Abort button and all. "Out of sight" means two things and neither alone is enough: minimised to Dock or taskbar keeps IsShown() true with nothing on screen, while hidden to tray leaves the iconized bit clear with no frame at all. CMuleTrayIcon::DoShowHide already had that pair spelled out inline to label its Show/Hide entry; it moves to CamuleDlg::IsVisibleToUser() and both callers share the one definition. Restoring is likewise two paths, because tray-hide never fires wxIconizeEvent and iconize never fires EVT_SHOW, so OnMinimize and OnShow each carry the hook. Neither shows the dialog directly: that would run a nested modal loop whose abort path calls Quit(), and tearing the main window down from a nested loop is what amule-project#738 was about, so it goes through CallAfter. The retry machinery needed no changes -- AttemptReconnect, ScheduleNextReconnect and OnReconnectTimer already guarded every dialog access. What did need splitting is the tail of BeginReconnect, which assumed it was resuming after ShowModal returned; that work moves to FinishReconnect() so it runs whether or not a dialog was ever shown. The dialog was never gated on window state, so what changed recently is how often it is reached rather than when it may appear: amule-project#768 made a silent link trigger a reconnect instead of freezing, and amule-project#773's move to ~1 s polling keeps a request outstanding far more of the time, which is that watchdog's precondition. Iconize is not observable on Wayland (xdg-shell has no such notification), so compositors that never report it keep the old behaviour for the minimise case; the tray paths are unaffected.
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.
Summary
Second cleanup PR from the worklist on #766, addressing six small, isolated safety guards surfaced by the
.clang-tidybaseline in #770:src/utils/cas/html.c:89fopen(template,"r")result not NULL-checked beforefgetcdereferences — crash on missing templateclang-analyzer-unix.Streamsrc/PartFile.cpp:3341, 3420uint16 partNumberloop againstuint32 partCount— would silently truncate above 65535 ifGetPartCount()ever widensbugprone-too-small-loop-variablesrc/utils/aLinkCreator/src/ed2khash.cpp:114bufbut leaks therealloc-growntmpCharHashclang-analyzer-unix.Mallocsrc/kademlia/kademlia/Search.cpp:241(time_t)(uint32 + 3)— addition wraps inuint32before the cast (2106 boundary)bugprone-misplaced-widening-castsrc/ED2KLinkParser.cpp:107string(getenv("HOME"))is UB if HOME unset; mirror the existing macOS-branch's defensive patternclang-analyzer-cplusplus.StringCheckersrc/BitVector.h:144SetBuffercallsmemcpy(NULL, src, 0)afterclear()— C-standard UB, matchesSetAllTrue()pattern aboveclang-analyzer-core.NonNullParamCheckerTest plan
Depends on #770 for the baseline config that surfaced this worklist.