Lameguy64 / PSn00bSDK

The most powerful open source SDK for the PS1 (as far as open source PS1 SDKs go). Not recommended for beginner use.
Other
838 stars 68 forks source link

`vsnprintf` putting terminator char in wrong place causing memory corruption #84

Open maltebp opened 6 months ago

maltebp commented 6 months ago

Background I ran into a memory corruption issue in my code (compiling with psn00bsdk using C++ and PCSX Redux). Stepping through the assembly, using Redux I found the corruption to happen in vsnprintf. Looking at the code for vsnprintf it is pretty obvious what the problem is.

The bug vsnprintf writes the characters to the output buffer calling:

put_in_string(string, ssz, character_to_write, string_pos++);   

I.e. ssz is the size of the output buffer (minus 1 so there is space for terminator), and string_pos is the current position to write to. However, if the size of the output buffer (ssz) is less than string_pos then it will write nothing. But string_pos is still incremented.

Then, right before returning from the function it does this:

string[string_pos] = 0;

I.e., regardless of how big the output buffer string is, it indiscriminately writes the terminator character at the position where the end of the string would be had the buffer been big enough for it.

Note, I use the function like so (snprintf calls vsnprintf):

char dummy_buffy;
int32 num_chars_to_write = snprintf(&dummy_buffy, 1, some_format, some args... );

to gauge how big of a buffer I should allocate for the string.

A fix... I currently don't have the time to fix the issue, but might look at it later.