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 (C) 2016 InfoTeCS JSC. All rights reserved.
|
||||
// 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
|
||||
@ -44,13 +45,13 @@
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
static int const stackLimit_g = 1000;
|
||||
#if __cplusplus >= 201103L
|
||||
thread_local static int stackDepth_g = 0; // see readValue()
|
||||
#else
|
||||
static int stackDepth_g = 0; // see readValue()
|
||||
// Define JSONCPP_STACK_LIMIT as an appropriate integer at compile time to change the stack limit
|
||||
#if !defined(JSONCPP_STACK_LIMIT)
|
||||
#define JSONCPP_STACK_LIMIT 1000
|
||||
#endif
|
||||
|
||||
static size_t const stackLimit_g = JSONCPP_STACK_LIMIT; // see readValue()
|
||||
|
||||
namespace Json {
|
||||
|
||||
#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
|
||||
@ -142,7 +143,6 @@ bool Reader::parse(const char* beginDoc,
|
||||
nodes_.pop();
|
||||
nodes_.push(&root);
|
||||
|
||||
stackDepth_g = 0; // Yes, this is bad coding, but options are limited.
|
||||
bool successful = readValue();
|
||||
Token token;
|
||||
skipCommentTokens(token);
|
||||
@ -165,12 +165,10 @@ bool Reader::parse(const char* beginDoc,
|
||||
}
|
||||
|
||||
bool Reader::readValue() {
|
||||
// This is a non-reentrant way to support a stackLimit. Terrible!
|
||||
// But this deprecated class has a security problem: Bad input can
|
||||
// cause a seg-fault. This seems like a fair, binary-compatible way
|
||||
// to prevent the problem.
|
||||
if (stackDepth_g >= stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
|
||||
++stackDepth_g;
|
||||
// readValue() may call itself only if it calls readObject() or ReadArray().
|
||||
// These methods execute nodes_.push() just before and nodes_.pop)() just after calling readValue().
|
||||
// parse() executes one nodes_.push(), so > instead of >=.
|
||||
if (nodes_.size() > stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
|
||||
|
||||
Token token;
|
||||
skipCommentTokens(token);
|
||||
@ -244,7 +242,6 @@ bool Reader::readValue() {
|
||||
lastValue_ = ¤tValue();
|
||||
}
|
||||
|
||||
--stackDepth_g;
|
||||
return successful;
|
||||
}
|
||||
|
||||
@ -1032,7 +1029,6 @@ private:
|
||||
Location lastValueEnd_;
|
||||
Value* lastValue_;
|
||||
JSONCPP_STRING commentsBefore_;
|
||||
int stackDepth_;
|
||||
|
||||
OurFeatures const features_;
|
||||
bool collectComments_;
|
||||
@ -1043,7 +1039,6 @@ private:
|
||||
OurReader::OurReader(OurFeatures const& features)
|
||||
: errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
|
||||
lastValue_(), commentsBefore_(),
|
||||
stackDepth_(0),
|
||||
features_(features), collectComments_() {
|
||||
}
|
||||
|
||||
@ -1067,7 +1062,6 @@ bool OurReader::parse(const char* beginDoc,
|
||||
nodes_.pop();
|
||||
nodes_.push(&root);
|
||||
|
||||
stackDepth_ = 0;
|
||||
bool successful = readValue();
|
||||
Token token;
|
||||
skipCommentTokens(token);
|
||||
@ -1096,8 +1090,8 @@ bool OurReader::parse(const char* beginDoc,
|
||||
}
|
||||
|
||||
bool OurReader::readValue() {
|
||||
if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
|
||||
++stackDepth_;
|
||||
// To preserve the old behaviour we cast size_t to int.
|
||||
if (static_cast<int>(nodes_.size()) > features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
|
||||
Token token;
|
||||
skipCommentTokens(token);
|
||||
bool successful = true;
|
||||
@ -1194,7 +1188,6 @@ bool OurReader::readValue() {
|
||||
lastValue_ = ¤tValue();
|
||||
}
|
||||
|
||||
--stackDepth_;
|
||||
return successful;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user