New events, all read-only (never mutate kernel state, no cleanup/sort calls
- see HLEKernelObjectSubscriber.cpp's header comment):
- hle.object.list: every live kernel object of every type at once (uid,
type, name, one-line quickInfo), with an optional 'type' filter. Uses
KernelObjectPool::IterateAll(), a new type-agnostic sibling of the
existing Iterate<T>().
- hle.eventflag.list/info, hle.mutex.list/info, hle.semaphore.list/info,
hle.msgpipe.list/info, hle.callback.list/info: per-type full detail
(all Native* status struct fields plus waiting-thread lists), reading
straight off the classes exposed in the previous commit.
Also adds JsonWriter::DictScope/ArrayScope (Common/Data/Format/JSONWriter.h)
- RAII push/pop for pushDict()/pushArray(), used throughout the new
handlers. A forgotten or early-returned pop() previously just produced
silently malformed JSON; with 11 new handlers each writing a handful of
nested arrays/dicts, that seemed worth fixing at the API level rather
than trusting every call site to pair things up by hand. Existing
handlers are untouched - this is purely additive.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
raw_bytes_per_frame (the 'fmt ' chunk's blockAlign field) is
unvalidated file data, and was used unchecked in three places:
- Divided into the 'data' chunk size to compute numFrames - a value
of 0 divides by zero (crash).
- malloc()'d for raw_data was never null-checked before ReadData()
wrote into it.
- Passed directly as the read length to the audio decoder on every
frame, regardless of how much data is actually left in raw_data at
the current offset - a bogus blockAlign larger than the real 'data'
chunk size reads past the (padded) allocation into the decoder.
Clamp it to what's actually available.
IsSimpleWAV() only checked raw_bytes_per_frame's upper bound, not that
it exactly matched one of the two cases Sample::Load() actually
handles (16-bit or 8-bit raw PCM) - a value in between passed the
check but matched neither of Load()'s conversion branches, leaving its
output buffer uninitialized and played back as heap garbage.
Reachable via a WAV/AT3 file parsed by BackgroundAudio.cpp - either
the menu background music preview (any EBOOT.PBP's SND0.AT3 track,
just from browsing the game list) or a user-configurable achievement
sound file.
RIFFReader::ReadData() trusted its count argument completely and
memcpy'd straight from the internal buffer with no bounds check.
Hardened it to clamp against the buffer and zero-fill any shortfall,
as defense in depth.
The actual reachable bug was in BackgroundAudio.cpp: it read a WAV
'smpl' chunk into a vector sized by GetCurrentChunkSize(), then
unconditionally indexed smplData[28] (and, for the loop array,
smplData[36]) with no check that the chunk was actually that large -
a short/corrupt chunk in a game's background-music WAV caused a heap
OOB read. Also fixes &smplData[0] being UB when the chunk is empty.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4QAoxV2KY7ek4PcZw3WvY
These dereferenced get()'s result unconditionally, unlike the
two/three-arg "OrDefault" overloads which check. Hit on externally
sourced JSON: UI/Store.cpp reads the remote homebrew-store listing,
UI/DriverManagerScreen.cpp reads user-supplied GPU driver package
metadata - a field simply missing from either crashed the app instead
of failing gracefully.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4QAoxV2KY7ek4PcZw3WvY
pngLoadPtr allocated the decoded buffer directly from attacker-controlled
PNG IHDR dimensions with no upper bound, so browsing a crafted game icon
or savedata could trigger a multi-gigabyte allocation.
- Add maxWidth/maxHeight parameters to pngLoadPtr (default 8192x8192)
and reject images larger than the limits.
- Thread the limits through LoadTextureLevelsFromFileData,
CreateTextureFromFileData, and CreateTextureFromFile.
- Limit game icons to 256x128 in GameInfoCache and IconCache.
Check the ZIM header, dimensions, mip count, allocation arithmetic,
and uncompressed payload size before allocating or copying image data.
This prevents crafted texture files from overflowing the image buffer.
Unfortunately the ub (undefined behavior) sanitizer has some bugs, it doesn't
understand pointers to member functions, so can't use it in-game (due to the
vertex decoder).
Thanks Nemoumbra for the reminder.
* Rename LogType to Log
* Explicitly use the Log:: enum when logging. Allows for autocomplete when editing.
* Mac/ARM64 buildfix
* Do the same with the hle result log macros
* Rename the log names to mixed case while at it.
* iOS buildfix
* Qt buildfix attempt, ARM32 buildfix