stb_sprintf: not working with 'j' 'z' modifiers
stefano-zanotti-88 opened this issue · comments
Describe the bug
Modifiers 'j' and 'z' do not work properly on some architecture, because the arguments have a size different from that inferred by the library, which results in wrong data being read from the varargs list.
To Reproduce
stb_sprintf(buff, "%ji %zi %ti", (intmax_t)-1, (ssize_t)2, (ptrdiff_t)-3);
taken from the test:
Line 75 in beebb24
To be executed on a platform with:
sizeof(intmax_t) == 8
sizeof(size_t) == 4
sizeof(ptrdiff_t) == 4
e.g. a 32-bit architecture like ARM Cortex-M
Fix
This:
Lines 543 to 551 in beebb24
should be changed to have:
case 'j': ... sizeof(intmax_t)
case 'z': ... sizeof(size_t)
Since intmax_t
is not available for this library (see the discussion here: #633), something else should be used, e.g. assume that it is always 8, or do this:
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#include <stdint.h> // for intmax_t
#endif
...
case 'j':
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
fl |= (sizeof(intmax_t) == 8) ? STBSP__INTMAX : 0;
#else
fl |= STBSP__INTMAX;
#endif
The proper handling was already suggested before (see #633 above), but since it was manually merged, also with the goal of minimizing dependencies, the wrong types were used.