diff --git a/.gitignore b/.gitignore index 39d90c22a..7dacb0b67 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,8 @@ jsoncpp_lib_static.dir/ /src/lib_json/Makefile /src/test_lib_json/Makefile /src/test_lib_json/jsoncpp_test + +# eclipse project files +.project +.cproject +/.settings/ diff --git a/include/json/allocator.h b/include/json/allocator.h new file mode 100644 index 000000000..9d8b9fc9c --- /dev/null +++ b/include/json/allocator.h @@ -0,0 +1,94 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef CPPTL_JSON_ALLOCATOR_H_INCLUDED +#define CPPTL_JSON_ALLOCATOR_H_INCLUDED + +#include +#include + +namespace Json { +template +class SecureAllocator { + public: + // Type definitions + using value_type = T; + using pointer = T*; + using const_pointer = const T*; + using reference = T&; + using const_reference = const T&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + /** + * Allocate memory for N items using the standard allocator. + */ + pointer allocate(size_type n) { + // allocate using "global operator new" + return static_cast(::operator new(n * sizeof(T))); + } + + /** + * Release memory which was allocated for N items at pointer P. + * + * The memory block is filled with zeroes before being released. + * The pointer argument is tagged as "volatile" to prevent the + * compiler optimizing out this critical step. + */ + void deallocate(volatile pointer p, size_type n) { + std::memset(p, 0, n * sizeof(T)); + // free using "global operator delete" + ::operator delete(p); + } + + /** + * Construct an item in-place at pointer P. + */ + template + void construct(pointer p, Args&&... args) { + // construct using "placement new" and "perfect forwarding" + ::new (static_cast(p)) T(std::forward(args)...); + } + + size_type max_size() const { + return size_t(-1) / sizeof(T); + } + + pointer address( reference x ) const { + return std::addressof(x); + } + + const_pointer address( const_reference x ) const { + return std::addressof(x); + } + + /** + * Destroy an item in-place at pointer P. + */ + void destroy(pointer p) { + // destroy using "explicit destructor" + p->~T(); + } + + // Boilerplate + SecureAllocator() {} + template SecureAllocator(const SecureAllocator&) {} + template struct rebind { using other = SecureAllocator; }; +}; + + +template +bool operator==(const SecureAllocator&, const SecureAllocator&) { + return true; +} + +template +bool operator!=(const SecureAllocator&, const SecureAllocator&) { + return false; +} + +} //namespace Json + +#endif // CPPTL_JSON_ALLOCATOR_H_INCLUDED diff --git a/include/json/config.h b/include/json/config.h index 909ef8c13..c823f25f7 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -6,6 +6,7 @@ #ifndef JSON_CONFIG_H_INCLUDED #define JSON_CONFIG_H_INCLUDED #include +#include "allocator.h" //typedef Allocator #include //typdef String /// If defined, indicates that json library is embedded in CppTL library. @@ -119,6 +120,16 @@ # define JSON_USE_INT64_DOUBLE_CONVERSION 1 #endif +// If non-zero, the library zeroes any memory that it has allocated before +// it frees its +#ifndef JSON_USE_SECURE_MEMORY +#define JSON_USE_SECURE_MEMORY 0 +#endif + +#if JSON_USE_SECURE_MEMORY +#include "allocator.h" //typedef Allocator +#endif + namespace Json { typedef int Int; typedef unsigned int UInt; @@ -139,11 +150,19 @@ typedef Int64 LargestInt; typedef UInt64 LargestUInt; #define JSON_HAS_INT64 #endif // if defined(JSON_NO_INT64) +#if JSON_USE_SECURE_MEMORY +#define JSONCPP_STRING std::basic_string, Json::SecureAllocator > +#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream, Json::SecureAllocator > +#define JSONCPP_OSTREAM std::basic_ostream> +#define JSONCPP_ISTRINGSTREAM std::basic_istringstream, Json::SecureAllocator > +#define JSONCPP_ISTREAM std::istream +#else #define JSONCPP_STRING std::string #define JSONCPP_OSTRINGSTREAM std::ostringstream #define JSONCPP_OSTREAM std::ostream #define JSONCPP_ISTRINGSTREAM std::istringstream #define JSONCPP_ISTREAM std::istream +#endif // if JSON_USE_SECURE_MEMORY } // end namespace Json #endif // JSON_CONFIG_H_INCLUDED diff --git a/include/json/reader.h b/include/json/reader.h index 720e63894..959b5d639 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -44,7 +44,7 @@ class JSON_API Reader { struct StructuredError { ptrdiff_t offset_start; ptrdiff_t offset_limit; - std::string message; + JSONCPP_STRING message; }; /** \brief Constructs a Reader allowing all features @@ -111,7 +111,7 @@ class JSON_API Reader { * \deprecated Use getFormattedErrorMessages() instead (typo fix). */ JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") - std::string getFormatedErrorMessages() const; + JSONCPP_STRING getFormatedErrorMessages() const; /** \brief Returns a user friendly string that list errors in the parsed * document. @@ -121,7 +121,7 @@ class JSON_API Reader { * occurred * during parsing. */ - std::string getFormattedErrorMessages() const; + JSONCPP_STRING getFormattedErrorMessages() const; /** \brief Returns a vector of structured erros encounted while parsing. * \return A (possibly empty) vector of StructuredError objects. Currently @@ -138,7 +138,7 @@ class JSON_API Reader { * \return \c true if the error was successfully added, \c false if the * Value offset exceeds the document size. */ - bool pushError(const Value& value, const std::string& message); + bool pushError(const Value& value, const JSONCPP_STRING& message); /** \brief Add a semantic error message with extra context. * \param value JSON Value location associated with the error @@ -147,7 +147,7 @@ class JSON_API Reader { * \return \c true if the error was successfully added, \c false if either * Value offset exceeds the document size. */ - bool pushError(const Value& value, const std::string& message, const Value& extra); + bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra); /** \brief Return whether there are any errors. * \return \c true if there are no errors to report \c false if @@ -183,7 +183,7 @@ class JSON_API Reader { class ErrorInfo { public: Token token_; - std::string message_; + JSONCPP_STRING message_; Location extra_; }; @@ -203,7 +203,7 @@ class JSON_API Reader { bool decodeNumber(Token& token); bool decodeNumber(Token& token, Value& decoded); bool decodeString(Token& token); - bool decodeString(Token& token, std::string& decoded); + bool decodeString(Token& token, JSONCPP_STRING& decoded); bool decodeDouble(Token& token); bool decodeDouble(Token& token, Value& decoded); bool decodeUnicodeCodePoint(Token& token, @@ -214,9 +214,9 @@ class JSON_API Reader { Location& current, Location end, unsigned int& unicode); - bool addError(const std::string& message, Token& token, Location extra = 0); + bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); bool recoverFromError(TokenType skipUntilToken); - bool addErrorAndRecover(const std::string& message, + bool addErrorAndRecover(const JSONCPP_STRING& message, Token& token, TokenType skipUntilToken); void skipUntilSpace(); @@ -224,20 +224,20 @@ class JSON_API Reader { Char getNextChar(); void getLocationLineAndColumn(Location location, int& line, int& column) const; - std::string getLocationLineAndColumn(Location location) const; + JSONCPP_STRING getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); void skipCommentTokens(Token& token); typedef std::stack Nodes; Nodes nodes_; Errors errors_; - std::string document_; + JSONCPP_STRING document_; Location begin_; Location end_; Location current_; Location lastValueEnd_; Value* lastValue_; - std::string commentsBefore_; + JSONCPP_STRING commentsBefore_; Features features_; bool collectComments_; }; // Reader @@ -266,7 +266,7 @@ class JSON_API CharReader { */ virtual bool parse( char const* beginDoc, char const* endDoc, - Value* root, std::string* errs) = 0; + Value* root, JSONCPP_STRING* errs) = 0; class JSON_API Factory { public: @@ -286,7 +286,7 @@ class JSON_API CharReader { CharReaderBuilder builder; builder["collectComments"] = false; Value value; - std::string errs; + JSONCPP_STRING errs; bool ok = parseFromStream(builder, std::cin, &value, &errs); \endcode */ @@ -344,7 +344,7 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { /** A simple way to update a specific setting. */ - Value& operator[](std::string key); + Value& operator[](JSONCPP_STRING key); /** Called by ctor, but you can use this to reset settings_. * \pre 'settings' != NULL (but Json::null is fine) diff --git a/include/json/value.h b/include/json/value.h index 08ae6f6f1..3b7b34ce6 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -323,6 +323,9 @@ Json::Value obj_value(Json::objectValue); // {} int compare(const Value& other) const; const char* asCString() const; ///< Embedded zeroes could cause you trouble! +#if JSON_USE_SECURE_MEMORY + unsigned getCStringLength() const; //Allows you to understand the length of the CString +#endif JSONCPP_STRING asString() const; ///< Embedded zeroes are possible. /** Get raw char* of string-value. * \return false if !string. (Seg-fault if str or end are NULL.) diff --git a/include/json/writer.h b/include/json/writer.h index 443b752bb..58c716b06 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -66,7 +66,7 @@ class JSON_API StreamWriter { /** \brief Write into stringstream, then return string, for convenience. * A StreamWriter will be created from the factory, used, and then deleted. */ -std::string JSON_API writeString(StreamWriter::Factory const& factory, Value const& root); +JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root); /** \brief Build a StreamWriter implementation. @@ -125,7 +125,7 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { bool validate(Json::Value* invalid) const; /** A simple way to update a specific setting. */ - Value& operator[](std::string key); + Value& operator[](JSONCPP_STRING key); /** Called by ctor, but you can use this to reset settings_. * \pre 'settings' != NULL (but Json::null is fine) @@ -142,7 +142,7 @@ class JSON_API Writer { public: virtual ~Writer(); - virtual std::string write(const Value& root) = 0; + virtual JSONCPP_STRING write(const Value& root) = 0; }; /** \brief Outputs a Value in JSON format @@ -172,12 +172,12 @@ class JSON_API FastWriter : public Writer { void omitEndingLineFeed(); public: // overridden from Writer - std::string write(const Value& root) override; + JSONCPP_STRING write(const Value& root) override; private: void writeValue(const Value& value); - std::string document_; + JSONCPP_STRING document_; bool yamlCompatiblityEnabled_; bool dropNullPlaceholders_; bool omitEndingLineFeed_; @@ -217,27 +217,27 @@ class JSON_API StyledWriter : public Writer { * \param root Value to serialize. * \return String containing the JSON document that represents the root value. */ - std::string write(const Value& root) override; + JSONCPP_STRING write(const Value& root) override; private: void writeValue(const Value& value); void writeArrayValue(const Value& value); bool isMultineArray(const Value& value); - void pushValue(const std::string& value); + void pushValue(const JSONCPP_STRING& value); void writeIndent(); - void writeWithIndent(const std::string& value); + void writeWithIndent(const JSONCPP_STRING& value); void indent(); void unindent(); void writeCommentBeforeValue(const Value& root); void writeCommentAfterValueOnSameLine(const Value& root); bool hasCommentForValue(const Value& value); - static std::string normalizeEOL(const std::string& text); + static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); - typedef std::vector ChildValues; + typedef std::vector ChildValues; ChildValues childValues_; - std::string document_; - std::string indentString_; + JSONCPP_STRING document_; + JSONCPP_STRING indentString_; unsigned int rightMargin_; unsigned int indentSize_; bool addChildValues_; @@ -271,7 +271,7 @@ class JSON_API StyledWriter : public Writer { */ class JSON_API StyledStreamWriter { public: - StyledStreamWriter(std::string indentation = "\t"); + StyledStreamWriter(JSONCPP_STRING indentation = "\t"); ~StyledStreamWriter() {} public: @@ -287,36 +287,36 @@ class JSON_API StyledStreamWriter { void writeValue(const Value& value); void writeArrayValue(const Value& value); bool isMultineArray(const Value& value); - void pushValue(const std::string& value); + void pushValue(const JSONCPP_STRING& value); void writeIndent(); - void writeWithIndent(const std::string& value); + void writeWithIndent(const JSONCPP_STRING& value); void indent(); void unindent(); void writeCommentBeforeValue(const Value& root); void writeCommentAfterValueOnSameLine(const Value& root); bool hasCommentForValue(const Value& value); - static std::string normalizeEOL(const std::string& text); + static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); - typedef std::vector ChildValues; + typedef std::vector ChildValues; ChildValues childValues_; JSONCPP_OSTREAM* document_; - std::string indentString_; + JSONCPP_STRING indentString_; unsigned int rightMargin_; - std::string indentation_; + JSONCPP_STRING indentation_; bool addChildValues_ : 1; bool indented_ : 1; }; #if defined(JSON_HAS_INT64) -std::string JSON_API valueToString(Int value); -std::string JSON_API valueToString(UInt value); +JSONCPP_STRING JSON_API valueToString(Int value); +JSONCPP_STRING JSON_API valueToString(UInt value); #endif // if defined(JSON_HAS_INT64) -std::string JSON_API valueToString(LargestInt value); -std::string JSON_API valueToString(LargestUInt value); -std::string JSON_API valueToString(double value); -std::string JSON_API valueToString(bool value); -std::string JSON_API valueToQuotedString(const char* value); +JSONCPP_STRING JSON_API valueToString(LargestInt value); +JSONCPP_STRING JSON_API valueToString(LargestUInt value); +JSONCPP_STRING JSON_API valueToString(double value); +JSONCPP_STRING JSON_API valueToString(bool value); +JSONCPP_STRING JSON_API valueToQuotedString(const char* value); /// \brief Output using the StyledStreamWriter. /// \see Json::operator>>() diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index a0c88bd79..05d973b95 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -17,14 +17,14 @@ struct Options { - std::string path; + JSONCPP_STRING path; Json::Features features; bool parseOnly; - typedef std::string (*writeFuncType)(Json::Value const&); + typedef JSONCPP_STRING (*writeFuncType)(Json::Value const&); writeFuncType write; }; -static std::string normalizeFloatingPointStr(double value) { +static JSONCPP_STRING normalizeFloatingPointStr(double value) { char buffer[32]; #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) sprintf_s(buffer, sizeof(buffer), "%.16g", value); @@ -32,18 +32,21 @@ static std::string normalizeFloatingPointStr(double value) { snprintf(buffer, sizeof(buffer), "%.16g", value); #endif buffer[sizeof(buffer) - 1] = 0; - std::string s(buffer); - std::string::size_type index = s.find_last_of("eE"); - if (index != std::string::npos) { - std::string::size_type hasSign = + JSONCPP_STRING s(buffer); +#if JSON_USE_SECURE_MEMORY + memset(&buffer, 0, sizeof(buffer)); +#endif + JSONCPP_STRING::size_type index = s.find_last_of("eE"); + if (index != JSONCPP_STRING::npos) { + JSONCPP_STRING::size_type hasSign = (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; - std::string::size_type exponentStartIndex = index + 1 + hasSign; - std::string normalized = s.substr(0, exponentStartIndex); - std::string::size_type indexDigit = + JSONCPP_STRING::size_type exponentStartIndex = index + 1 + hasSign; + JSONCPP_STRING normalized = s.substr(0, exponentStartIndex); + JSONCPP_STRING::size_type indexDigit = s.find_first_not_of('0', exponentStartIndex); - std::string exponent = "0"; + JSONCPP_STRING exponent = "0"; if (indexDigit != - std::string::npos) // There is an exponent different from 0 + JSONCPP_STRING::npos) // There is an exponent different from 0 { exponent = s.substr(indexDigit); } @@ -52,26 +55,29 @@ static std::string normalizeFloatingPointStr(double value) { return s; } -static std::string readInputTestFile(const char* path) { +static JSONCPP_STRING readInputTestFile(const char* path) { FILE* file = fopen(path, "rb"); if (!file) - return std::string(""); + return JSONCPP_STRING(""); fseek(file, 0, SEEK_END); long const size = ftell(file); unsigned long const usize = static_cast(size); fseek(file, 0, SEEK_SET); - std::string text; + JSONCPP_STRING text; char* buffer = new char[size + 1]; buffer[size] = 0; if (fread(buffer, 1, usize, file) == usize) text = buffer; fclose(file); +#if JSON_USE_SECURE_MEMORY + memset(buffer, 0, static_cast(size + 1)); +#endif delete[] buffer; return text; } static void -printValueTree(FILE* fout, Json::Value& value, const std::string& path = ".") { +printValueTree(FILE* fout, Json::Value& value, const JSONCPP_STRING& path = ".") { if (value.hasComment(Json::commentBefore)) { fprintf(fout, "%s\n", value.getComment(Json::commentBefore).c_str()); } @@ -120,11 +126,11 @@ printValueTree(FILE* fout, Json::Value& value, const std::string& path = ".") { fprintf(fout, "%s={}\n", path.c_str()); Json::Value::Members members(value.getMemberNames()); std::sort(members.begin(), members.end()); - std::string suffix = *(path.end() - 1) == '.' ? "" : "."; + JSONCPP_STRING suffix = *(path.end() - 1) == '.' ? "" : "."; for (Json::Value::Members::iterator it = members.begin(); it != members.end(); ++it) { - const std::string& name = *it; + const JSONCPP_STRING name = *it; printValueTree(fout, value[name], path + suffix + name); } } break; @@ -137,15 +143,15 @@ printValueTree(FILE* fout, Json::Value& value, const std::string& path = ".") { } } -static int parseAndSaveValueTree(const std::string& input, - const std::string& actual, - const std::string& kind, +static int parseAndSaveValueTree(const JSONCPP_STRING& input, + const JSONCPP_STRING& actual, + const JSONCPP_STRING& kind, const Json::Features& features, bool parseOnly, Json::Value* root) { Json::Reader reader(features); - bool parsingSuccessful = reader.parse(input, *root); + bool parsingSuccessful = reader.parse(input.data(), input.data() + input.size(), *root); if (!parsingSuccessful) { printf("Failed to parse %s file: \n%s\n", kind.c_str(), @@ -163,18 +169,18 @@ static int parseAndSaveValueTree(const std::string& input, } return 0; } -// static std::string useFastWriter(Json::Value const& root) { +// static JSONCPP_STRING useFastWriter(Json::Value const& root) { // Json::FastWriter writer; // writer.enableYAMLCompatibility(); // return writer.write(root); // } -static std::string useStyledWriter( +static JSONCPP_STRING useStyledWriter( Json::Value const& root) { Json::StyledWriter writer; return writer.write(root); } -static std::string useStyledStreamWriter( +static JSONCPP_STRING useStyledStreamWriter( Json::Value const& root) { Json::StyledStreamWriter writer; @@ -182,17 +188,17 @@ static std::string useStyledStreamWriter( writer.write(sout, root); return sout.str(); } -static std::string useBuiltStyledStreamWriter( +static JSONCPP_STRING useBuiltStyledStreamWriter( Json::Value const& root) { Json::StreamWriterBuilder builder; return Json::writeString(builder, root); } static int rewriteValueTree( - const std::string& rewritePath, + const JSONCPP_STRING& rewritePath, const Json::Value& root, Options::writeFuncType write, - std::string* rewrite) + JSONCPP_STRING* rewrite) { *rewrite = write(root); FILE* fout = fopen(rewritePath.c_str(), "wt"); @@ -205,13 +211,13 @@ static int rewriteValueTree( return 0; } -static std::string removeSuffix(const std::string& path, - const std::string& extension) { +static JSONCPP_STRING removeSuffix(const JSONCPP_STRING& path, + const JSONCPP_STRING& extension) { if (extension.length() >= path.length()) - return std::string(""); - std::string suffix = path.substr(path.length() - extension.length()); + return JSONCPP_STRING(""); + JSONCPP_STRING suffix = path.substr(path.length() - extension.length()); if (suffix != extension) - return std::string(""); + return JSONCPP_STRING(""); return path.substr(0, path.length() - extension.length()); } @@ -238,18 +244,18 @@ static int parseCommandLine( return printUsage(argv); } int index = 1; - if (std::string(argv[index]) == "--json-checker") { + if (JSONCPP_STRING(argv[index]) == "--json-checker") { opts->features = Json::Features::strictMode(); opts->parseOnly = true; ++index; } - if (std::string(argv[index]) == "--json-config") { + if (JSONCPP_STRING(argv[index]) == "--json-config") { printConfig(); return 3; } - if (std::string(argv[index]) == "--json-writer") { + if (JSONCPP_STRING(argv[index]) == "--json-writer") { ++index; - std::string const writerName(argv[index++]); + JSONCPP_STRING const writerName(argv[index++]); if (writerName == "StyledWriter") { opts->write = &useStyledWriter; } else if (writerName == "StyledStreamWriter") { @@ -271,22 +277,22 @@ static int runTest(Options const& opts) { int exitCode = 0; - std::string input = readInputTestFile(opts.path.c_str()); + JSONCPP_STRING input = readInputTestFile(opts.path.c_str()); if (input.empty()) { printf("Failed to read input or empty input: %s\n", opts.path.c_str()); return 3; } - std::string basePath = removeSuffix(opts.path, ".json"); + JSONCPP_STRING basePath = removeSuffix(opts.path, ".json"); if (!opts.parseOnly && basePath.empty()) { printf("Bad input path. Path does not end with '.expected':\n%s\n", opts.path.c_str()); return 3; } - std::string const actualPath = basePath + ".actual"; - std::string const rewritePath = basePath + ".rewrite"; - std::string const rewriteActualPath = basePath + ".actual-rewrite"; + JSONCPP_STRING const actualPath = basePath + ".actual"; + JSONCPP_STRING const rewritePath = basePath + ".rewrite"; + JSONCPP_STRING const rewriteActualPath = basePath + ".actual-rewrite"; Json::Value root; exitCode = parseAndSaveValueTree( @@ -295,7 +301,7 @@ static int runTest(Options const& opts) if (exitCode || opts.parseOnly) { return exitCode; } - std::string rewrite; + JSONCPP_STRING rewrite; exitCode = rewriteValueTree(rewritePath, root, opts.write, &rewrite); if (exitCode) { return exitCode; diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index bfa484bf4..ef71e19f5 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -98,7 +98,8 @@ Reader::Reader(const Features& features) bool Reader::parse(const std::string& document, Value& root, bool collectComments) { - document_ = document; + JSONCPP_STRING documentCopy(document.data(), document.data() + document.capacity()); + std::swap(documentCopy, document_); const char* begin = document_.c_str(); const char* end = begin + document_.length(); return parse(begin, end, root, collectComments); @@ -110,11 +111,11 @@ bool Reader::parse(std::istream& sin, Value& root, bool collectComments) { // Those would allow streamed input from a file, if parse() were a // template function. - // Since std::string is reference-counted, this at least does not + // Since JSONCPP_STRING is reference-counted, this at least does not // create an extra copy. - std::string doc; + JSONCPP_STRING doc; std::getline(sin, doc, (char)EOF); - return parse(doc, root, collectComments); + return parse(doc.data(), doc.data() + doc.size(), root, collectComments); } bool Reader::parse(const char* beginDoc, @@ -368,8 +369,8 @@ bool Reader::readComment() { return true; } -static std::string normalizeEOL(Reader::Location begin, Reader::Location end) { - std::string normalized; +static JSONCPP_STRING normalizeEOL(Reader::Location begin, Reader::Location end) { + JSONCPP_STRING normalized; normalized.reserve(static_cast(end - begin)); Reader::Location current = begin; while (current != end) { @@ -390,7 +391,7 @@ static std::string normalizeEOL(Reader::Location begin, Reader::Location end) { void Reader::addComment(Location begin, Location end, CommentPlacement placement) { assert(collectComments_); - const std::string& normalized = normalizeEOL(begin, end); + const JSONCPP_STRING& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { assert(lastValue_ != 0); lastValue_->setComment(normalized, placement); @@ -460,7 +461,7 @@ bool Reader::readString() { bool Reader::readObject(Token& tokenStart) { Token tokenName; - std::string name; + JSONCPP_STRING name; Value init(objectValue); currentValue().swapPayload(init); currentValue().setOffsetStart(tokenStart.start_ - begin_); @@ -480,7 +481,7 @@ bool Reader::readObject(Token& tokenStart) { Value numberName; if (!decodeNumber(tokenName, numberName)) return recoverFromError(tokenObjectEnd); - name = numberName.asString(); + name = JSONCPP_STRING(numberName.asCString()); } else { break; } @@ -616,10 +617,10 @@ bool Reader::decodeDouble(Token& token) { bool Reader::decodeDouble(Token& token, Value& decoded) { double value = 0; - std::string buffer(token.start_, token.end_); + JSONCPP_STRING buffer(token.start_, token.end_); JSONCPP_ISTRINGSTREAM is(buffer); if (!(is >> value)) - return addError("'" + std::string(token.start_, token.end_) + + return addError("'" + JSONCPP_STRING(token.start_, token.end_) + "' is not a number.", token); decoded = value; @@ -627,7 +628,7 @@ bool Reader::decodeDouble(Token& token, Value& decoded) { } bool Reader::decodeString(Token& token) { - std::string decoded_string; + JSONCPP_STRING decoded_string; if (!decodeString(token, decoded_string)) return false; Value decoded(decoded_string); @@ -637,7 +638,7 @@ bool Reader::decodeString(Token& token) { return true; } -bool Reader::decodeString(Token& token, std::string& decoded) { +bool Reader::decodeString(Token& token, JSONCPP_STRING& decoded) { decoded.reserve(static_cast(token.end_ - token.start_ - 2)); Location current = token.start_ + 1; // skip '"' Location end = token.end_ - 1; // do not include '"' @@ -749,7 +750,7 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token, } bool -Reader::addError(const std::string& message, Token& token, Location extra) { +Reader::addError(const JSONCPP_STRING& message, Token& token, Location extra) { ErrorInfo info; info.token_ = token; info.message_ = message; @@ -771,7 +772,7 @@ bool Reader::recoverFromError(TokenType skipUntilToken) { return false; } -bool Reader::addErrorAndRecover(const std::string& message, +bool Reader::addErrorAndRecover(const JSONCPP_STRING& message, Token& token, TokenType skipUntilToken) { addError(message, token); @@ -809,7 +810,7 @@ void Reader::getLocationLineAndColumn(Location location, ++line; } -std::string Reader::getLocationLineAndColumn(Location location) const { +JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) const { int line, column; getLocationLineAndColumn(location, line, column); char buffer[18 + 16 + 16 + 1]; @@ -818,12 +819,12 @@ std::string Reader::getLocationLineAndColumn(Location location) const { } // Deprecated. Preserved for backward compatibility -std::string Reader::getFormatedErrorMessages() const { +JSONCPP_STRING Reader::getFormatedErrorMessages() const { return getFormattedErrorMessages(); } -std::string Reader::getFormattedErrorMessages() const { - std::string formattedMessage; +JSONCPP_STRING Reader::getFormattedErrorMessages() const { + JSONCPP_STRING formattedMessage; for (Errors::const_iterator itError = errors_.begin(); itError != errors_.end(); ++itError) { @@ -853,7 +854,7 @@ std::vector Reader::getStructuredErrors() const { return allErrors; } -bool Reader::pushError(const Value& value, const std::string& message) { +bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) { ptrdiff_t const length = end_ - begin_; if(value.getOffsetStart() > length || value.getOffsetLimit() > length) @@ -870,7 +871,7 @@ bool Reader::pushError(const Value& value, const std::string& message) { return true; } -bool Reader::pushError(const Value& value, const std::string& message, const Value& extra) { +bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) { ptrdiff_t const length = end_ - begin_; if(value.getOffsetStart() > length || value.getOffsetLimit() > length @@ -923,7 +924,7 @@ class OurReader { struct StructuredError { ptrdiff_t offset_start; ptrdiff_t offset_limit; - std::string message; + JSONCPP_STRING message; }; OurReader(OurFeatures const& features); @@ -931,10 +932,10 @@ class OurReader { const char* endDoc, Value& root, bool collectComments = true); - std::string getFormattedErrorMessages() const; + JSONCPP_STRING getFormattedErrorMessages() const; std::vector getStructuredErrors() const; - bool pushError(const Value& value, const std::string& message); - bool pushError(const Value& value, const std::string& message, const Value& extra); + bool pushError(const Value& value, const JSONCPP_STRING& message); + bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra); bool good() const; private: @@ -971,7 +972,7 @@ class OurReader { class ErrorInfo { public: Token token_; - std::string message_; + JSONCPP_STRING message_; Location extra_; }; @@ -992,7 +993,7 @@ class OurReader { bool decodeNumber(Token& token); bool decodeNumber(Token& token, Value& decoded); bool decodeString(Token& token); - bool decodeString(Token& token, std::string& decoded); + bool decodeString(Token& token, JSONCPP_STRING& decoded); bool decodeDouble(Token& token); bool decodeDouble(Token& token, Value& decoded); bool decodeUnicodeCodePoint(Token& token, @@ -1003,9 +1004,9 @@ class OurReader { Location& current, Location end, unsigned int& unicode); - bool addError(const std::string& message, Token& token, Location extra = 0); + bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); bool recoverFromError(TokenType skipUntilToken); - bool addErrorAndRecover(const std::string& message, + bool addErrorAndRecover(const JSONCPP_STRING& message, Token& token, TokenType skipUntilToken); void skipUntilSpace(); @@ -1013,20 +1014,20 @@ class OurReader { Char getNextChar(); void getLocationLineAndColumn(Location location, int& line, int& column) const; - std::string getLocationLineAndColumn(Location location) const; + JSONCPP_STRING getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); void skipCommentTokens(Token& token); typedef std::stack Nodes; Nodes nodes_; Errors errors_; - std::string document_; + JSONCPP_STRING document_; Location begin_; Location end_; Location current_; Location lastValueEnd_; Value* lastValue_; - std::string commentsBefore_; + JSONCPP_STRING commentsBefore_; int stackDepth_; OurFeatures const features_; @@ -1350,7 +1351,7 @@ bool OurReader::readComment() { void OurReader::addComment(Location begin, Location end, CommentPlacement placement) { assert(collectComments_); - const std::string& normalized = normalizeEOL(begin, end); + const JSONCPP_STRING& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { assert(lastValue_ != 0); lastValue_->setComment(normalized, placement); @@ -1437,7 +1438,7 @@ bool OurReader::readStringSingleQuote() { bool OurReader::readObject(Token& tokenStart) { Token tokenName; - std::string name; + JSONCPP_STRING name; Value init(objectValue); currentValue().swapPayload(init); currentValue().setOffsetStart(tokenStart.start_ - begin_); @@ -1469,7 +1470,7 @@ bool OurReader::readObject(Token& tokenStart) { } if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30"); if (features_.rejectDupKeys_ && currentValue().isMember(name)) { - std::string msg = "Duplicate key: '" + name + "'"; + JSONCPP_STRING msg = "Duplicate key: '" + name + "'"; return addErrorAndRecover( msg, tokenName, tokenObjectEnd); } @@ -1620,12 +1621,12 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) { buffer[length] = 0; count = sscanf(buffer, format, &value); } else { - std::string buffer(token.start_, token.end_); + JSONCPP_STRING buffer(token.start_, token.end_); count = sscanf(buffer.c_str(), format, &value); } if (count != 1) - return addError("'" + std::string(token.start_, token.end_) + + return addError("'" + JSONCPP_STRING(token.start_, token.end_) + "' is not a number.", token); decoded = value; @@ -1633,7 +1634,7 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) { } bool OurReader::decodeString(Token& token) { - std::string decoded_string; + JSONCPP_STRING decoded_string; if (!decodeString(token, decoded_string)) return false; Value decoded(decoded_string); @@ -1643,7 +1644,7 @@ bool OurReader::decodeString(Token& token) { return true; } -bool OurReader::decodeString(Token& token, std::string& decoded) { +bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) { decoded.reserve(static_cast(token.end_ - token.start_ - 2)); Location current = token.start_ + 1; // skip '"' Location end = token.end_ - 1; // do not include '"' @@ -1755,7 +1756,7 @@ bool OurReader::decodeUnicodeEscapeSequence(Token& token, } bool -OurReader::addError(const std::string& message, Token& token, Location extra) { +OurReader::addError(const JSONCPP_STRING& message, Token& token, Location extra) { ErrorInfo info; info.token_ = token; info.message_ = message; @@ -1777,7 +1778,7 @@ bool OurReader::recoverFromError(TokenType skipUntilToken) { return false; } -bool OurReader::addErrorAndRecover(const std::string& message, +bool OurReader::addErrorAndRecover(const JSONCPP_STRING& message, Token& token, TokenType skipUntilToken) { addError(message, token); @@ -1815,7 +1816,7 @@ void OurReader::getLocationLineAndColumn(Location location, ++line; } -std::string OurReader::getLocationLineAndColumn(Location location) const { +JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const { int line, column; getLocationLineAndColumn(location, line, column); char buffer[18 + 16 + 16 + 1]; @@ -1823,8 +1824,8 @@ std::string OurReader::getLocationLineAndColumn(Location location) const { return buffer; } -std::string OurReader::getFormattedErrorMessages() const { - std::string formattedMessage; +JSONCPP_STRING OurReader::getFormattedErrorMessages() const { + JSONCPP_STRING formattedMessage; for (Errors::const_iterator itError = errors_.begin(); itError != errors_.end(); ++itError) { @@ -1854,7 +1855,7 @@ std::vector OurReader::getStructuredErrors() const { return allErrors; } -bool OurReader::pushError(const Value& value, const std::string& message) { +bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) { ptrdiff_t length = end_ - begin_; if(value.getOffsetStart() > length || value.getOffsetLimit() > length) @@ -1871,7 +1872,7 @@ bool OurReader::pushError(const Value& value, const std::string& message) { return true; } -bool OurReader::pushError(const Value& value, const std::string& message, const Value& extra) { +bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) { ptrdiff_t length = end_ - begin_; if(value.getOffsetStart() > length || value.getOffsetLimit() > length @@ -1906,7 +1907,7 @@ class OurCharReader : public CharReader { {} bool parse( char const* beginDoc, char const* endDoc, - Value* root, std::string* errs) override { + Value* root, JSONCPP_STRING* errs) override { bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); if (errs) { *errs = reader_.getFormattedErrorMessages(); @@ -1936,7 +1937,7 @@ CharReader* CharReaderBuilder::newCharReader() const features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool(); return new OurCharReader(collectComments, features); } -static void getValidReaderKeys(std::set* valid_keys) +static void getValidReaderKeys(std::set* valid_keys) { valid_keys->clear(); valid_keys->insert("collectComments"); @@ -1955,19 +1956,19 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const Json::Value my_invalid; if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL Json::Value& inv = *invalid; - std::set valid_keys; + std::set valid_keys; getValidReaderKeys(&valid_keys); Value::Members keys = settings_.getMemberNames(); size_t n = keys.size(); for (size_t i = 0; i < n; ++i) { - std::string const& key = keys[i]; + JSONCPP_STRING const& key = keys[i]; if (valid_keys.find(key) == valid_keys.end()) { inv[key] = settings_[key]; } } return 0u == inv.size(); } -Value& CharReaderBuilder::operator[](std::string key) +Value& CharReaderBuilder::operator[](JSONCPP_STRING key) { return settings_[key]; } @@ -2008,11 +2009,11 @@ void CharReaderBuilder::setDefaults(Json::Value* settings) bool parseFromStream( CharReader::Factory const& fact, JSONCPP_ISTREAM& sin, - Value* root, std::string* errs) + Value* root, JSONCPP_STRING* errs) { JSONCPP_OSTRINGSTREAM ssin; ssin << sin.rdbuf(); - std::string doc = ssin.str(); + JSONCPP_STRING doc = ssin.str(); char const* begin = doc.data(); char const* end = begin + doc.size(); // Note that we do not actually need a null-terminator. @@ -2022,7 +2023,7 @@ bool parseFromStream( JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) { CharReaderBuilder b; - std::string errs; + JSONCPP_STRING errs; bool ok = parseFromStream(b, sin, &root, &errs); if (!ok) { fprintf(stderr, diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index e65e51b41..ec2b1f27f 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -15,8 +15,8 @@ namespace Json { /// Converts a unicode code-point to UTF-8. -static inline std::string codePointToUTF8(unsigned int cp) { - std::string result; +static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) { + JSONCPP_STRING result; // based on description from http://en.wikipedia.org/wiki/UTF-8 diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index e6eb3457e..3f91e5243 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -83,7 +83,8 @@ static inline bool InRange(double d, T min, U max) { * @return Pointer on the duplicate instance of string. */ static inline char* duplicateStringValue(const char* value, - size_t length) { + size_t length) +{ // Avoid an integer overflow in the call to malloc below by limiting length // to a sane value. if (length >= static_cast(Value::maxInt)) @@ -137,7 +138,25 @@ inline static void decodePrefixedString( } /** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue(). */ -static inline void releaseStringValue(char* value) { free(value); } +static inline void releasePrefixedStringValue(char* value) { +#if JSON_USE_SECURE_MEMORY + unsigned length = 0; + const char* valueDecoded; + decodePrefixedString(true, value, &length, &valueDecoded); + length += sizeof(unsigned) + 1; + memset(value, 0, length); +#endif + free(value); +} + +static inline void releaseStringValue(char* value, unsigned length) { +#if JSON_USE_SECURE_MEMORY + if (length == 0) + length = static_cast(strlen(value)); //As we allocated the strings memory + memset(value, 0, length); +#endif + free(value); +} } // namespace Json @@ -187,16 +206,17 @@ void throwLogicError(JSONCPP_STRING const& msg) // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -Value::CommentInfo::CommentInfo() : comment_(0) {} +Value::CommentInfo::CommentInfo() : comment_(0) +{} Value::CommentInfo::~CommentInfo() { if (comment_) - releaseStringValue(comment_); + releaseStringValue(comment_, 0u); } void Value::CommentInfo::setComment(const char* text, size_t len) { if (comment_) { - releaseStringValue(comment_); + releaseStringValue(comment_, 0u); comment_ = 0; } JSON_ASSERT(text != 0); @@ -227,10 +247,10 @@ Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy a storage_.length_ = ulength & 0x3FFFFFFF; } -Value::CZString::CZString(const CZString& other) - : cstr_(other.storage_.policy_ != noDuplication && other.cstr_ != 0 - ? duplicateStringValue(other.cstr_, other.storage_.length_) - : other.cstr_) { +Value::CZString::CZString(const CZString& other) { + cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0 + ? duplicateStringValue(other.cstr_, other.storage_.length_) + : other.cstr_); storage_.policy_ = static_cast(other.cstr_ ? (static_cast(other.storage_.policy_) == noDuplication ? noDuplication : duplicate) @@ -246,8 +266,14 @@ Value::CZString::CZString(CZString&& other) #endif Value::CZString::~CZString() { - if (cstr_ && storage_.policy_ == duplicate) - releaseStringValue(const_cast(cstr_)); + if (cstr_ && storage_.policy_ == duplicate) { +#if JSON_USE_SECURE_MEMORY + releaseStringValue(const_cast(cstr_), storage_.length_ + 1u); //+1 for null terminating character for sake of completeness but not actually necessary +#else + releaseStringValue(const_cast(cstr_), storage_.length_ + 1u); +#endif + + } } void Value::CZString::swap(CZString& other) { @@ -453,7 +479,7 @@ Value::~Value() { break; case stringValue: if (allocated_) - releaseStringValue(value_.string_); + releasePrefixedStringValue(value_.string_); break; case arrayValue: case objectValue: @@ -465,6 +491,8 @@ Value::~Value() { if (comments_) delete[] comments_; + + value_.uint_ = 0; } Value& Value::operator=(Value other) { @@ -609,6 +637,18 @@ const char* Value::asCString() const { return this_str; } +#if JSON_USE_SECURE_MEMORY +unsigned Value::getCStringLength() const { + JSON_ASSERT_MESSAGE(type_ == stringValue, + "in Json::Value::asCString(): requires stringValue"); + if (value_.string_ == 0) return 0; + unsigned this_len; + char const* this_str; + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); + return this_len; +} +#endif + bool Value::getString(char const** str, char const** cend) const { if (type_ != stringValue) return false; if (value_.string_ == 0) return false; diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 1ed67b16a..72954e792 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -99,7 +99,7 @@ static bool containsControlCharacter0(const char* str, unsigned len) { return false; } -std::string valueToString(LargestInt value) { +JSONCPP_STRING valueToString(LargestInt value) { UIntToStringBuffer buffer; char* current = buffer + sizeof(buffer); if (value == Value::minLargestInt) { @@ -115,7 +115,7 @@ std::string valueToString(LargestInt value) { return current; } -std::string valueToString(LargestUInt value) { +JSONCPP_STRING valueToString(LargestUInt value) { UIntToStringBuffer buffer; char* current = buffer + sizeof(buffer); uintToString(value, current); @@ -125,17 +125,17 @@ std::string valueToString(LargestUInt value) { #if defined(JSON_HAS_INT64) -std::string valueToString(Int value) { +JSONCPP_STRING valueToString(Int value) { return valueToString(LargestInt(value)); } -std::string valueToString(UInt value) { +JSONCPP_STRING valueToString(UInt value) { return valueToString(LargestUInt(value)); } #endif // # if defined(JSON_HAS_INT64) -std::string valueToString(double value, bool useSpecialFloats, unsigned int precision) { +JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision) { // Allocate a buffer that is more than large enough to store the 16 digits of // precision requested below. char buffer[32]; @@ -165,23 +165,23 @@ std::string valueToString(double value, bool useSpecialFloats, unsigned int prec return buffer; } -std::string valueToString(double value) { return valueToString(value, false, 17); } +JSONCPP_STRING valueToString(double value) { return valueToString(value, false, 17); } -std::string valueToString(bool value) { return value ? "true" : "false"; } +JSONCPP_STRING valueToString(bool value) { return value ? "true" : "false"; } -std::string valueToQuotedString(const char* value) { +JSONCPP_STRING valueToQuotedString(const char* value) { if (value == NULL) return ""; // Not sure how to handle unicode... if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && !containsControlCharacter(value)) - return std::string("\"") + value + "\""; + return JSONCPP_STRING("\"") + value + "\""; // We have to walk value and escape any special characters. - // Appending to std::string is not efficient, but this should be rare. + // Appending to JSONCPP_STRING is not efficient, but this should be rare. // (Note: forward slashes are *not* rare, but I am not escaping them.) - std::string::size_type maxsize = + JSONCPP_STRING::size_type maxsize = strlen(value) * 2 + 3; // allescaped+quotes+NULL - std::string result; + JSONCPP_STRING result; result.reserve(maxsize); // to avoid lots of mallocs result += "\""; for (const char* c = value; *c != 0; ++c) { @@ -246,19 +246,19 @@ static char const* strnpbrk(char const* s, char const* accept, size_t n) { } return NULL; } -static std::string valueToQuotedStringN(const char* value, unsigned length) { +static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) { if (value == NULL) return ""; // Not sure how to handle unicode... if (strnpbrk(value, "\"\\\b\f\n\r\t", length) == NULL && !containsControlCharacter0(value, length)) - return std::string("\"") + value + "\""; + return JSONCPP_STRING("\"") + value + "\""; // We have to walk value and escape any special characters. - // Appending to std::string is not efficient, but this should be rare. + // Appending to JSONCPP_STRING is not efficient, but this should be rare. // (Note: forward slashes are *not* rare, but I am not escaping them.) - std::string::size_type maxsize = + JSONCPP_STRING::size_type maxsize = length * 2 + 3; // allescaped+quotes+NULL - std::string result; + JSONCPP_STRING result; result.reserve(maxsize); // to avoid lots of mallocs result += "\""; char const* end = value + length; @@ -326,7 +326,7 @@ void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; } void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; } -std::string FastWriter::write(const Value& root) { +JSONCPP_STRING FastWriter::write(const Value& root) { document_ = ""; writeValue(root); if (!omitEndingLineFeed_) @@ -376,7 +376,7 @@ void FastWriter::writeValue(const Value& value) { document_ += '{'; for (Value::Members::iterator it = members.begin(); it != members.end(); ++it) { - const std::string& name = *it; + const JSONCPP_STRING& name = *it; if (it != members.begin()) document_ += ','; document_ += valueToQuotedStringN(name.data(), static_cast(name.length())); @@ -394,7 +394,7 @@ void FastWriter::writeValue(const Value& value) { StyledWriter::StyledWriter() : rightMargin_(74), indentSize_(3), addChildValues_() {} -std::string StyledWriter::write(const Value& root) { +JSONCPP_STRING StyledWriter::write(const Value& root) { document_ = ""; addChildValues_ = false; indentString_ = ""; @@ -444,7 +444,7 @@ void StyledWriter::writeValue(const Value& value) { indent(); Value::Members::iterator it = members.begin(); for (;;) { - const std::string& name = *it; + const JSONCPP_STRING& name = *it; const Value& childValue = value[name]; writeCommentBeforeValue(childValue); writeWithIndent(valueToQuotedString(name.c_str())); @@ -534,7 +534,7 @@ bool StyledWriter::isMultineArray(const Value& value) { return isMultiLine; } -void StyledWriter::pushValue(const std::string& value) { +void StyledWriter::pushValue(const JSONCPP_STRING& value) { if (addChildValues_) childValues_.push_back(value); else @@ -552,12 +552,12 @@ void StyledWriter::writeIndent() { document_ += indentString_; } -void StyledWriter::writeWithIndent(const std::string& value) { +void StyledWriter::writeWithIndent(const JSONCPP_STRING& value) { writeIndent(); document_ += value; } -void StyledWriter::indent() { indentString_ += std::string(indentSize_, ' '); } +void StyledWriter::indent() { indentString_ += JSONCPP_STRING(indentSize_, ' '); } void StyledWriter::unindent() { assert(indentString_.size() >= indentSize_); @@ -570,8 +570,8 @@ void StyledWriter::writeCommentBeforeValue(const Value& root) { document_ += "\n"; writeIndent(); - const std::string& comment = root.getComment(commentBefore); - std::string::const_iterator iter = comment.begin(); + const JSONCPP_STRING& comment = root.getComment(commentBefore); + JSONCPP_STRING::const_iterator iter = comment.begin(); while (iter != comment.end()) { document_ += *iter; if (*iter == '\n' && @@ -604,7 +604,7 @@ bool StyledWriter::hasCommentForValue(const Value& value) { // Class StyledStreamWriter // ////////////////////////////////////////////////////////////////// -StyledStreamWriter::StyledStreamWriter(std::string indentation) +StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation) : document_(NULL), rightMargin_(74), indentation_(indentation), addChildValues_() {} @@ -661,7 +661,7 @@ void StyledStreamWriter::writeValue(const Value& value) { indent(); Value::Members::iterator it = members.begin(); for (;;) { - const std::string& name = *it; + const JSONCPP_STRING& name = *it; const Value& childValue = value[name]; writeCommentBeforeValue(childValue); writeWithIndent(valueToQuotedString(name.c_str())); @@ -753,7 +753,7 @@ bool StyledStreamWriter::isMultineArray(const Value& value) { return isMultiLine; } -void StyledStreamWriter::pushValue(const std::string& value) { +void StyledStreamWriter::pushValue(const JSONCPP_STRING& value) { if (addChildValues_) childValues_.push_back(value); else @@ -768,7 +768,7 @@ void StyledStreamWriter::writeIndent() { *document_ << '\n' << indentString_; } -void StyledStreamWriter::writeWithIndent(const std::string& value) { +void StyledStreamWriter::writeWithIndent(const JSONCPP_STRING& value) { if (!indented_) writeIndent(); *document_ << value; indented_ = false; @@ -786,8 +786,8 @@ void StyledStreamWriter::writeCommentBeforeValue(const Value& root) { return; if (!indented_) writeIndent(); - const std::string& comment = root.getComment(commentBefore); - std::string::const_iterator iter = comment.begin(); + const JSONCPP_STRING& comment = root.getComment(commentBefore); + JSONCPP_STRING::const_iterator iter = comment.begin(); while (iter != comment.end()) { *document_ << *iter; if (*iter == '\n' && @@ -832,11 +832,11 @@ struct CommentStyle { struct BuiltStyledStreamWriter : public StreamWriter { BuiltStyledStreamWriter( - std::string const& indentation, + JSONCPP_STRING const& indentation, CommentStyle::Enum cs, - std::string const& colonSymbol, - std::string const& nullSymbol, - std::string const& endingLineFeedSymbol, + JSONCPP_STRING const& colonSymbol, + JSONCPP_STRING const& nullSymbol, + JSONCPP_STRING const& endingLineFeedSymbol, bool useSpecialFloats, unsigned int precision); int write(Value const& root, JSONCPP_OSTREAM* sout) override; @@ -844,36 +844,36 @@ struct BuiltStyledStreamWriter : public StreamWriter void writeValue(Value const& value); void writeArrayValue(Value const& value); bool isMultineArray(Value const& value); - void pushValue(std::string const& value); + void pushValue(JSONCPP_STRING const& value); void writeIndent(); - void writeWithIndent(std::string const& value); + void writeWithIndent(JSONCPP_STRING const& value); void indent(); void unindent(); void writeCommentBeforeValue(Value const& root); void writeCommentAfterValueOnSameLine(Value const& root); static bool hasCommentForValue(const Value& value); - typedef std::vector ChildValues; + typedef std::vector ChildValues; ChildValues childValues_; - std::string indentString_; + JSONCPP_STRING indentString_; unsigned int rightMargin_; - std::string indentation_; + JSONCPP_STRING indentation_; CommentStyle::Enum cs_; - std::string colonSymbol_; - std::string nullSymbol_; - std::string endingLineFeedSymbol_; + JSONCPP_STRING colonSymbol_; + JSONCPP_STRING nullSymbol_; + JSONCPP_STRING endingLineFeedSymbol_; bool addChildValues_ : 1; bool indented_ : 1; bool useSpecialFloats_ : 1; unsigned int precision_; }; BuiltStyledStreamWriter::BuiltStyledStreamWriter( - std::string const& indentation, + JSONCPP_STRING const& indentation, CommentStyle::Enum cs, - std::string const& colonSymbol, - std::string const& nullSymbol, - std::string const& endingLineFeedSymbol, + JSONCPP_STRING const& colonSymbol, + JSONCPP_STRING const& nullSymbol, + JSONCPP_STRING const& endingLineFeedSymbol, bool useSpecialFloats, unsigned int precision) : rightMargin_(74) @@ -942,7 +942,7 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { indent(); Value::Members::iterator it = members.begin(); for (;;) { - std::string const& name = *it; + JSONCPP_STRING const& name = *it; Value const& childValue = value[name]; writeCommentBeforeValue(childValue); writeWithIndent(valueToQuotedStringN(name.data(), static_cast(name.length()))); @@ -1036,7 +1036,7 @@ bool BuiltStyledStreamWriter::isMultineArray(Value const& value) { return isMultiLine; } -void BuiltStyledStreamWriter::pushValue(std::string const& value) { +void BuiltStyledStreamWriter::pushValue(JSONCPP_STRING const& value) { if (addChildValues_) childValues_.push_back(value); else @@ -1055,7 +1055,7 @@ void BuiltStyledStreamWriter::writeIndent() { } } -void BuiltStyledStreamWriter::writeWithIndent(std::string const& value) { +void BuiltStyledStreamWriter::writeWithIndent(JSONCPP_STRING const& value) { if (!indented_) writeIndent(); *sout_ << value; indented_ = false; @@ -1074,8 +1074,8 @@ void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) { return; if (!indented_) writeIndent(); - const std::string& comment = root.getComment(commentBefore); - std::string::const_iterator iter = comment.begin(); + const JSONCPP_STRING& comment = root.getComment(commentBefore); + JSONCPP_STRING::const_iterator iter = comment.begin(); while (iter != comment.end()) { *sout_ << *iter; if (*iter == '\n' && @@ -1125,8 +1125,8 @@ StreamWriterBuilder::~StreamWriterBuilder() {} StreamWriter* StreamWriterBuilder::newStreamWriter() const { - std::string indentation = settings_["indentation"].asString(); - std::string cs_str = settings_["commentStyle"].asString(); + JSONCPP_STRING indentation = settings_["indentation"].asString(); + JSONCPP_STRING cs_str = settings_["commentStyle"].asString(); bool eyc = settings_["enableYAMLCompatibility"].asBool(); bool dnp = settings_["dropNullPlaceholders"].asBool(); bool usf = settings_["useSpecialFloats"].asBool(); @@ -1139,23 +1139,23 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const } else { throwRuntimeError("commentStyle must be 'All' or 'None'"); } - std::string colonSymbol = " : "; + JSONCPP_STRING colonSymbol = " : "; if (eyc) { colonSymbol = ": "; } else if (indentation.empty()) { colonSymbol = ":"; } - std::string nullSymbol = "null"; + JSONCPP_STRING nullSymbol = "null"; if (dnp) { nullSymbol = ""; } if (pre > 17) pre = 17; - std::string endingLineFeedSymbol = ""; + JSONCPP_STRING endingLineFeedSymbol = ""; return new BuiltStyledStreamWriter( indentation, cs, colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre); } -static void getValidWriterKeys(std::set* valid_keys) +static void getValidWriterKeys(std::set* valid_keys) { valid_keys->clear(); valid_keys->insert("indentation"); @@ -1170,19 +1170,19 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const Json::Value my_invalid; if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL Json::Value& inv = *invalid; - std::set valid_keys; + std::set valid_keys; getValidWriterKeys(&valid_keys); Value::Members keys = settings_.getMemberNames(); size_t n = keys.size(); for (size_t i = 0; i < n; ++i) { - std::string const& key = keys[i]; + JSONCPP_STRING const& key = keys[i]; if (valid_keys.find(key) == valid_keys.end()) { inv[key] = settings_[key]; } } return 0u == inv.size(); } -Value& StreamWriterBuilder::operator[](std::string key) +Value& StreamWriterBuilder::operator[](JSONCPP_STRING key) { return settings_[key]; } @@ -1199,7 +1199,7 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings) //! [StreamWriterBuilderDefaults] } -std::string writeString(StreamWriter::Factory const& builder, Value const& root) { +JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value const& root) { JSONCPP_OSTRINGSTREAM sout; StreamWriterPtr const writer(builder.newStreamWriter()); writer->write(root, &sout); diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index bd9463fa5..6ac5cebe4 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -81,7 +81,7 @@ TestResult::TestResult() predicateStackTail_ = &rootPredicateNode_; } -void TestResult::setTestName(const std::string& name) { name_ = name; } +void TestResult::setTestName(const JSONCPP_STRING& name) { name_ = name; } TestResult& TestResult::addFailure(const char* file, unsigned int line, const char* expr) { @@ -163,7 +163,7 @@ void TestResult::printFailure(bool printTestName) const { Failures::const_iterator itEnd = failures_.end(); for (Failures::const_iterator it = failures_.begin(); it != itEnd; ++it) { const Failure& failure = *it; - std::string indent(failure.nestingLevel_ * 2, ' '); + JSONCPP_STRING indent(failure.nestingLevel_ * 2, ' '); if (failure.file_) { printf("%s%s(%d): ", indent.c_str(), failure.file_, failure.line_); } @@ -173,19 +173,19 @@ void TestResult::printFailure(bool printTestName) const { printf("\n"); } if (!failure.message_.empty()) { - std::string reindented = indentText(failure.message_, indent + " "); + JSONCPP_STRING reindented = indentText(failure.message_, indent + " "); printf("%s\n", reindented.c_str()); } } } -std::string TestResult::indentText(const std::string& text, - const std::string& indent) { - std::string reindented; - std::string::size_type lastIndex = 0; +JSONCPP_STRING TestResult::indentText(const JSONCPP_STRING& text, + const JSONCPP_STRING& indent) { + JSONCPP_STRING reindented; + JSONCPP_STRING::size_type lastIndex = 0; while (lastIndex < text.size()) { - std::string::size_type nextIndex = text.find('\n', lastIndex); - if (nextIndex == std::string::npos) { + JSONCPP_STRING::size_type nextIndex = text.find('\n', lastIndex); + if (nextIndex == JSONCPP_STRING::npos) { nextIndex = text.size() - 1; } reindented += indent; @@ -195,7 +195,7 @@ std::string TestResult::indentText(const std::string& text, return reindented; } -TestResult& TestResult::addToLastFailure(const std::string& message) { +TestResult& TestResult::addToLastFailure(const JSONCPP_STRING& message) { if (messageTarget_ != 0) { messageTarget_->message_ += message; } @@ -240,9 +240,9 @@ unsigned int Runner::testCount() const { return static_cast(tests_.size()); } -std::string Runner::testNameAt(unsigned int index) const { +JSONCPP_STRING Runner::testNameAt(unsigned int index) const { TestCase* test = tests_[index](); - std::string name = test->testName(); + JSONCPP_STRING name = test->testName(); delete test; return name; } @@ -303,7 +303,7 @@ bool Runner::runAllTest(bool printSummary) const { } } -bool Runner::testIndex(const std::string& testName, +bool Runner::testIndex(const JSONCPP_STRING& testName, unsigned int& indexOut) const { unsigned int count = testCount(); for (unsigned int index = 0; index < count; ++index) { @@ -323,10 +323,10 @@ void Runner::listTests() const { } int Runner::runCommandLine(int argc, const char* argv[]) const { - // typedef std::deque TestNames; + // typedef std::deque TestNames; Runner subrunner; for (int index = 1; index < argc; ++index) { - std::string opt = argv[index]; + JSONCPP_STRING opt = argv[index]; if (opt == "--list-tests") { listTests(); return 0; @@ -426,9 +426,23 @@ void Runner::printUsage(const char* appName) { // Assertion functions // ////////////////////////////////////////////////////////////////// +JSONCPP_STRING ToJsonString(const char* toConvert) { + return JSONCPP_STRING(toConvert); +} + +JSONCPP_STRING ToJsonString(JSONCPP_STRING in) { + return in; +} + +#if JSON_USE_SECURE_MEMORY +JSONCPP_STRING ToJsonString(std::string in) { + return JSONCPP_STRING(in.data(), in.data() + in.length()); +} +#endif + TestResult& checkStringEqual(TestResult& result, - const std::string& expected, - const std::string& actual, + const JSONCPP_STRING& expected, + const JSONCPP_STRING& actual, const char* file, unsigned int line, const char* expr) { diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 4bce85fba..f9f6c0c2d 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -32,8 +32,8 @@ class Failure { public: const char* file_; unsigned int line_; - std::string expr_; - std::string message_; + JSONCPP_STRING expr_; + JSONCPP_STRING message_; unsigned int nestingLevel_; }; @@ -65,7 +65,7 @@ class TestResult { /// \internal Implementation detail for predicate macros PredicateContext* predicateStackTail_; - void setTestName(const std::string& name); + void setTestName(const JSONCPP_STRING& name); /// Adds an assertion failure. TestResult& @@ -96,19 +96,19 @@ class TestResult { TestResult& operator<<(Json::UInt64 value); private: - TestResult& addToLastFailure(const std::string& message); + TestResult& addToLastFailure(const JSONCPP_STRING& message); unsigned int getAssertionNestingLevel() const; /// Adds a failure or a predicate context void addFailureInfo(const char* file, unsigned int line, const char* expr, unsigned int nestingLevel); - static std::string indentText(const std::string& text, - const std::string& indent); + static JSONCPP_STRING indentText(const JSONCPP_STRING& text, + const JSONCPP_STRING& indent); typedef std::deque Failures; Failures failures_; - std::string name_; + JSONCPP_STRING name_; PredicateContext rootPredicateNode_; PredicateContext::Id lastUsedPredicateId_; /// Failure which is the target of the messages added using operator << @@ -155,7 +155,7 @@ class Runner { unsigned int testCount() const; /// Returns the name of the test case at the specified index - std::string testNameAt(unsigned int index) const; + JSONCPP_STRING testNameAt(unsigned int index) const; /// Runs the test case at the specified index using the specified TestResult void runTestAt(unsigned int index, TestResult& result) const; @@ -168,7 +168,7 @@ class Runner { private: void listTests() const; - bool testIndex(const std::string& testName, unsigned int& index) const; + bool testIndex(const JSONCPP_STRING& testName, unsigned int& index) const; static void preventDialogOnCrash(); private: @@ -191,9 +191,15 @@ TestResult& checkEqual(TestResult& result, return result; } +JSONCPP_STRING ToJsonString(const char* toConvert); +JSONCPP_STRING ToJsonString(JSONCPP_STRING in); +#if JSON_USE_SECURE_MEMORY +JSONCPP_STRING ToJsonString(std::string in); +#endif + TestResult& checkStringEqual(TestResult& result, - const std::string& expected, - const std::string& actual, + const JSONCPP_STRING& expected, + const JSONCPP_STRING& actual, const char* file, unsigned int line, const char* expr); @@ -235,8 +241,8 @@ TestResult& checkStringEqual(TestResult& result, /// \brief Asserts that two values are equals. #define JSONTEST_ASSERT_STRING_EQUAL(expected, actual) \ JsonTest::checkStringEqual(*result_, \ - std::string(expected), \ - std::string(actual), \ + JsonTest::ToJsonString(expected), \ + JsonTest::ToJsonString(actual), \ __FILE__, \ __LINE__, \ #expected " == " #actual) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 92ad68ea3..fbe771a92 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -102,21 +102,21 @@ struct ValueTest : JsonTest::TestCase { /// Normalize the representation of floating-point number by stripped leading /// 0 in exponent. - static std::string normalizeFloatingPointStr(const std::string& s); + static JSONCPP_STRING normalizeFloatingPointStr(const JSONCPP_STRING& s); }; -std::string ValueTest::normalizeFloatingPointStr(const std::string& s) { - std::string::size_type index = s.find_last_of("eE"); - if (index != std::string::npos) { - std::string::size_type hasSign = +JSONCPP_STRING ValueTest::normalizeFloatingPointStr(const JSONCPP_STRING& s) { + JSONCPP_STRING::size_type index = s.find_last_of("eE"); + if (index != JSONCPP_STRING::npos) { + JSONCPP_STRING::size_type hasSign = (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; - std::string::size_type exponentStartIndex = index + 1 + hasSign; - std::string normalized = s.substr(0, exponentStartIndex); - std::string::size_type indexDigit = + JSONCPP_STRING::size_type exponentStartIndex = index + 1 + hasSign; + JSONCPP_STRING normalized = s.substr(0, exponentStartIndex); + JSONCPP_STRING::size_type indexDigit = s.find_first_not_of('0', exponentStartIndex); - std::string exponent = "0"; + JSONCPP_STRING exponent = "0"; if (indexDigit != - std::string::npos) // There is an exponent different from 0 + JSONCPP_STRING::npos) // There is an exponent different from 0 { exponent = s.substr(indexDigit); } @@ -647,7 +647,7 @@ JSONTEST_FIXTURE(ValueTest, integers) { JSONTEST_ASSERT_EQUAL((1 << 20), val.asFloat()); JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_STRING_EQUAL("1048576", - normalizeFloatingPointStr(val.asString())); + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // -2^20 val = Json::Value(-(1 << 20)); @@ -888,7 +888,7 @@ JSONTEST_FIXTURE(ValueTest, integers) { JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asFloat()); JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_STRING_EQUAL("1099511627776", - normalizeFloatingPointStr(val.asString())); + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // -2^40 val = Json::Value(-(Json::Int64(1) << 40)); @@ -963,7 +963,7 @@ JSONTEST_FIXTURE(ValueTest, integers) { val.asFloat()); JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_STRING_EQUAL("9.2233720368547758e+18", - normalizeFloatingPointStr(val.asString())); + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // int64 min val = Json::Value(Json::Int64(kint64min)); @@ -1011,7 +1011,7 @@ JSONTEST_FIXTURE(ValueTest, integers) { JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asFloat()); JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_STRING_EQUAL("-9.2233720368547758e+18", - normalizeFloatingPointStr(val.asString())); + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // 10^19 const Json::UInt64 ten_to_19 = static_cast(1e19); @@ -1058,7 +1058,7 @@ JSONTEST_FIXTURE(ValueTest, integers) { JSONTEST_ASSERT_EQUAL(1e19, val.asFloat()); JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_STRING_EQUAL("1e+19", - normalizeFloatingPointStr(val.asString())); + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // uint64 max val = Json::Value(Json::UInt64(kuint64max)); @@ -1102,7 +1102,7 @@ JSONTEST_FIXTURE(ValueTest, integers) { JSONTEST_ASSERT_EQUAL(18446744073709551616.0, val.asFloat()); JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_STRING_EQUAL("1.8446744073709552e+19", - normalizeFloatingPointStr(val.asString())); + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); #endif } @@ -1192,7 +1192,7 @@ JSONTEST_FIXTURE(ValueTest, nonIntegers) { #endif JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_EQUAL("2147483647.5", - normalizeFloatingPointStr(val.asString())); + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // A bit under int32 min val = Json::Value(kint32min - 0.5); @@ -1220,7 +1220,7 @@ JSONTEST_FIXTURE(ValueTest, nonIntegers) { #endif JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_EQUAL("-2147483648.5", - normalizeFloatingPointStr(val.asString())); + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // A bit over uint32 max val = Json::Value(kuint32max + 0.5); @@ -1250,29 +1250,29 @@ JSONTEST_FIXTURE(ValueTest, nonIntegers) { #endif JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_EQUAL("4294967295.5", - normalizeFloatingPointStr(val.asString())); + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); val = Json::Value(1.2345678901234); JSONTEST_ASSERT_STRING_EQUAL("1.2345678901234001", - normalizeFloatingPointStr(val.asString())); + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // A 16-digit floating point number. val = Json::Value(2199023255552000.0f); JSONTEST_ASSERT_EQUAL(float(2199023255552000.0f), val.asFloat()); JSONTEST_ASSERT_STRING_EQUAL("2199023255552000", - normalizeFloatingPointStr(val.asString())); + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // A very large floating point number. val = Json::Value(3.402823466385289e38); JSONTEST_ASSERT_EQUAL(float(3.402823466385289e38), val.asFloat()); JSONTEST_ASSERT_STRING_EQUAL("3.402823466385289e+38", - normalizeFloatingPointStr(val.asString())); + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // An even larger floating point number. val = Json::Value(1.2345678e300); JSONTEST_ASSERT_EQUAL(double(1.2345678e300), val.asDouble()); JSONTEST_ASSERT_STRING_EQUAL("1.2345678e+300", - normalizeFloatingPointStr(val.asString())); + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); } void ValueTest::checkConstMemberCount(const Json::Value& value, @@ -1538,7 +1538,7 @@ JSONTEST_FIXTURE(ValueTest, offsetAccessors) { JSONTEST_FIXTURE(ValueTest, StaticString) { char mutant[] = "hello"; Json::StaticString ss(mutant); - std::string regular(mutant); + JSONCPP_STRING regular(mutant); mutant[1] = 'a'; JSONTEST_ASSERT_STRING_EQUAL("hallo", ss.c_str()); JSONTEST_ASSERT_STRING_EQUAL("hello", regular.c_str()); @@ -1560,15 +1560,15 @@ JSONTEST_FIXTURE(ValueTest, StaticString) { JSONTEST_FIXTURE(ValueTest, CommentBefore) { Json::Value val; // fill val - val.setComment(std::string("// this comment should appear before"), Json::commentBefore); + val.setComment(JSONCPP_STRING("// this comment should appear before"), Json::commentBefore); Json::StreamWriterBuilder wbuilder; wbuilder.settings_["commentStyle"] = "All"; { char const expected[] = "// this comment should appear before\nnull"; - std::string result = Json::writeString(wbuilder, val); + JSONCPP_STRING result = Json::writeString(wbuilder, val); JSONTEST_ASSERT_STRING_EQUAL(expected, result); - std::string res2 = val.toStyledString(); - std::string exp2 = "\n"; + JSONCPP_STRING res2 = val.toStyledString(); + JSONCPP_STRING exp2 = "\n"; exp2 += expected; exp2 += "\n"; JSONTEST_ASSERT_STRING_EQUAL(exp2, res2); @@ -1577,10 +1577,10 @@ JSONTEST_FIXTURE(ValueTest, CommentBefore) { val.swapPayload(other); { char const expected[] = "// this comment should appear before\n\"hello\""; - std::string result = Json::writeString(wbuilder, val); + JSONCPP_STRING result = Json::writeString(wbuilder, val); JSONTEST_ASSERT_STRING_EQUAL(expected, result); - std::string res2 = val.toStyledString(); - std::string exp2 = "\n"; + JSONCPP_STRING res2 = val.toStyledString(); + JSONCPP_STRING exp2 = "\n"; exp2 += expected; exp2 += "\n"; JSONTEST_ASSERT_STRING_EQUAL(exp2, res2); @@ -1591,10 +1591,10 @@ JSONTEST_FIXTURE(ValueTest, CommentBefore) { // Assignment over-writes comments. { char const expected[] = "\"hello\""; - std::string result = Json::writeString(wbuilder, val); + JSONCPP_STRING result = Json::writeString(wbuilder, val); JSONTEST_ASSERT_STRING_EQUAL(expected, result); - std::string res2 = val.toStyledString(); - std::string exp2 = ""; + JSONCPP_STRING res2 = val.toStyledString(); + JSONCPP_STRING exp2 = ""; exp2 += expected; exp2 += "\n"; JSONTEST_ASSERT_STRING_EQUAL(exp2, res2); @@ -1603,7 +1603,7 @@ JSONTEST_FIXTURE(ValueTest, CommentBefore) { JSONTEST_FIXTURE(ValueTest, zeroes) { char const cstr[] = "h\0i"; - std::string binary(cstr, sizeof(cstr)); // include trailing 0 + JSONCPP_STRING binary(cstr, sizeof(cstr)); // include trailing 0 JSONTEST_ASSERT_EQUAL(4U, binary.length()); Json::StreamWriterBuilder b; { @@ -1631,7 +1631,7 @@ JSONTEST_FIXTURE(ValueTest, zeroes) { JSONTEST_FIXTURE(ValueTest, zeroesInKeys) { char const cstr[] = "h\0i"; - std::string binary(cstr, sizeof(cstr)); // include trailing 0 + JSONCPP_STRING binary(cstr, sizeof(cstr)); // include trailing 0 JSONTEST_ASSERT_EQUAL(4U, binary.length()); { Json::Value root; @@ -1660,8 +1660,8 @@ JSONTEST_FIXTURE(ValueTest, specialFloats) { b.settings_["useSpecialFloats"] = true; Json::Value v = std::numeric_limits::quiet_NaN(); - std::string expected = "NaN"; - std::string result = Json::writeString(b, v); + JSONCPP_STRING expected = "NaN"; + JSONCPP_STRING result = Json::writeString(b, v); JSONTEST_ASSERT_STRING_EQUAL(expected, result); v = std::numeric_limits::infinity(); @@ -1680,8 +1680,8 @@ JSONTEST_FIXTURE(ValueTest, precision) { b.settings_["precision"] = 5; Json::Value v = 100.0/3; - std::string expected = "33.333"; - std::string result = Json::writeString(b, v); + JSONCPP_STRING expected = "33.333"; + JSONCPP_STRING result = Json::writeString(b, v); JSONTEST_ASSERT_STRING_EQUAL(expected, result); v = 0.25000000; @@ -1735,15 +1735,15 @@ JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) { } JSONTEST_FIXTURE(StreamWriterTest, writeZeroes) { - std::string binary("hi", 3); // include trailing 0 + JSONCPP_STRING binary("hi", 3); // include trailing 0 JSONTEST_ASSERT_EQUAL(3, binary.length()); - std::string expected("\"hi\\u0000\""); // unicoded zero + JSONCPP_STRING expected("\"hi\\u0000\""); // unicoded zero Json::StreamWriterBuilder b; { Json::Value root; root = binary; JSONTEST_ASSERT_STRING_EQUAL(binary, root.asString()); - std::string out = Json::writeString(b, root); + JSONCPP_STRING out = Json::writeString(b, root); JSONTEST_ASSERT_EQUAL(expected.size(), out.size()); JSONTEST_ASSERT_STRING_EQUAL(expected, out); } @@ -1751,7 +1751,7 @@ JSONTEST_FIXTURE(StreamWriterTest, writeZeroes) { Json::Value root; root["top"] = binary; JSONTEST_ASSERT_STRING_EQUAL(binary, root["top"].asString()); - std::string out = Json::writeString(b, root["top"]); + JSONCPP_STRING out = Json::writeString(b, root["top"]); JSONTEST_ASSERT_STRING_EQUAL(expected, out); } } @@ -1852,7 +1852,7 @@ struct CharReaderTest : JsonTest::TestCase {}; JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrors) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; Json::Value root; char const doc[] = "{ \"property\" : \"value\" }"; bool ok = reader->parse( @@ -1866,7 +1866,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrors) { JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrorsTestingOffsets) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; Json::Value root; char const doc[] = "{ \"property\" : [\"value\", \"value2\"], \"obj\" : " @@ -1883,7 +1883,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrorsTestingOffsets) { JSONTEST_FIXTURE(CharReaderTest, parseWithOneError) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; Json::Value root; char const doc[] = "{ \"property\" :: \"value\" }"; @@ -1900,7 +1900,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithOneError) { JSONTEST_FIXTURE(CharReaderTest, parseChineseWithOneError) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; Json::Value root; char const doc[] = "{ \"pr佐藤erty\" :: \"value\" }"; @@ -1917,7 +1917,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseChineseWithOneError) { JSONTEST_FIXTURE(CharReaderTest, parseWithDetailError) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; Json::Value root; char const doc[] = "{ \"property\" : \"v\\alue\" }"; @@ -1939,7 +1939,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) { { b.settings_["stackLimit"] = 2; Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; bool ok = reader->parse( doc, doc + std::strlen(doc), &root, &errs); @@ -1951,7 +1951,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) { { b.settings_["stackLimit"] = 1; Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; JSONTEST_ASSERT_THROWS(reader->parse( doc, doc + std::strlen(doc), &root, &errs)); @@ -1969,7 +1969,7 @@ JSONTEST_FIXTURE(CharReaderStrictModeTest, dupKeys) { { b.strictMode(&b.settings_); Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; bool ok = reader->parse( doc, doc + std::strlen(doc), &root, &errs); @@ -1993,7 +1993,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { { b.settings_["failIfExtra"] = false; Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; bool ok = reader->parse( doc, doc + std::strlen(doc), &root, &errs); @@ -2005,7 +2005,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { { b.settings_["failIfExtra"] = true; Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; bool ok = reader->parse( doc, doc + std::strlen(doc), &root, &errs); @@ -2020,7 +2020,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { b.settings_["failIfExtra"] = false; b.strictMode(&b.settings_); Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; bool ok = reader->parse( doc, doc + std::strlen(doc), &root, &errs); @@ -2040,7 +2040,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue107) { "1:2:3"; b.settings_["failIfExtra"] = true; Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; bool ok = reader->parse( doc, doc + std::strlen(doc), &root, &errs); @@ -2060,7 +2060,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterObject) { "{ \"property\" : \"value\" } //trailing\n//comment\n"; b.settings_["failIfExtra"] = true; Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; bool ok = reader->parse( doc, doc + std::strlen(doc), &root, &errs); @@ -2077,7 +2077,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterArray) { "[ \"property\" , \"value\" ] //trailing\n//comment\n"; b.settings_["failIfExtra"] = true; Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; bool ok = reader->parse( doc, doc + std::strlen(doc), &root, &errs); @@ -2093,7 +2093,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterBool) { " true /*trailing\ncomment*/"; b.settings_["failIfExtra"] = true; Json::CharReader* reader(b.newCharReader()); - std::string errs; + JSONCPP_STRING errs; bool ok = reader->parse( doc, doc + std::strlen(doc), &root, &errs); @@ -2108,7 +2108,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { Json::CharReaderBuilder b; b.settings_["allowDroppedNullPlaceholders"] = true; Json::Value root; - std::string errs; + JSONCPP_STRING errs; Json::CharReader* reader(b.newCharReader()); { char const doc[] = "{\"a\":,\"b\":true}"; @@ -2260,7 +2260,7 @@ JSONTEST_FIXTURE(CharReaderAllowSingleQuotesTest, issue182) { Json::CharReaderBuilder b; b.settings_["allowSingleQuotes"] = true; Json::Value root; - std::string errs; + JSONCPP_STRING errs; Json::CharReader* reader(b.newCharReader()); { char const doc[] = "{'a':true,\"b\":true}"; @@ -2293,7 +2293,7 @@ JSONTEST_FIXTURE(CharReaderAllowZeroesTest, issue176) { Json::CharReaderBuilder b; b.settings_["allowSingleQuotes"] = true; Json::Value root; - std::string errs; + JSONCPP_STRING errs; Json::CharReader* reader(b.newCharReader()); { char const doc[] = "{'a':true,\"b\":true}"; @@ -2326,7 +2326,7 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { Json::CharReaderBuilder b; b.settings_["allowSpecialFloats"] = true; Json::Value root; - std::string errs; + JSONCPP_STRING errs; Json::CharReader* reader(b.newCharReader()); { char const doc[] = "{\"a\":NaN,\"b\":Infinity,\"c\":-Infinity}"; @@ -2345,7 +2345,7 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { struct TestData { int line; bool ok; - std::string in; + JSONCPP_STRING in; }; const TestData test_data[] = { {__LINE__, 1, "{\"a\":9}"}, @@ -2425,7 +2425,7 @@ JSONTEST_FIXTURE(IteratorTest, distance) { json["k1"] = "a"; json["k2"] = "b"; int dist = 0; - std::string str; + JSONCPP_STRING str; for (Json::ValueIterator it = json.begin(); it != json.end(); ++it) { dist = it - json.begin(); str = it->asString().c_str(); @@ -2482,7 +2482,7 @@ JSONTEST_FIXTURE(IteratorTest, const) { { JSONCPP_OSTRINGSTREAM out; out << std::setw(2) << i; - std::string str = out.str(); + JSONCPP_STRING str = out.str(); value[str] = str; } @@ -2493,7 +2493,7 @@ JSONTEST_FIXTURE(IteratorTest, const) { { out << *iter << ','; } - std::string expected = "\" 9\",\"10\",\"11\","; + JSONCPP_STRING expected = "\" 9\",\"10\",\"11\","; JSONTEST_ASSERT_STRING_EQUAL(expected, out.str()); }