nlohmann::json dump_test;
std::vector<char> data = {
(char)109, (char)108, (char)103, (char)125, (char)-122, (char)-53, (char)115,
(char)18, (char)3, (char)0, (char)102, (char)19, (char)1, (char)15,
(char)-110, (char)13, (char)-3, (char)-1, (char)-81, (char)32, (char)2,
(char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0,
(char)8, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0,
(char)0, (char)0, (char)0, (char)0, (char)0, (char)-80, (char)2,
(char)0, (char)0, (char)96, (char)-118, (char)46, (char)-116, (char)46,
(char)109, (char)-84, (char)-87, (char)108, (char)14, (char)109, (char)-24,
(char)-83, (char)13, (char)-18, (char)-51, (char)-83, (char)-52, (char)-115,
(char)14, (char)6, (char)32, (char)0, (char)0, (char)0, (char)0,
(char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0,
(char)64, (char)3, (char)0, (char)0, (char)0, (char)35, (char)-74,
(char)-73, (char)55, (char)57, (char)-128, (char)0, (char)0, (char)0,
(char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0,
(char)0, (char)0, (char)33, (char)0, (char)0, (char)0, (char)-96,
(char)-54, (char)-28, (char)-26};
dump_test["1"] = std::string{data.data(), data.size()};
dump_test.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
- this 0x0000006792b7e8c0 {o=shared_ptr {str="{\"1\":\"" } [1 strong ref] [make_shared] number_buffer={ size=64 } ...} nlohmann::detail::serializer<nlohmann::basic_json<std::map,std::vector,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,bool,__int64,unsigned __int64,double,std::allocator,nlohmann::adl_serializer> > *
+ o shared_ptr {str="{\"1\":\"" } [1 strong ref] [make_shared] std::shared_ptr<nlohmann::detail::output_adapter_protocol<char> >
+ number_buffer { size=64 } std::array<char,64>
+ loc ucrtbased.dll!0x00007ffc1e3ce020 (load symbols for additional information) {decimal_point=0x00007ffc1e3ce458 "." ...} const lconv *
thousands_sep 0 '\0' const char
decimal_point 46 '.' const char
+ string_buffer { size=512 } std::array<char,512>
indent_char 32 ' ' const char
+ indent_string " ... std::basic_string<char,std::char_traits<char>,std::allocator<char> >
error_handler replace (1) const nlohmann::detail::error_handler_t
byte 230 'æ' const unsigned char
bytes 512 unsigned __int64
bytes_after_last_accept 511 unsigned __int64
codepoint 294 unsigned int
ensure_ascii true const bool
i 106 unsigned __int64
+ s "mlg}†Ës\x12\x3" const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &
state 1 '\x1' unsigned char
undumped_chars 1 unsigned __int64
json_test.exe!std::array<char,512>::operator[](unsigned __int64 _Pos) Line 152 C++
> json_test.exe!nlohmann::detail::serializer<nlohmann::basic_json<std::map,std::vector,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,bool,__int64,unsigned __int64,double,std::allocator,nlohmann::adl_serializer> >::dump_escaped(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & s, const bool ensure_ascii) Line 445 C++
json_test.exe!nlohmann::detail::serializer<nlohmann::basic_json<std::map,std::vector,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,bool,__int64,unsigned __int64,double,std::allocator,nlohmann::adl_serializer> >::dump(const nlohmann::basic_json<std::map,std::vector,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,bool,__int64,unsigned __int64,double,std::allocator,nlohmann::adl_serializer> & val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent) Line 234 C++
json_test.exe!nlohmann::detail::serializer<nlohmann::basic_json<std::map,std::vector,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,bool,__int64,unsigned __int64,double,std::allocator,nlohmann::adl_serializer> >::dump(const nlohmann::basic_json<std::map,std::vector,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,bool,__int64,unsigned __int64,double,std::allocator,nlohmann::adl_serializer> & val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent) Line 165 C++
json_test.exe!nlohmann::basic_json<std::map,std::vector,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,bool,__int64,unsigned __int64,double,std::allocator,nlohmann::adl_serializer>::dump(const int indent, const char indent_char, const bool ensure_ascii, const nlohmann::detail::error_handler_t error_handler) Line 1979 C++
What is the issue you have?
On Windows, with a specifically crafted JSON string object (initialised with std::string), json::dump crashes if
ensure_asciiis set to true, and the error handler is set toerror_handler_t::replace. Looking at the stack trace, it appears thatdump_escapedinsideserializer.hppdoesn't do any bounds checking inside theUTF8_REJECTcase forstring_buffer, which is hardcoded to be exactly 512 bytes.Please describe the steps to reproduce the issue. Can you provide a small but working code example?
Compile and run the following code on Windows (with optimisations disabled and in debug mode):
What is the expected behavior?
It works fine.
And what is the actual behavior instead?
It crashes on serializer.hpp on line 445 (in debug mode). The state of the local variables are:
The stack trace is:
Which compiler and operating system are you using? Is it a supported compiler?
Windows 10. Visual Studio 2015 (latest version).
Did you use a released version of the library or the version from the
developbranch?Version 3.5.0
If you experience a compilation error: can you compile and run the unit tests?
Yes. All pass with Visual Studio 2015.