- MString::read() now gives up after repeated I/O errors instead of
looping forever and crashing via realloc() failure (root cause of a
recurring barant.com production crash).
- HTTPRequest::parse() no longer leaks lineParser/headerParser on a
malformed request.
- Log gained size-based rotation (config-driven) and a non-static-mutex
fix; a separate fix stopped rotation from destroying the logs symlink
on its first trigger.
- File.cpp: symlink-preserving rotation support.
- JString: fixed an array-index out-of-bounds and a setString issue.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- File: stat() only after a successful open() (previously ran first with
its result ignored, feeding a missing file's garbage st_size into a
realloc - could crash the whole APIServer on a request for a
nonexistent static asset)
- JString::setString(): always quote+escape the value instead of going
through set()'s literal-value guess, which misclassified any string
starting with digits (e.g. a UUID) as a bare numeric literal and wrote
it unquoted, corrupting later edits to the same JSON document
- MString::remove() (both overloads): fixed an off-by-one that read one
byte past the buffer on a completely full string (found via ASan under
concurrent load)
- CGIFormData: added fields() so callers can iterate every parsed field
without knowing names in advance (used to merge POST body into
jet::Global::variables the same way query-string params already are)