Skip to content

Guard against empty containers in ARRL Digi decode path (Qt6 crash) - #51

Open
cjkjellander wants to merge 1 commit into
WSJTX:masterfrom
cjkjellander:fix/arrl-digi-empty-container-crashes
Open

Guard against empty containers in ARRL Digi decode path (Qt6 crash)#51
cjkjellander wants to merge 1 commit into
WSJTX:masterfrom
cjkjellander:fix/arrl-digi-empty-container-crashes

Conversation

@cjkjellander

Copy link
Copy Markdown

The ARRL Digital contest feature (SpecOp::ARRL_DIGI) indexes several
containers with the unchecked operator[] while processing decodes in
MainWindow::readFromStdout(). When a decode yields an empty result these
become out-of-bounds accesses. Under Qt6 (unlike Qt5's tolerant
QByteRef/QList) they dereference invalid memory and segfault.

Three sites, all reached only in ARRL_DIGI mode (hence rarely hit):

  1. MainWindow::activeWorked()m_activeCall[call].bands is empty when
    the callsign was never seeded (a default-constructed map entry), so
    ba[0..6]=... writes past the end of the QByteArray.
  2. MainWindow::ARRL_Digi_Update()dt.messageWords()[0] indexes an
    empty QStringList for a decode with no words, then .left(3) reads garbage.
  3. MainWindow::readFromStdout()word[0] indexes the result of
    split(" ", SkipEmptyParts), which can be empty.

Each site gets an isEmpty()/size() guard; behavior is unchanged when the
containers are populated.

Found via gdb backtraces on a Qt6 RelWithDebInfo build while decoding FT8 in
ARRL_DIGI mode — the crash reproduces reliably once jt9 produces decodes.

The ARRL Digital contest feature indexes several containers with the
unchecked operator[] while processing decodes in readFromStdout(),
which segfaults under Qt6 (Qt5's QByteRef/QList tolerated it):

  - activeWorked(): m_activeCall[call].bands is empty when the callsign
    was never seeded via ARRL_Digi_Update(), so ba[3]='d' (and the other
    band slots) write past the end of the QByteArray.
  - ARRL_Digi_Update(): dt.messageWords()[0] indexes an empty QStringList
    for a decode that yields no words.
  - readFromStdout(): word[0] indexes the result of
    split(" ", SkipEmptyParts), which can be empty.

Add isEmpty()/size() guards at each site. These paths only execute in
ARRL_DIGI special-operating mode, which is why they went unnoticed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant