Three complex type cases (pivComplexf, pivComplexd, pivComplexld)
lacked break statements, causing fallthrough to pivTime. Setting
a complex variant from string silently overwrote the value with
PITime::fromString(), corrupting the variant's type and data.
When mmap() returned MAP_FAILED, data stayed as (void*)-1, causing
subsequent read/write/close to pass the null guard and crash.
Now resets data=nullptr, and calls shm_unlink when owner=true to
avoid orphaned shared memory objects.
The float FFT plan generator wrote 8 ints per entry (indices +0..+7)
but declared entrysize=4, causing heap overwrite into the next entry
and incorrect plan array sizing.
processFile() accessed files_[id - 1] without validating id.
When id == 0 (from a crafted network packet), id - 1 = -1 caused
out-of-bounds access. Added bounds check: id must be in range
[1, files_.size()]. Stops receive and logs error on invalid id.
fork() can return -1 on error (too many processes, out of memory).
The old code treated pid_ == -1 as a successful fork, entering the
parent branch and calling waitpid(-1, ...) which waits for ANY
child process. Added explicit check: close pipes, free memory,
and return on fork failure.
In the blocking read path (timeout_ms <= 0), the while loop had no
exit condition for readDevice() returning 0 (EOF) or -1 (error).
This caused an infinite busy-loop at 100% CPU. Added 'else break'
to exit the loop on read failure, matching the timeout branch
which already handles this case.
readDevice() did pos += size instead of pos += ret. The clamping
on the next line (pos = min(pos, data_->size_s())) masked the
issue in practice, but the semantics were wrong. Aligns with
writeDevice() which correctly uses pos += rs.size_s().
open() returns -1 on error. The check fd != 0 treated -1 as a
valid fd (since -1 != 0 is true), causing devctl(-1, ...) and
close(-1) on QNX. Fixed to fd >= 0.
File descriptor 0 is stdin (a valid fd). Using 0 as the 'not-open'
sentinel caused isCreate() to return false and destroy() to skip
close() when pipe() happened to allocate fds {0, 1} (e.g. in daemons
with closed stdio). POSIX convention: -1 = invalid fd.
When the custom client_factory() returned nullptr, the incoming
PIEthernet pointer was leaked. Matches existing pattern used in the
max_clients overflow branch.
- toChar(): char v was uninitialized, causing UB when
sscanf fails to match (empty string). Initialize to 0.
- operator+=(PIConstChars): loop iterated l < d.size() instead of
l < str.size(), reading past the end of str after d.enlarge().
This is a heap buffer overread with undefined behavior.
change subscription logic - now keep subscriptions independently from connecting state. No unregisters on disconnect, but resubscriptions on connect. So one-time subscription on app start and just connect() on lost connection - all subscriptions keeps
1. subscribe now similar to HTTP server, with lambda
2. subscribe topic syntax support all HTTP features as path arguments and wildcards
3. event received() changed to receivedUnhandled() for unhandled messages (should never be called in proper work)
4. internal logic got more complicated, several endpoints may be serviced by single MQTT topic, so nested Map used