From 717b08695e3c9c6e5a48ad65858357951b72c525 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sun, 8 Mar 2015 12:05:28 -0500 Subject: [PATCH] clarify errors * use macros for logic errors, not input errors * throw on parsing failure in `operator>>()`, not assert * throw on malloc, not assert --- include/json/assertions.h | 6 +++++- include/json/writer.h | 2 +- src/lib_json/json_reader.cpp | 2 +- src/lib_json/json_value.cpp | 16 ++++++++++------ 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/include/json/assertions.h b/include/json/assertions.h index d5fd661..07e7f2e 100644 --- a/include/json/assertions.h +++ b/include/json/assertions.h @@ -13,6 +13,10 @@ #include "config.h" #endif // if !defined(JSON_IS_AMALGAMATION) +/** It should not be possible for a maliciously designed file to + * cause an abort() or seg-fault, so these macros are used only + * for pre-condition violations and internal logic errors. + */ #if JSON_USE_EXCEPTION #include #define JSON_ASSERT(condition) \ @@ -27,7 +31,7 @@ #define JSON_ASSERT(condition) assert(condition) // The call to assert() will show the failure message in debug builds. In -// release bugs we abort, for a core-dump or debugger. +// release builds we abort, for a core-dump or debugger. #define JSON_FAIL_MESSAGE(message) \ { \ std::ostringstream oss; oss << message; \ diff --git a/include/json/writer.h b/include/json/writer.h index 2d6dbce..f6fcc9c 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -46,7 +46,7 @@ public: /** Write Value into document as configured in sub-class. Do not take ownership of sout, but maintain a reference during function. \pre sout != NULL - \return zero on success + \return zero on success (For now, we always return zero, so check the stream instead.) \throw std::exception possibly, depending on configuration */ virtual int write(Value const& root, std::ostream* sout) = 0; diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 9ceaf38..32f4d02 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1994,7 +1994,7 @@ std::istream& operator>>(std::istream& sin, Value& root) { "Error from reader: %s", errs.c_str()); - JSON_FAIL_MESSAGE("reader error"); + throw std::runtime_error("reader error"); } return sin; } diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 46385b9..4e032ce 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -87,9 +87,11 @@ static inline char* duplicateStringValue(const char* value, length = Value::maxInt - 1; char* newString = static_cast(malloc(length + 1)); - JSON_ASSERT_MESSAGE(newString != 0, - "in Json::Value::duplicateStringValue(): " - "Failed to allocate string value buffer"); + if (newString == NULL) { + throw std::runtime_error( + "in Json::Value::duplicateStringValue(): " + "Failed to allocate string value buffer"); + } memcpy(newString, value, length); newString[length] = 0; return newString; @@ -108,9 +110,11 @@ static inline char* duplicateAndPrefixStringValue( "length too big for prefixing"); unsigned actualLength = length + sizeof(unsigned) + 1U; char* newString = static_cast(malloc(actualLength)); - JSON_ASSERT_MESSAGE(newString != 0, - "in Json::Value::duplicateAndPrefixStringValue(): " - "Failed to allocate string value buffer"); + if (newString == 0) { + throw std::runtime_error( + "in Json::Value::duplicateAndPrefixStringValue(): " + "Failed to allocate string value buffer"); + } *reinterpret_cast(newString) = length; memcpy(newString + sizeof(unsigned), value, length); newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later