Skip to content

Secure alloc compile time #426

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
94 changes: 94 additions & 0 deletions include/json/allocator.h
Original file line number Diff line number Diff line change
@@ -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 <cstring>
#include <memory>

namespace Json {
template<typename T>
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<pointer>(::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<typename... Args>
void construct(pointer p, Args&&... args) {
// construct using "placement new" and "perfect forwarding"
::new (static_cast<void*>(p)) T(std::forward<Args>(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<typename U> SecureAllocator(const SecureAllocator<U>&) {}
template<typename U> struct rebind { using other = SecureAllocator<U>; };
};


template<typename T, typename U>
bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return true;
}

template<typename T, typename U>
bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return false;
}

} //namespace Json

#endif // CPPTL_JSON_ALLOCATOR_H_INCLUDED
4 changes: 2 additions & 2 deletions include/json/assertions.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

# define JSON_FAIL_MESSAGE(message) \
{ \
std::ostringstream oss; oss << message; \
Json::OStringStream oss; oss << message; \
Json::throwLogicError(oss.str()); \
abort(); \
}
Expand All @@ -38,7 +38,7 @@
// release builds we abort, for a core-dump or debugger.
# define JSON_FAIL_MESSAGE(message) \
{ \
std::ostringstream oss; oss << message; \
Json::OStringStream oss; oss << message; \
assert(false && oss.str().c_str()); \
abort(); \
}
Expand Down
19 changes: 19 additions & 0 deletions include/json/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#ifndef JSON_CONFIG_H_INCLUDED
#define JSON_CONFIG_H_INCLUDED
#include <stddef.h>
#include "allocator.h" //typedef Allocator
#include <string> //typdef String

/// If defined, indicates that json library is embedded in CppTL library.
//# define JSON_IN_CPPTL 1
Expand Down Expand Up @@ -118,6 +120,12 @@
# 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

namespace Json {
typedef int Int;
typedef unsigned int UInt;
Expand All @@ -138,6 +146,17 @@ typedef Int64 LargestInt;
typedef UInt64 LargestUInt;
#define JSON_HAS_INT64
#endif // if defined(JSON_NO_INT64)
#if JSON_USE_SECURE_MEMORY
typedef std::basic_string<char, std::char_traits<char>, SecureAllocator<char>> String;
typedef std::basic_ostringstream<char, std::char_traits<char>, SecureAllocator<char>> OStringStream;
typedef std::basic_ostream<char, std::char_traits<char>> OStream;
typedef std::basic_istringstream<char, std::char_traits<char>, SecureAllocator<char>> IStringStream;
#else
typedef std::string String;
typedef std::ostringstream OStringStream;
typedef std::ostream OStream;
typedef std::istringstream IStringStream;
#endif // if JSON_USE_SECURE_MEMORY
} // end namespace Json

#endif // JSON_CONFIG_H_INCLUDED
32 changes: 16 additions & 16 deletions include/json/reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class JSON_API Reader {
struct StructuredError {
ptrdiff_t offset_start;
ptrdiff_t offset_limit;
std::string message;
Json::String message;
};

/** \brief Constructs a Reader allowing all features
Expand Down Expand Up @@ -111,7 +111,7 @@ class JSON_API Reader {
* \deprecated Use getFormattedErrorMessages() instead (typo fix).
*/
JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
std::string getFormatedErrorMessages() const;
Json::String getFormatedErrorMessages() const;

/** \brief Returns a user friendly string that list errors in the parsed
* document.
Expand All @@ -121,7 +121,7 @@ class JSON_API Reader {
* occurred
* during parsing.
*/
std::string getFormattedErrorMessages() const;
Json::String getFormattedErrorMessages() const;

/** \brief Returns a vector of structured erros encounted while parsing.
* \return A (possibly empty) vector of StructuredError objects. Currently
Expand All @@ -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 Json::String& message);

/** \brief Add a semantic error message with extra context.
* \param value JSON Value location associated with the error
Expand All @@ -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 Json::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
Expand Down Expand Up @@ -183,7 +183,7 @@ class JSON_API Reader {
class ErrorInfo {
public:
Token token_;
std::string message_;
Json::String message_;
Location extra_;
};

Expand All @@ -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, Json::String& decoded);
bool decodeDouble(Token& token);
bool decodeDouble(Token& token, Value& decoded);
bool decodeUnicodeCodePoint(Token& token,
Expand All @@ -214,30 +214,30 @@ 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 Json::String& message, Token& token, Location extra = 0);
bool recoverFromError(TokenType skipUntilToken);
bool addErrorAndRecover(const std::string& message,
bool addErrorAndRecover(const Json::String& message,
Token& token,
TokenType skipUntilToken);
void skipUntilSpace();
Value& currentValue();
Char getNextChar();
void
getLocationLineAndColumn(Location location, int& line, int& column) const;
std::string getLocationLineAndColumn(Location location) const;
Json::String getLocationLineAndColumn(Location location) const;
void addComment(Location begin, Location end, CommentPlacement placement);
void skipCommentTokens(Token& token);

typedef std::stack<Value*> Nodes;
Nodes nodes_;
Errors errors_;
std::string document_;
Json::String document_;
Location begin_;
Location end_;
Location current_;
Location lastValueEnd_;
Value* lastValue_;
std::string commentsBefore_;
Json::String commentsBefore_;
Features features_;
bool collectComments_;
}; // Reader
Expand Down Expand Up @@ -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, Json::String* errs) = 0;

class JSON_API Factory {
public:
Expand All @@ -286,7 +286,7 @@ class JSON_API CharReader {
CharReaderBuilder builder;
builder["collectComments"] = false;
Value value;
std::string errs;
Json::String errs;
bool ok = parseFromStream(builder, std::cin, &value, &errs);
\endcode
*/
Expand Down Expand Up @@ -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[](Json::String key);

/** Called by ctor, but you can use this to reset settings_.
* \pre 'settings' != NULL (but Json::null is fine)
Expand All @@ -367,7 +367,7 @@ class JSON_API CharReaderBuilder : public CharReader::Factory {
bool JSON_API parseFromStream(
CharReader::Factory const&,
std::istream&,
Value* root, std::string* errs);
Value* root, Json::String* errs);

/** \brief Read from 'sin' into 'root'.

Expand Down
Loading