mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-08-17 17:02:51 +08:00
CacheReadString() took the length of a string straight from the .cached file and passed len - 1 to wxCharBuffer. A stored length of 0 underflowed to SIZE_MAX, so wxCharTypeBuffer allocated (SIZE_MAX + 1) bytes, i.e. none, and then wrote its terminator at str[SIZE_MAX], which wraps on 64-bit to a write one byte in front of the block. The buffer was also a byte shorter than the read that filled it, so the terminator was overwritten and the wxString constructor went looking for one past the end, and a large or negative length asked for a huge allocation or a read through a null pointer. Size the buffer as len so the terminator survives the read, as ReadString() in zipstrm.cpp already does, reject a length that cannot have come from CacheWriteString() or that exceeds the file, check the read actually delivered the bytes, and build the string from the known length rather than by scanning for a NUL. The contents and index counts are used to reserve memory before anything is read, so bound them against the file as well, and move the contents loop to std::make_unique so the new early returns cannot leak, as the index loop already does. Fixes #26765. Closes #26766.