I can't readily generate proper patches because I've done horrible things to the code to get it included in my project. Here's a couple of modifications to 2.12 that I am pretty sure are also valid C, and slightly clean up the code:
Modern C++ demands that printing pointers be done only after casting to void:
static int loop_check(hashtable_t *parents, const json_t *json, char *key, size_t key_size)
{
- snprintf(key, key_size, "%p", json);
+ snprintf(key, key_size, "%p", (void *) json);
This is only used in the conditionally defined code that follows so should be moved in with it:
static uint32_t buf_to_uint32(char *data)
#if !defined(_WIN32) && defined(USE_URANDOM)
You print one buffer into a same-size buffer with extra context and while it might be valid the compiler complains because it doesn't know that. I went with added context, others might prefer ...TEXT_WITH_CONTEXT = 200 or whatever:
#define JSON_ERROR_TEXT_LENGTH 160
+#define JSON_ERROR_CONTEXT_LENGTH 80
#define JSON_ERROR_SOURCE_LENGTH 80
@@ -114,9 +114,9 @@ static void error_set(json_error_t *error, const lex_t *lex,
if(saved_text && saved_text[0])
{
if(lex->saved_text.length <= 20) {
- snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,
+ snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH + JSON_ERROR_CONTEXT_LENGTH,
"%s near '%s'", msg_text, saved_text);
- msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
+ msg_with_context[JSON_ERROR_TEXT_LENGTH + JSON_ERROR_CONTEXT_LENGTH - 1] = '\0';
result = msg_with_context;
}
}
@@ -131,9 +131,9 @@ static void error_set(json_error_t *error, const lex_t *lex,
result = msg_text;
}
else {
- snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,
+ snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH + JSON_ERROR_CONTEXT_LENGTH,
"%s near end of file", msg_text);
- msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
+ msg_with_context[JSON_ERROR_TEXT_LENGTH + JSON_ERROR_CONTEXT_LENGTH - 1] = '\0';
result = msg_with_context;
}
}
I'm chasing some memory issues which block on the clang memory sanitizer complaining about me passing std::string.c_str() values into json_string and json_dump. I think that's legal, but I'm using the buffer+size versions because they work (because passing string.c_str(),string.length() is fine). And I'm struggling to get debug info, so included the code directly in my program (now I get debug info 50% of the time rather than 0%). Anyway, now I get dumps like this and can start trying to make a test case that reproduces the problem. The current JSON file is ~12kB and that's a bit unreasonable:
Uninitialized bytes in __interceptor_memchr at offset 0 inside [0x701000000050, 11)
==17893==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x10e8a9d in parse_object /builds/chris/listener/Listener/../jansson/src/load.c:717:13 /// if (memchr(key, '\0', len)) {
#1 0x10e76bc in parse_value /builds/chris/listener/Listener/../jansson/src/load.c:860:20
#2 0x10e696e in parse_json /builds/chris/listener/Listener/../jansson/src/load.c:897:14
#3 0x10e6cb0 in json_loadf /builds/chris/listener/Listener/../jansson/src/load.c:1029:14
#4 0xf3a54d in digiflex::ConfigurationFile::LoadConfig(digiflex::Configuration&, bool*) /builds/chris/listener/Listener/../common/ConfigurationFile.cpp:70:29
#5 0x12eb216 in UpdateRedisConfig(char*) /builds/chris/listener/Listener/main.cpp:362:14
#6 0x12eb96c in main /builds/chris/listener/Listener/main.cpp:413:5
#7 0x7fbca932f812 in __libc_start_main (/lib64/libc.so.6+0x23812)
#8 0xdaa26d in _start (/code/listener/listener-new+0xdaa26d)
Uninitialized value was created by a heap allocation
#0 0xdb2e83 in malloc /llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp:925:3
#1 0x10e8e51 in jsonp_malloc /builds/chris/listener/Listener/../jansson/src/memory.c:28:12
#2 0x10e7b20 in lex_scan_string /builds/chris/listener/Listener/../jansson/src/load.c:389:9
#3 0x10e72d4 in lex_scan /builds/chris/listener/Listener/../jansson/src/load.c:620:9
#4 0x10e8a11 in parse_object /builds/chris/listener/Listener/../jansson/src/load.c:700:5
#5 0x10e76bc in parse_value /builds/chris/listener/Listener/../jansson/src/load.c:860:20
#6 0x10e696e in parse_json /builds/chris/listener/Listener/../jansson/src/load.c:897:14
#7 0x10e6cb0 in json_loadf /builds/chris/listener/Listener/../jansson/src/load.c:1029:14
#8 0xf3a54d in digiflex::ConfigurationFile::LoadConfig(digiflex::Configuration&, bool*) /builds/chris/listener/Listener/../common/ConfigurationFile.cpp:70:29
#9 0x12eb216 in UpdateRedisConfig(char*) /builds/chris/listener/Listener/main.cpp:362:14
#10 0x12eb96c in main /builds/chris/listener/Listener/main.cpp:413:5
#11 0x7fbca932f812 in __libc_start_main (/lib64/libc.so.6+0x23812)
SUMMARY: MemorySanitizer: use-of-uninitialized-value /builds/chris/listener/Listener/../jansson/src/load.c:717:13 in parse_object