fix: Fix OOM crash in SettingsSerializer readStream() VInt decoder. #707
Mergeable / Mergeable
succeeded
May 19, 2026 in 2s
3 checks passed!
Status: PASS
Details
✔️ Validator: TITLE
- ✔️ All the requisite validations passed for 'or' option
Input : fix: Fix OOM crash in SettingsSerializer readStream() VInt decoder.
Settings :{"or":[{"must_include":{"regex":"^(feat|docs|chore|cleanup|fix|refactor|test|style|perf)(\\([^) ]+\\))?:\\ .+$","message":"Semantic release conventions must be followed."}},{"must_include":{"regex":"^Bump [^ ]* from [^ ]* to [^ ]*$","message":"Dependabot PRs are exempt from semantic release conventions."}}]}
✔️ Validator: COMMIT
- ✔️ Your commit messages met the specified criteria
Input : fix: Fix OOM crash in SettingsSerializer readStream() VInt decoder.
readStream() had no bounds check on the VInt shift count or the accumulated size value before calling QByteArray::resize(), allowing a crafted settings file to trigger an unbounded allocation (up to 2GB) and immediate OOM crash. The signed left-shift also produced undefined behavior when the shift exceeded 28 bits. Add the same overflow guard used by dataToVInt() (num2 > sizeof(int) * CHAR_BIT), stream error status checks, and a post-loop validity check on the decoded size before allocation.,test: add unit tests for SettingsSerializer readStream() input validation
Covers the three guards added to readStream():
- OOM payload: VInt encoding 0x7FFFFFFF triggers the shift-count guard
(num2 > sizeof(int)*CHAR_BIT), preventing QByteArray::resize(INT_MAX) - Shift overflow: 5 continuation bytes push shifts past 32 bits,
exercising the same guard for the UB case - Truncated stream: premature EOF is caught by the QDataStream status
check before each readRawData - Zero-size VInt: the post-loop num <= 0 guard rejects empty values
- Valid settings: round-trips a key/value pair through the serializer
- isSerializedFormat: verifies QTOX magic detection
Settings :{"do":"commit","message":{"regex":"^((feat|docs|chore|cleanup|fix|refactor|test|style|perf)(\\([^) ]+\\))?:\\ .+|Bump [^ ]* from [^ ]* to [^ ]*)","message":"Semantic release conventions must be followed."}}
✔️ Validator: DESCRIPTION
- ✔️ description must exclude '\[ \]'
Input : readStream() had no bounds check on the VInt shift count or the accumulated size value before calling QByteArray::resize(), allowing a crafted settings file to trigger an unbounded allocation (up to 2GB) and immediate OOM crash. The signed left-shift also produced undefined behavior when the shift exceeded 28 bits. Add the same overflow guard used by dataToVInt() (num2 > sizeof(int) * CHAR_BIT), stream error status checks, and a post-loop validity check on the decoded size before allocation.
Resolves #706
Settings : {"must_exclude":{"regex":"\\\\[ \\\\]","message":"There are incomplete TODO task(s) unchecked."}}
Loading