3434#include <limits.h>
3535#include <math.h>
3636#include <stdio.h>
37+ #include <stdlib.h>
3738#include <string.h>
3839#include <unistd.h>
3940
@@ -267,6 +268,7 @@ sentrycrashjson_beginElement(SentryCrashJSONEncodeContext *const context, const
267268 SENTRY_ASYNC_SAFE_LOG_DEBUG ("Name was null inside an object" );
268269 return SentryCrashJSON_ERROR_INVALID_DATA ;
269270 }
271+ // CWE-676: name from encode API; null-terminated.
270272 unlikely_if ((result = addQuotedEscapedString (context , name , (int )strlen (name )))
271273 != SentryCrashJSON_OK )
272274 {
@@ -322,6 +324,7 @@ sentrycrashjson_addFloatingPointElement(
322324 unlikely_if (result != SentryCrashJSON_OK ) { return result ; }
323325 char buff [50 ];
324326 snprintf (buff , sizeof (buff ), "%lg" , value );
327+ // CWE-676: snprintf null-terminates buff.
325328 return addJSONData (context , buff , (int )strlen (buff ));
326329}
327330
@@ -333,6 +336,7 @@ sentrycrashjson_addIntegerElement(
333336 unlikely_if (result != SentryCrashJSON_OK ) { return result ; }
334337 char buff [30 ];
335338 snprintf (buff , sizeof (buff ), "%" PRId64 , value );
339+ // CWE-676: snprintf null-terminates buff.
336340 return addJSONData (context , buff , (int )strlen (buff ));
337341}
338342
@@ -344,6 +348,7 @@ sentrycrashjson_addUIntegerElement(
344348 unlikely_if (result != SentryCrashJSON_OK ) { return result ; }
345349 char buff [30 ];
346350 snprintf (buff , sizeof (buff ), "%" PRIu64 , value );
351+ // CWE-676: snprintf null-terminates buff.
347352 return addJSONData (context , buff , (int )strlen (buff ));
348353}
349354
@@ -363,6 +368,7 @@ sentrycrashjson_addStringElement(SentryCrashJSONEncodeContext *const context,
363368 int result = sentrycrashjson_beginElement (context , name );
364369 unlikely_if (result != SentryCrashJSON_OK ) { return result ; }
365370 if (length == SentryCrashJSON_SIZE_AUTOMATIC ) {
371+ // CWE-676: value from encode API; null-terminated.
366372 length = (int )strlen (value );
367373 }
368374 return addQuotedEscapedString (context , value , length );
@@ -959,6 +965,7 @@ decodeString(SentryCrashJSONDecodeContext *context, char *dstBuffer, int dstBuff
959965 // If no escape characters were encountered, we can fast copy.
960966 likely_if (fastCopy )
961967 {
968+ // CWE-676: length < dstBufferLength checked above.
962969 memcpy (dstBuffer , src , length );
963970 dstBuffer [length ] = 0 ;
964971 return SentryCrashJSON_OK ;
@@ -1248,8 +1255,7 @@ decodeElement(const char *const name, SentryCrashJSONDecodeContext *context)
12481255 }
12491256
12501257 // our buffer is not necessarily NULL-terminated, so
1251- // it would be undefined to call sscanf/sttod etc. directly.
1252- // instead we create a temporary string.
1258+ // we create a temporary null-terminated string and use strtod (CWE-676: avoid sscanf).
12531259 double value ;
12541260 int len = (int )(context -> bufferPtr - start );
12551261 if (len >= context -> stringBufferLength ) {
@@ -1265,9 +1271,7 @@ decodeElement(const char *const name, SentryCrashJSONDecodeContext *context)
12651271 strncpy (context -> stringBuffer , start , len );
12661272 context -> stringBuffer [len ] = '\0' ;
12671273
1268- // Parses a floating point number from the string buffer into value using %lg format
1269- // %lg uses shortest decimal representation and removes trailing zeros
1270- sscanf (context -> stringBuffer , "%lg" , & value );
1274+ value = strtod (context -> stringBuffer , NULL );
12711275
12721276 value *= sign ;
12731277 return context -> callbacks -> onFloatingPointElement (name , value , context -> userData );
@@ -1339,6 +1343,7 @@ updateDecoder_readFile(struct JSONFromFileContext *context)
13391343 unlikely_if (remainingLength < bufferLength / 2 )
13401344 {
13411345 int fillLength = bufferLength - remainingLength ;
1346+ // CWE-676: remainingLength <= bufferLength; start has bufferLength bytes.
13421347 memcpy (start , ptr , remainingLength );
13431348 context -> decodeContext -> bufferPtr = start ;
13441349 int bytesRead = (int )read (context -> fd , start + remainingLength , (unsigned )fillLength );
@@ -1415,6 +1420,7 @@ addJSONFromFile_onStringElement(
14151420 const char * const name , const char * const value , void * const userData )
14161421{
14171422 JSONFromFileContext * context = (JSONFromFileContext * )userData ;
1423+ // CWE-676: value from JSON decode; decode produces null-terminated strings.
14181424 int result
14191425 = sentrycrashjson_addStringElement (context -> encodeContext , name , value , (int )strlen (value ));
14201426 context -> updateDecoderCallback (context );
0 commit comments