@ -300,6 +300,46 @@ static void stbsp__lead_sign(stbsp__uint32 fl, char *sign)
}
}
}
}
static STBSP__ASAN stbsp__uint32 stbsp__strlen_limited ( char const * s , stbsp__uint32 limit )
{
char const * sn = s ;
// get up to 4-byte alignment
for ( ; ; ) {
if ( ( ( stbsp__uintptr ) sn & 3 ) = = 0 )
break ;
if ( ! limit | | * sn = = 0 )
return ( stbsp__uint32 ) ( sn - s ) ;
+ + sn ;
- - limit ;
}
// scan over 4 bytes at a time to find terminating 0
// this will intentionally scan up to 3 bytes past the end of buffers,
// but becase it works 4B aligned, it will never cross page boundaries
// (hence the STBSP__ASAN markup; the over-read here is intentional
// and harmless)
while ( limit > = 4 ) {
stbsp__uint32 v = * ( stbsp__uint32 * ) sn ;
// bit hack to find if there's a 0 byte in there
if ( ( v - 0x01010101 ) & ( ~ v ) & 0x80808080UL )
break ;
sn + = 4 ;
limit - = 4 ;
}
// handle the last few characters to find actual size
while ( limit & & * sn ) {
+ + sn ;
- - limit ;
}
return ( stbsp__uint32 ) ( sn - s ) ;
}
STBSP__PUBLICDEF int STB_SPRINTF_DECORATE ( vsprintfcb ) ( STBSP_SPRINTFCB * callback , void * user , char * buf , char const * fmt , va_list va )
STBSP__PUBLICDEF int STB_SPRINTF_DECORATE ( vsprintfcb ) ( STBSP_SPRINTFCB * callback , void * user , char * buf , char const * fmt , va_list va )
{
{
static char hex [ ] = " 0123456789abcdefxp " ;
static char hex [ ] = " 0123456789abcdefxp " ;
@ -543,37 +583,9 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
s = va_arg ( va , char * ) ;
s = va_arg ( va , char * ) ;
if ( s = = 0 )
if ( s = = 0 )
s = ( char * ) " null " ;
s = ( char * ) " null " ;
// get the length
// get the length, limited to desired precision
sn = s ;
// always limit to ~0u chars since our counts are 32b
for ( ; ; ) {
l = stbsp__strlen_limited ( s , ( pr > = 0 ) ? pr : ~ 0u ) ;
if ( ( ( ( stbsp__uintptr ) sn ) & 3 ) = = 0 )
break ;
lchk :
if ( sn [ 0 ] = = 0 )
goto ld ;
+ + sn ;
}
n = 0xffffffff ;
if ( pr > = 0 ) {
n = ( stbsp__uint32 ) ( sn - s ) ;
if ( n > = ( stbsp__uint32 ) pr )
goto ld ;
n = ( ( stbsp__uint32 ) ( pr - n ) ) > > 2 ;
}
while ( n ) {
stbsp__uint32 v = * ( stbsp__uint32 * ) sn ;
if ( ( v - 0x01010101 ) & ( ~ v ) & 0x80808080UL )
goto lchk ;
sn + = 4 ;
- - n ;
}
goto lchk ;
ld :
l = ( stbsp__uint32 ) ( sn - s ) ;
// clamp to precision
if ( l > ( stbsp__uint32 ) pr )
l = pr ;
lead [ 0 ] = 0 ;
lead [ 0 ] = 0 ;
tail [ 0 ] = 0 ;
tail [ 0 ] = 0 ;
pr = 0 ;
pr = 0 ;