-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