Compare commits

...

26 Commits
0.9.4 ... 1.6.1

Author SHA1 Message Date
Christopher Dunn
9cb88d2ca6 1.6.1 <- 1.6.0 2015-03-31 15:07:14 -05:00
Christopher Dunn
363e51c0a9 Merge pull request #232 from cdunn2001/fix-snprintf
Fix snprintf

Well, it passes Travis. But when we have time, we should clean up how snprintf is used in both reader and writer.
2015-03-31 15:06:11 -05:00
Christopher Dunn
240ddb6a1b use std::snprintf for C++11 2015-03-31 15:04:24 -05:00
Baruch Siach
9dd77dc0ef Revert "Use std namespace for snprintf."
This reverts commit 1c58876185.

std::snprintf() is only available in C++11, which is not provided by
all compilers. Since the C library snprintf() can easily be used as a
replacement on Linux systems, this patch changes jsoncpp to use the C
library snprintf() instead of C++11 std::snprintf(), fixing the build error
below:

    src/lib_json/json_writer.cpp:33:18: error: 'snprintf' is not a member of 'std'

See #231, #224, and #218.
2015-03-31 15:04:24 -05:00
Christopher Dunn
244b1496e1 Merge pull request #225 from selaselah/master
fix find_program() bug: no result in not-win sys
2015-03-31 11:32:06 -05:00
selaselah
c083835261 fix find_program() bug: no result in not-win sys 2015-03-19 19:18:58 +08:00
Christopher Dunn
cbe7e7c9cb Merge pull request #221 from btolfa/forgotten-virtual-dtor
Added forgotten virtual dtor for `Json::CharReader::Factory`.

(Without this, the destructor of the derived `CharReaderBuilder` would not be called, which is a small memory leak.)
2015-03-15 13:49:24 -05:00
Tengiz Sharafiev
be183def8f Update reader.h 2015-03-14 21:30:00 +03:00
Christopher Dunn
951bd3d05d Merge pull request #219 from cdunn2001/c-std-headers
Close #218. Fix #214.
2015-03-11 21:36:51 -05:00
Connor Manning
1c58876185 Use std namespace for snprintf. 2015-03-11 21:33:08 -05:00
Connor Manning
2f2034629e Constrain MSVC _isfinite to before 2013, remove duplicate includes. 2015-03-11 21:33:08 -05:00
Dani-Hub
7020451b44 Fix isfinite for MSVC. 2015-03-11 21:32:59 -05:00
Connor Manning
80497f102e Use C++ standard headers. 2015-03-10 18:48:45 -05:00
Dani-Hub
f9feb66be2 Change exception data member
from "reference to string" to "string" (Resolves the most serious part of issue #216)
2015-03-09 18:42:16 -05:00
Christopher Dunn
ed495edcc1 prefer ValueIterator::name() to ::memberName()
in case of embedded nulls
2015-03-08 14:35:00 -05:00
Christopher Dunn
3c0a383877 Merge pull request #212 from cdunn2001/macro-deprec
close #210
2015-03-08 13:10:37 -05:00
Dani-Hub
5003983029 Make preprocessor query robust against older gcc versions 2015-03-08 13:07:27 -05:00
Dani-Hub
871b311e7e Provide JSONCPP_DEPRECATED definitions for clang and gcc 2015-03-08 13:07:27 -05:00
Christopher Dunn
cdbc35f6ac 1.6.0 2015-03-08 12:57:13 -05:00
Christopher Dunn
4e30c4fcdb comments 2015-03-08 12:56:32 -05:00
Christopher Dunn
0d33cb3639 Merge pull request #211 from cdunn2001/except
* Add Json::Exception and derivatives.
* Clarify when exceptions are thrown, to avoid crashes caused by malicious input.
* Use our own type (derived fro std::exception) so they are trappable.
2015-03-08 12:50:34 -05:00
Christopher Dunn
2250b3c29d use Json::RuntimeError 2015-03-08 12:44:55 -05:00
Christopher Dunn
9376368d86 use Json::LogicError in macros 2015-03-08 12:42:53 -05:00
Christopher Dunn
5383794cc9 Runtime/LogicError and throwers 2015-03-08 12:31:57 -05:00
Christopher Dunn
75279ccec2 base Json::Exception 2015-03-08 12:20:06 -05:00
Christopher Dunn
717b08695e clarify errors
* use macros for logic errors, not input errors
* throw on parsing failure in `operator>>()`, not assert
* throw on malloc, not assert
2015-03-08 12:06:22 -05:00
14 changed files with 187 additions and 46 deletions

View File

@@ -60,7 +60,7 @@ ENDMACRO(jsoncpp_parse_version)
#SET( JSONCPP_VERSION_MAJOR X )
#SET( JSONCPP_VERSION_MINOR Y )
#SET( JSONCPP_VERSION_PATCH Z )
SET( JSONCPP_VERSION 1.5.4 )
SET( JSONCPP_VERSION 1.6.1 )
jsoncpp_parse_version( ${JSONCPP_VERSION} JSONCPP_VERSION )
#IF(NOT JSONCPP_VERSION_FOUND)
# MESSAGE(FATAL_ERROR "Failed to parse version string properly. Expect X.Y.Z")

View File

@@ -31,7 +31,7 @@ def find_program(*filenames):
paths = os.environ.get('PATH', '').split(os.pathsep)
suffixes = ('win32' in sys.platform) and '.exe .com .bat .cmd' or ''
for filename in filenames:
for name in [filename+ext for ext in suffixes.split()]:
for name in [filename+ext for ext in suffixes.split(' ')]:
for directory in paths:
full_path = os.path.join(directory, name)
if os.path.isfile(full_path):

View File

@@ -13,22 +13,30 @@
#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 <stdexcept>
#define JSON_ASSERT(condition) \
{if (!(condition)) {throw std::logic_error( "assert json failed" );}} // @todo <= add detail about condition in exception
#define JSON_FAIL_MESSAGE(message) \
// @todo <= add detail about condition in exception
# define JSON_ASSERT(condition) \
{if (!(condition)) {Json::throwLogicError( "assert json failed" );}}
# define JSON_FAIL_MESSAGE(message) \
{ \
std::ostringstream oss; oss << message; \
throw std::logic_error(oss.str()); \
Json::throwLogicError(oss.str()); \
abort(); \
}
//#define JSON_FAIL_MESSAGE(message) throw std::logic_error(message)
#else // JSON_USE_EXCEPTION
#define JSON_ASSERT(condition) assert(condition)
# 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.
#define JSON_FAIL_MESSAGE(message) \
// release builds we abort, for a core-dump or debugger.
# define JSON_FAIL_MESSAGE(message) \
{ \
std::ostringstream oss; oss << message; \
assert(false && oss.str().c_str()); \

View File

@@ -70,6 +70,14 @@
#if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008
/// Indicates that the following function is deprecated.
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
#elif defined(__clang__) && defined(__has_feature)
#if __has_feature(attribute_deprecated_with_message)
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
#endif
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
#elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
#endif
#if !defined(JSONCPP_DEPRECATED)

View File

@@ -110,7 +110,7 @@ public:
* during parsing.
* \deprecated Use getFormattedErrorMessages() instead (typo fix).
*/
JSONCPP_DEPRECATED("Use getFormattedErrorMessages instead")
JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
std::string getFormatedErrorMessages() const;
/** \brief Returns a user friendly string that list errors in the parsed
@@ -270,6 +270,7 @@ public:
class Factory {
public:
virtual ~Factory() {}
/** \brief Allocate a CharReader via operator new().
* \throw std::exception if something goes wrong (e.g. invalid settings)
*/
@@ -279,8 +280,6 @@ public:
/** \brief Build a CharReader implementation.
\deprecated This is experimental and will be altered before the next release.
Usage:
\code
using namespace Json;

View File

@@ -11,6 +11,7 @@
#endif // if !defined(JSON_IS_AMALGAMATION)
#include <string>
#include <vector>
#include <exception>
#ifndef JSON_USE_CPPTL_SMALLMAP
#include <map>
@@ -32,6 +33,31 @@
*/
namespace Json {
/** Base class for all exceptions we throw.
*
* We use nothing but these internally. Of course, STL can throw others.
*/
class JSON_API Exception;
/** Exceptions which the user cannot easily avoid.
*
* E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
*
* \remark derived from Json::Exception
*/
class JSON_API RuntimeError;
/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
*
* These are precondition-violations (user bugs) and internal errors (our bugs).
*
* \remark derived from Json::Exception
*/
class JSON_API LogicError;
/// used internally
void throwRuntimeError(std::string const& msg);
/// used internally
void throwLogicError(std::string const& msg);
/** \brief Type of the value held by a Value object.
*/
enum ValueType {
@@ -641,16 +667,22 @@ public:
/// Value.
Value key() const;
/// Return the index of the referenced Value. -1 if it is not an arrayValue.
/// Return the index of the referenced Value, or -1 if it is not an arrayValue.
UInt index() const;
/// Return the member name of the referenced Value, or "" if it is not an
/// objectValue.
/// \note Avoid `c_str()` on result, as embedded zeroes are possible.
std::string name() const;
/// Return the member name of the referenced Value. "" if it is not an
/// objectValue.
/// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls.
JSONCPP_DEPRECATED("Use `key = name();` instead.")
char const* memberName() const;
/// Return the member name of the referenced Value, or NULL if it is not an
/// objectValue.
/// Better version than memberName(). Allows embedded nulls.
/// \note Better version than memberName(). Allows embedded nulls.
char const* memberName(char const** end) const;
protected:

View File

@@ -4,10 +4,10 @@
#ifndef JSON_VERSION_H_INCLUDED
# define JSON_VERSION_H_INCLUDED
# define JSONCPP_VERSION_STRING "1.5.4"
# define JSONCPP_VERSION_STRING "1.6.1"
# define JSONCPP_VERSION_MAJOR 1
# define JSONCPP_VERSION_MINOR 5
# define JSONCPP_VERSION_PATCH 4
# define JSONCPP_VERSION_MINOR 6
# define JSONCPP_VERSION_PATCH 1
# define JSONCPP_VERSION_QUALIFIER
# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))

View File

@@ -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;
@@ -132,7 +132,7 @@ public:
};
/** \brief Abstract class for writers.
* \deprecated Use StreamWriter.
* \deprecated Use StreamWriter. (And really, this is an implementation detail.)
*/
class JSON_API Writer {
public:
@@ -151,6 +151,7 @@ public:
* \deprecated Use StreamWriterBuilder.
*/
class JSON_API FastWriter : public Writer {
public:
FastWriter();
virtual ~FastWriter() {}

View File

@@ -17,7 +17,6 @@
#include <sstream>
#include <memory>
#include <set>
#include <stdexcept>
#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
#define snprintf _snprintf
@@ -148,7 +147,7 @@ bool Reader::readValue() {
// But this deprecated class has a security problem: Bad input can
// cause a seg-fault. This seems like a fair, binary-compatible way
// to prevent the problem.
if (stackDepth_g >= stackLimit_g) throw std::runtime_error("Exceeded stackLimit in readValue().");
if (stackDepth_g >= stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
++stackDepth_g;
Token token;
@@ -1107,7 +1106,7 @@ bool OurReader::parse(const char* beginDoc,
}
bool OurReader::readValue() {
if (stackDepth_ >= features_.stackLimit_) throw std::runtime_error("Exceeded stackLimit in readValue().");
if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
++stackDepth_;
Token token;
skipCommentTokens(token);
@@ -1431,7 +1430,7 @@ bool OurReader::readObject(Token& tokenStart) {
return addErrorAndRecover(
"Missing ':' after object member name", colon, tokenObjectEnd);
}
if (name.length() >= (1U<<30)) throw std::runtime_error("keylength >= 2^30");
if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30");
if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
std::string msg = "Duplicate key: '" + name + "'";
return addErrorAndRecover(
@@ -1994,7 +1993,7 @@ std::istream& operator>>(std::istream& sin, Value& root) {
"Error from reader: %s",
errs.c_str());
JSON_FAIL_MESSAGE("reader error");
throwRuntimeError("reader error");
}
return sin;
}

View File

@@ -87,9 +87,11 @@ static inline char* duplicateStringValue(const char* value,
length = Value::maxInt - 1;
char* newString = static_cast<char*>(malloc(length + 1));
JSON_ASSERT_MESSAGE(newString != 0,
if (newString == NULL) {
throwRuntimeError(
"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<char*>(malloc(actualLength));
JSON_ASSERT_MESSAGE(newString != 0,
if (newString == 0) {
throwRuntimeError(
"in Json::Value::duplicateAndPrefixStringValue(): "
"Failed to allocate string value buffer");
}
*reinterpret_cast<unsigned*>(newString) = length;
memcpy(newString + sizeof(unsigned), value, length);
newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later
@@ -148,6 +152,47 @@ static inline void releaseStringValue(char* value) { free(value); }
namespace Json {
class JSON_API Exception : public std::exception {
public:
Exception(std::string const& msg);
virtual ~Exception() throw();
virtual char const* what() const throw();
protected:
std::string const msg_;
};
class JSON_API RuntimeError : public Exception {
public:
RuntimeError(std::string const& msg);
};
class JSON_API LogicError : public Exception {
public:
LogicError(std::string const& msg);
};
Exception::Exception(std::string const& msg)
: msg_(msg)
{}
Exception::~Exception() throw()
{}
char const* Exception::what() const throw()
{
return msg_.c_str();
}
RuntimeError::RuntimeError(std::string const& msg)
: Exception(msg)
{}
LogicError::LogicError(std::string const& msg)
: Exception(msg)
{}
void throwRuntimeError(std::string const& msg)
{
throw RuntimeError(msg);
}
void throwLogicError(std::string const& msg)
{
throw LogicError(msg);
}
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////

View File

@@ -92,6 +92,14 @@ UInt ValueIteratorBase::index() const {
return Value::UInt(-1);
}
std::string ValueIteratorBase::name() const {
char const* key;
char const* end;
key = memberName(&end);
if (!key) return std::string();
return std::string(key, end);
}
char const* ValueIteratorBase::memberName() const {
const char* name = (*current_).first.data();
return name ? name : "";

View File

@@ -12,16 +12,25 @@
#include <sstream>
#include <utility>
#include <set>
#include <stdexcept>
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <cassert>
#include <cstring>
#include <cstdio>
#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0
#include <float.h>
#define isfinite _finite
#elif defined(__sun) && defined(__SVR4) //Solaris
#include <ieeefp.h>
#define isfinite finite
#else
#include <cmath>
#define isfinite std::isfinite
#endif
#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
#define snprintf _snprintf
#elif __cplusplus >= 201103L
#define snprintf std::snprintf
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
@@ -29,11 +38,6 @@
#pragma warning(disable : 4996)
#endif
#if defined(__sun) && defined(__SVR4) //Solaris
#include <ieeefp.h>
#define isfinite finite
#endif
namespace Json {
#if __cplusplus >= 201103L
@@ -1080,7 +1084,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
} else if (cs_str == "None") {
cs = CommentStyle::None;
} else {
throw std::runtime_error("commentStyle must be 'All' or 'None'");
throwRuntimeError("commentStyle must be 'All' or 'None'");
}
std::string colonSymbol = " : ";
if (eyc) {

View File

@@ -6,7 +6,6 @@
#include "jsontest.h"
#include <json/config.h>
#include <json/json.h>
#include <stdexcept>
#include <cstring>
// Make numeric limits more convenient to talk about.
@@ -2283,6 +2282,42 @@ JSONTEST_FIXTURE(IteratorTest, distance) {
JSONTEST_ASSERT_STRING_EQUAL("b", str);
}
JSONTEST_FIXTURE(IteratorTest, names) {
Json::Value json;
json["k1"] = "a";
json["k2"] = "b";
Json::ValueIterator it = json.begin();
JSONTEST_ASSERT(it != json.end());
JSONTEST_ASSERT_EQUAL(Json::Value("k1"), it.key());
JSONTEST_ASSERT_STRING_EQUAL("k1", it.name());
JSONTEST_ASSERT_EQUAL(-1, it.index());
++it;
JSONTEST_ASSERT(it != json.end());
JSONTEST_ASSERT_EQUAL(Json::Value("k2"), it.key());
JSONTEST_ASSERT_STRING_EQUAL("k2", it.name());
JSONTEST_ASSERT_EQUAL(-1, it.index());
++it;
JSONTEST_ASSERT(it == json.end());
}
JSONTEST_FIXTURE(IteratorTest, indexes) {
Json::Value json;
json[0] = "a";
json[1] = "b";
Json::ValueIterator it = json.begin();
JSONTEST_ASSERT(it != json.end());
JSONTEST_ASSERT_EQUAL(Json::Value(Json::ArrayIndex(0)), it.key());
JSONTEST_ASSERT_STRING_EQUAL("", it.name());
JSONTEST_ASSERT_EQUAL(0, it.index());
++it;
JSONTEST_ASSERT(it != json.end());
JSONTEST_ASSERT_EQUAL(Json::Value(Json::ArrayIndex(1)), it.key());
JSONTEST_ASSERT_STRING_EQUAL("", it.name());
JSONTEST_ASSERT_EQUAL(1, it.index());
++it;
JSONTEST_ASSERT(it == json.end());
}
int main(int argc, const char* argv[]) {
JsonTest::Runner runner;
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, checkNormalizeFloatingPointStr);
@@ -2347,6 +2382,8 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, BuilderTest, settings);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, distance);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, names);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, indexes);
return runner.runCommandLine(argc, argv);
}

View File

@@ -1 +1 @@
1.5.4
1.6.1