mirror of
https://github.com/open-source-parsers/jsoncpp.git
synced 2025-03-04 19:13:29 +01:00
Add files via upload
Removed a static variable used to contain the current recursion depth of Reader::readValue(). The number of elements in an internal container Reader::nodes_ is used instead. It is correct because any recursive call of Reader::readValue() is executed with adjacent nodes_.push() and nodes_.pop() calls. Added the option to change the allowed recursion depth at compile time by defining a macro JSONCPP_STACK_LIMIT as the required integer value.
This commit is contained in:
parent
77632b2611
commit
2ecd2a59de
@ -1,4 +1,5 @@
|
|||||||
// Copyright 2007-2011 Baptiste Lepilleur
|
// Copyright 2007-2011 Baptiste Lepilleur
|
||||||
|
// Copyright (C) 2016 InfoTeCS JSC. All rights reserved.
|
||||||
// Distributed under MIT license, or public domain if desired and
|
// Distributed under MIT license, or public domain if desired and
|
||||||
// recognized in your jurisdiction.
|
// recognized in your jurisdiction.
|
||||||
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
|
||||||
@ -44,13 +45,13 @@
|
|||||||
#pragma warning(disable : 4996)
|
#pragma warning(disable : 4996)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int const stackLimit_g = 1000;
|
// Define JSONCPP_STACK_LIMIT as an appropriate integer at compile time to change the stack limit
|
||||||
#if __cplusplus >= 201103L
|
#if !defined(JSONCPP_STACK_LIMIT)
|
||||||
thread_local static int stackDepth_g = 0; // see readValue()
|
#define JSONCPP_STACK_LIMIT 1000
|
||||||
#else
|
|
||||||
static int stackDepth_g = 0; // see readValue()
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static size_t const stackLimit_g = JSONCPP_STACK_LIMIT; // see readValue()
|
||||||
|
|
||||||
namespace Json {
|
namespace Json {
|
||||||
|
|
||||||
#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
|
#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
|
||||||
@ -142,7 +143,6 @@ bool Reader::parse(const char* beginDoc,
|
|||||||
nodes_.pop();
|
nodes_.pop();
|
||||||
nodes_.push(&root);
|
nodes_.push(&root);
|
||||||
|
|
||||||
stackDepth_g = 0; // Yes, this is bad coding, but options are limited.
|
|
||||||
bool successful = readValue();
|
bool successful = readValue();
|
||||||
Token token;
|
Token token;
|
||||||
skipCommentTokens(token);
|
skipCommentTokens(token);
|
||||||
@ -165,12 +165,10 @@ bool Reader::parse(const char* beginDoc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Reader::readValue() {
|
bool Reader::readValue() {
|
||||||
// This is a non-reentrant way to support a stackLimit. Terrible!
|
// readValue() may call itself only if it calls readObject() or ReadArray().
|
||||||
// But this deprecated class has a security problem: Bad input can
|
// These methods execute nodes_.push() just before and nodes_.pop)() just after calling readValue().
|
||||||
// cause a seg-fault. This seems like a fair, binary-compatible way
|
// parse() executes one nodes_.push(), so > instead of >=.
|
||||||
// to prevent the problem.
|
if (nodes_.size() > stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
|
||||||
if (stackDepth_g >= stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
|
|
||||||
++stackDepth_g;
|
|
||||||
|
|
||||||
Token token;
|
Token token;
|
||||||
skipCommentTokens(token);
|
skipCommentTokens(token);
|
||||||
@ -244,7 +242,6 @@ bool Reader::readValue() {
|
|||||||
lastValue_ = ¤tValue();
|
lastValue_ = ¤tValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
--stackDepth_g;
|
|
||||||
return successful;
|
return successful;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1032,7 +1029,6 @@ private:
|
|||||||
Location lastValueEnd_;
|
Location lastValueEnd_;
|
||||||
Value* lastValue_;
|
Value* lastValue_;
|
||||||
JSONCPP_STRING commentsBefore_;
|
JSONCPP_STRING commentsBefore_;
|
||||||
int stackDepth_;
|
|
||||||
|
|
||||||
OurFeatures const features_;
|
OurFeatures const features_;
|
||||||
bool collectComments_;
|
bool collectComments_;
|
||||||
@ -1043,7 +1039,6 @@ private:
|
|||||||
OurReader::OurReader(OurFeatures const& features)
|
OurReader::OurReader(OurFeatures const& features)
|
||||||
: errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
|
: errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
|
||||||
lastValue_(), commentsBefore_(),
|
lastValue_(), commentsBefore_(),
|
||||||
stackDepth_(0),
|
|
||||||
features_(features), collectComments_() {
|
features_(features), collectComments_() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1067,7 +1062,6 @@ bool OurReader::parse(const char* beginDoc,
|
|||||||
nodes_.pop();
|
nodes_.pop();
|
||||||
nodes_.push(&root);
|
nodes_.push(&root);
|
||||||
|
|
||||||
stackDepth_ = 0;
|
|
||||||
bool successful = readValue();
|
bool successful = readValue();
|
||||||
Token token;
|
Token token;
|
||||||
skipCommentTokens(token);
|
skipCommentTokens(token);
|
||||||
@ -1096,8 +1090,8 @@ bool OurReader::parse(const char* beginDoc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool OurReader::readValue() {
|
bool OurReader::readValue() {
|
||||||
if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
|
// To preserve the old behaviour we cast size_t to int.
|
||||||
++stackDepth_;
|
if (static_cast<int>(nodes_.size()) > features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
|
||||||
Token token;
|
Token token;
|
||||||
skipCommentTokens(token);
|
skipCommentTokens(token);
|
||||||
bool successful = true;
|
bool successful = true;
|
||||||
@ -1194,7 +1188,6 @@ bool OurReader::readValue() {
|
|||||||
lastValue_ = ¤tValue();
|
lastValue_ = ¤tValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
--stackDepth_;
|
|
||||||
return successful;
|
return successful;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user