-DJSONCPP_USE_SECURE_MEMORY=1 for cmake
Add allocator.h to amalgamated header
Test JSONCPP_USE_SECURE_MEMORY in Travis
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 22567b9..9a89f6e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -69,6 +69,7 @@
#IF(NOT JSONCPP_VERSION_FOUND)
# MESSAGE(FATAL_ERROR "Failed to parse version string properly. Expect X.Y.Z")
#ENDIF(NOT JSONCPP_VERSION_FOUND)
+SET( JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL" )
MESSAGE(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}")
# File version.h is only regenerated on CMake configure step
diff --git a/amalgamate.py b/amalgamate.py
index 1916bb0..2102f30 100644
--- a/amalgamate.py
+++ b/amalgamate.py
@@ -67,6 +67,7 @@
header.add_text("/// to prevent private header inclusion.")
header.add_text("#define JSON_IS_AMALGAMATION")
header.add_file("include/json/version.h")
+ header.add_file("include/json/allocator.h")
header.add_file("include/json/config.h")
header.add_file("include/json/forwards.h")
header.add_file("include/json/features.h")
diff --git a/include/json/config.h b/include/json/config.h
index 213d9cb..1e96210 100644
--- a/include/json/config.h
+++ b/include/json/config.h
@@ -119,13 +119,9 @@
# 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
+#include "version.h"
-#if JSON_USE_SECURE_MEMORY
+#if JSONCPP_USING_SECURE_MEMORY
#include "allocator.h" //typedef Allocator
#endif
@@ -149,11 +145,11 @@
typedef UInt64 LargestUInt;
#define JSON_HAS_INT64
#endif // if defined(JSON_NO_INT64)
-#if JSON_USE_SECURE_MEMORY
-#define JSONCPP_STRING std::basic_string<char, std::char_traits<char>, SecureAllocator<char> >
-#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream<char, std::char_traits<char>, SecureAllocator<char> >
+#if JSONCPP_USING_SECURE_MEMORY
+#define JSONCPP_STRING std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
+#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
#define JSONCPP_OSTREAM std::basic_ostream<char, std::char_traits<char>>
-#define JSONCPP_ISTRINGSTREAM std::basic_istringstream<char, std::char_traits<char>, SecureAllocator<char> >
+#define JSONCPP_ISTRINGSTREAM std::basic_istringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
#define JSONCPP_ISTREAM std::istream
#else
#define JSONCPP_STRING std::string
@@ -161,7 +157,7 @@
#define JSONCPP_OSTREAM std::ostream
#define JSONCPP_ISTRINGSTREAM std::istringstream
#define JSONCPP_ISTREAM std::istream
-#endif // if JSON_USE_SECURE_MEMORY
+#endif // if JSONCPP_USING_SECURE_MEMORY
} // end namespace Json
#endif // JSON_CONFIG_H_INCLUDED
diff --git a/include/json/value.h b/include/json/value.h
index 5948935..20747fe 100644
--- a/include/json/value.h
+++ b/include/json/value.h
@@ -336,6 +336,9 @@
int compare(const Value& other) const;
const char* asCString() const; ///< Embedded zeroes could cause you trouble!
+#if JSONCPP_USING_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/version.h b/include/json/version.h
index 6c570a1..dc975ff 100644
--- a/include/json/version.h
+++ b/include/json/version.h
@@ -10,4 +10,11 @@
# define JSONCPP_VERSION_QUALIFIER
# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
+#ifdef JSONCPP_USING_SECURE_MEMORY
+#undef JSONCPP_USING_SECURE_MEMORY
+#endif
+#define JSONCPP_USING_SECURE_MEMORY 1
+// If non-zero, the library zeroes any memory that it has allocated before
+// it frees its memory.
+
#endif // JSON_VERSION_H_INCLUDED
diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp
index 60f7e32..a1d911d 100644
--- a/src/jsontestrunner/main.cpp
+++ b/src/jsontestrunner/main.cpp
@@ -33,9 +33,6 @@
#endif
buffer[sizeof(buffer) - 1] = 0;
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 =
@@ -69,9 +66,6 @@
if (fread(buffer, 1, usize, file) == usize)
text = buffer;
fclose(file);
-#if JSON_USE_SECURE_MEMORY
- memset(buffer, 0, static_cast<size_t>(size + 1));
-#endif
delete[] buffer;
return text;
}
@@ -151,7 +145,7 @@
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(),
diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp
index f7e7bb1..ef71e19 100644
--- a/src/lib_json/json_reader.cpp
+++ b/src/lib_json/json_reader.cpp
@@ -98,7 +98,8 @@
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);
@@ -114,7 +115,7 @@
// create an extra copy.
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,
diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp
index 112d86d..bbfa12c 100644
--- a/src/lib_json/json_value.cpp
+++ b/src/lib_json/json_value.cpp
@@ -138,7 +138,29 @@
}
/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().
*/
-static inline void releaseStringValue(char* value) { free(value); }
+#if JSONCPP_USING_SECURE_MEMORY
+static inline void releasePrefixedStringValue(char* value) {
+ unsigned length = 0;
+ char const* valueDecoded;
+ decodePrefixedString(true, value, &length, &valueDecoded);
+ size_t const size = sizeof(unsigned) + length + 1U;
+ memset(value, 0, size);
+ free(value);
+}
+static inline void releaseStringValue(char* value, unsigned length) {
+ // length==0 => we allocated the strings memory
+ size_t size = (length==0) ? strlen(value) : length;
+ memset(value, 0, size);
+ free(value);
+}
+#else // !JSONCPP_USING_SECURE_MEMORY
+static inline void releasePrefixedStringValue(char* value) {
+ free(value);
+}
+static inline void releaseStringValue(char* value, unsigned length) {
+ free(value);
+}
+#endif // JSONCPP_USING_SECURE_MEMORY
} // namespace Json
@@ -193,12 +215,12 @@
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);
@@ -229,10 +251,10 @@
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<unsigned>(other.cstr_
? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication
? noDuplication : duplicate)
@@ -248,8 +270,9 @@
#endif
Value::CZString::~CZString() {
- if (cstr_ && storage_.policy_ == duplicate)
- releaseStringValue(const_cast<char*>(cstr_));
+ if (cstr_ && storage_.policy_ == duplicate) {
+ releaseStringValue(const_cast<char*>(cstr_), storage_.length_ + 1u); //+1 for null terminating character for sake of completeness but not actually necessary
+ }
}
void Value::CZString::swap(CZString& other) {
@@ -455,7 +478,7 @@
break;
case stringValue:
if (allocated_)
- releaseStringValue(value_.string_);
+ releasePrefixedStringValue(value_.string_);
break;
case arrayValue:
case objectValue:
@@ -467,6 +490,8 @@
if (comments_)
delete[] comments_;
+
+ value_.uint_ = 0;
}
Value& Value::operator=(Value other) {
@@ -611,6 +636,18 @@
return this_str;
}
+#if JSONCPP_USING_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/version.h.in b/src/lib_json/version.h.in
index 692ab5e..47aac69 100644
--- a/src/lib_json/version.h.in
+++ b/src/lib_json/version.h.in
@@ -10,4 +10,11 @@
# define JSONCPP_VERSION_QUALIFIER
# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
+#ifdef JSONCPP_USING_SECURE_MEMORY
+#undef JSONCPP_USING_SECURE_MEMORY
+#endif
+#define JSONCPP_USING_SECURE_MEMORY @JSONCPP_USE_SECURE_MEMORY@
+// If non-zero, the library zeroes any memory that it has allocated before
+// it frees its memory.
+
#endif // JSON_VERSION_H_INCLUDED
diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp
index 6ac5ceb..4c10a37 100644
--- a/src/test_lib_json/jsontest.cpp
+++ b/src/test_lib_json/jsontest.cpp
@@ -434,7 +434,7 @@
return in;
}
-#if JSON_USE_SECURE_MEMORY
+#if JSONCPP_USING_SECURE_MEMORY
JSONCPP_STRING ToJsonString(std::string in) {
return JSONCPP_STRING(in.data(), in.data() + in.length());
}
diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h
index ecd9079..69ecab7 100644
--- a/src/test_lib_json/jsontest.h
+++ b/src/test_lib_json/jsontest.h
@@ -193,7 +193,7 @@
JSONCPP_STRING ToJsonString(const char* toConvert);
JSONCPP_STRING ToJsonString(JSONCPP_STRING in);
-#if JSON_USE_SECURE_MEMORY
+#if JSONCPP_USING_SECURE_MEMORY
JSONCPP_STRING ToJsonString(std::string in);
#endif
diff --git a/travis.sh b/travis.sh
index 2b25f47..a9811ec 100755
--- a/travis.sh
+++ b/travis.sh
@@ -19,6 +19,8 @@
cmake -DJSONCPP_WITH_CMAKE_PACKAGE=$CMAKE_PKG -DBUILD_SHARED_LIBS=$SHARED_LIB -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_VERBOSE_MAKEFILE=$VERBOSE_MAKE .
make
+cmake -DJSONCPP_WITH_CMAKE_PACKAGE=$CMAKE_PKG -DBUILD_SHARED_LIBS=$SHARED_LIB -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_VERBOSE_MAKEFILE=$VERBOSE_MAKE -DJSONCPP_USE_SECURE_MEMORY=1 .
+make
# Python is not available in Travis for osx.
# https://github.com/travis-ci/travis-ci/issues/2320