-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix JsonDocument::clear() does not clear the KEY_IS_OWNED flag in VariantData's _flags variable #1542
Conversation
This might be related to the (fixed) issue from #1217 (comment) |
Hi @DanielEbert, Thank you very much for this Pull Request. Best Regards, |
TLDR: You can close this PR. I forgot that I had modified my local ArduinoJson source code. This PR fixes a problem that I have introduced with my own (local only) changes -- this problem does not exist with the unmodified latest ArduinoJson version. Long Story: MemorySanitizer complained due to a use-of-uninitialized-value in JsonDocument::clear(). To learn the internals of ArduinoJson I added a bunch of printf statement, including one in clear(): void clear() {
_pool.clear();
//_data.init(); // <- this is my PR
_data.setNull();
if (_data._flags != 0) { // <- these are my local-only modifications
printf("%u", _data._flags); // <- these are my local-only modifications
} // <- these are my local-only modifications
} And I made VariantData's _flags variable public: class VariantData {
...
public:
uint8_t _flags;
... This is my test source code c.cpp: #include "ArduinoJson-v6.17.3.h"
int main(){
char s[] = "{}";
DynamicJsonDocument doc(256);
DeserializationError ret = deserializeJson(doc, s, strlen(s));
return 0;
} Compile & Run (Ubuntu 20.04 64bit, clang 10.0, ArduinoJson-v6.17.3): ➜ clang++ c.cpp -fsanitize=memory && ./a.out
==6754==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x4990a8 in ArduinoJson6173_71::JsonDocument::clear() (/tmp/1/a.out+0x4990a8)
#1 0x498c05 in ArduinoJson6173_71::DeserializationError ArduinoJson6173_71::deserialize<ArduinoJson6173_71::JsonDeserializer, char, ArduinoJson6173_71::AllowAllFilter>(ArduinoJson6173_71::JsonDocument&, char*, unsigned long, ArduinoJson6173_71::NestingLimit, ArduinoJson6173_71::AllowAllFilter) (/tmp/1/a.out+0x498c05)
#2 0x497967 in ArduinoJson6173_71::DeserializationError ArduinoJson6173_71::deserializeJson<char>(ArduinoJson6173_71::JsonDocument&, char*, unsigned long, ArduinoJson6173_71::NestingLimit) (/tmp/1/a.out+0x497967)
#3 0x497541 in main (/tmp/1/a.out+0x497541)
#4 0x7feb1f97e0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
#5 0x41c2ad in _start (/tmp/1/a.out+0x41c2ad)
SUMMARY: MemorySanitizer: use-of-uninitialized-value (/tmp/1/a.out+0x4990a8) in ArduinoJson6173_71::JsonDocument::clear()
Exiting Again, I don't think it is a problem because MemorySanitizer does not complain when the unmodified ArduinoJson version is used. I think I have this problem because my if statement accesses the 'KEY_IS_OWNED' bit of the _flags byte and this bit is not initialized. I assume VariantData does not access this 'KEY_IS_OWNED' bit and for this reason MemorySanitizer does not complain when the unmodified ArduinoJson version is used. |
Indeed, |
I tried to run the test suite with
This was with clang-10 and libc++-10. Do you know how I could work around these problems? |
I get the same error messages. I don't know why that is the case. An alternative would be to use another uninitialized memory sanitizer, such as valgrind. |
Done! I added a Valgrind job to the continuous integration. |
If JsonDocument::clear() is called, the KEY_IS_OWNED flag of JsonDocument's _data variable is not cleared.
Currently, JsonDocument::clear() calls _data.setNull, which calls setType(VALUE_IS_NULL), and setType preserves the KEY_IS_OWNED flag due to the '_flags &= KEY_IS_OWNED;' statement.
In this pull request, the _data.init() call was added to the JsonDocument::clear() method so that the KEY_IS_OWNED flag is cleared.