mirror of
https://github.com/opencv/opencv.git
synced 2025-07-31 18:07:08 +08:00
Merge pull request #17157 from alalek:issue_17138
This commit is contained in:
commit
ee201f4df5
@ -225,7 +225,9 @@ class TextFormat::Parser::ParserImpl {
|
|||||||
bool allow_unknown_enum,
|
bool allow_unknown_enum,
|
||||||
bool allow_field_number,
|
bool allow_field_number,
|
||||||
bool allow_relaxed_whitespace,
|
bool allow_relaxed_whitespace,
|
||||||
bool allow_partial)
|
bool allow_partial,
|
||||||
|
int recursion_limit // backported from 3.8.0
|
||||||
|
)
|
||||||
: error_collector_(error_collector),
|
: error_collector_(error_collector),
|
||||||
finder_(finder),
|
finder_(finder),
|
||||||
parse_info_tree_(parse_info_tree),
|
parse_info_tree_(parse_info_tree),
|
||||||
@ -238,7 +240,9 @@ class TextFormat::Parser::ParserImpl {
|
|||||||
allow_unknown_enum_(allow_unknown_enum),
|
allow_unknown_enum_(allow_unknown_enum),
|
||||||
allow_field_number_(allow_field_number),
|
allow_field_number_(allow_field_number),
|
||||||
allow_partial_(allow_partial),
|
allow_partial_(allow_partial),
|
||||||
had_errors_(false) {
|
had_errors_(false),
|
||||||
|
recursion_limit_(recursion_limit) // backported from 3.8.0
|
||||||
|
{
|
||||||
// For backwards-compatibility with proto1, we need to allow the 'f' suffix
|
// For backwards-compatibility with proto1, we need to allow the 'f' suffix
|
||||||
// for floats.
|
// for floats.
|
||||||
tokenizer_.set_allow_f_after_float(true);
|
tokenizer_.set_allow_f_after_float(true);
|
||||||
@ -490,9 +494,9 @@ class TextFormat::Parser::ParserImpl {
|
|||||||
if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
|
if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
|
||||||
UnknownFieldSet* unknown_field = unknown_fields->AddGroup(unknown_fields->field_count());
|
UnknownFieldSet* unknown_field = unknown_fields->AddGroup(unknown_fields->field_count());
|
||||||
unknown_field->AddLengthDelimited(0, field_name); // Add a field's name.
|
unknown_field->AddLengthDelimited(0, field_name); // Add a field's name.
|
||||||
return SkipFieldValue(unknown_field);
|
return SkipFieldValue(unknown_field, recursion_limit_);
|
||||||
} else {
|
} else {
|
||||||
return SkipFieldMessage(unknown_fields);
|
return SkipFieldMessage(unknown_fields, recursion_limit_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,7 +579,14 @@ label_skip_parsing:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Skips the next field including the field's name and value.
|
// Skips the next field including the field's name and value.
|
||||||
bool SkipField(UnknownFieldSet* unknown_fields) {
|
bool SkipField(UnknownFieldSet* unknown_fields, int recursion_limit) {
|
||||||
|
|
||||||
|
// OpenCV specific
|
||||||
|
if (--recursion_limit < 0) {
|
||||||
|
ReportError("Message is too deep (SkipField)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
string field_name;
|
string field_name;
|
||||||
if (TryConsume("[")) {
|
if (TryConsume("[")) {
|
||||||
// Extension name.
|
// Extension name.
|
||||||
@ -594,9 +605,9 @@ label_skip_parsing:
|
|||||||
if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
|
if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
|
||||||
UnknownFieldSet* unknown_field = unknown_fields->AddGroup(unknown_fields->field_count());
|
UnknownFieldSet* unknown_field = unknown_fields->AddGroup(unknown_fields->field_count());
|
||||||
unknown_field->AddLengthDelimited(0, field_name); // Add a field's name.
|
unknown_field->AddLengthDelimited(0, field_name); // Add a field's name.
|
||||||
DO(SkipFieldValue(unknown_field));
|
DO(SkipFieldValue(unknown_field, recursion_limit));
|
||||||
} else {
|
} else {
|
||||||
DO(SkipFieldMessage(unknown_fields));
|
DO(SkipFieldMessage(unknown_fields, recursion_limit));
|
||||||
}
|
}
|
||||||
// For historical reasons, fields may optionally be separated by commas or
|
// For historical reasons, fields may optionally be separated by commas or
|
||||||
// semicolons.
|
// semicolons.
|
||||||
@ -608,6 +619,12 @@ label_skip_parsing:
|
|||||||
const Reflection* reflection,
|
const Reflection* reflection,
|
||||||
const FieldDescriptor* field) {
|
const FieldDescriptor* field) {
|
||||||
|
|
||||||
|
// backported from 3.8.0
|
||||||
|
if (--recursion_limit_ < 0) {
|
||||||
|
ReportError("Message is too deep");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// If the parse information tree is not NULL, create a nested one
|
// If the parse information tree is not NULL, create a nested one
|
||||||
// for the nested message.
|
// for the nested message.
|
||||||
ParseInfoTree* parent = parse_info_tree_;
|
ParseInfoTree* parent = parse_info_tree_;
|
||||||
@ -624,6 +641,9 @@ label_skip_parsing:
|
|||||||
delimiter));
|
delimiter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// backported from 3.8.0
|
||||||
|
++recursion_limit_;
|
||||||
|
|
||||||
// Reset the parse information tree.
|
// Reset the parse information tree.
|
||||||
parse_info_tree_ = parent;
|
parse_info_tree_ = parent;
|
||||||
return true;
|
return true;
|
||||||
@ -631,11 +651,17 @@ label_skip_parsing:
|
|||||||
|
|
||||||
// Skips the whole body of a message including the beginning delimiter and
|
// Skips the whole body of a message including the beginning delimiter and
|
||||||
// the ending delimiter.
|
// the ending delimiter.
|
||||||
bool SkipFieldMessage(UnknownFieldSet* unknown_fields) {
|
bool SkipFieldMessage(UnknownFieldSet* unknown_fields, int recursion_limit) {
|
||||||
|
// OpenCV specific
|
||||||
|
if (--recursion_limit < 0) {
|
||||||
|
ReportError("Message is too deep (SkipFieldMessage)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
string delimiter;
|
string delimiter;
|
||||||
DO(ConsumeMessageDelimiter(&delimiter));
|
DO(ConsumeMessageDelimiter(&delimiter));
|
||||||
while (!LookingAt(">") && !LookingAt("}")) {
|
while (!LookingAt(">") && !LookingAt("}")) {
|
||||||
DO(SkipField(unknown_fields));
|
DO(SkipField(unknown_fields, recursion_limit));
|
||||||
}
|
}
|
||||||
DO(Consume(delimiter));
|
DO(Consume(delimiter));
|
||||||
return true;
|
return true;
|
||||||
@ -775,7 +801,14 @@ label_skip_parsing:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkipFieldValue(UnknownFieldSet* unknown_field) {
|
bool SkipFieldValue(UnknownFieldSet* unknown_field, int recursion_limit) {
|
||||||
|
|
||||||
|
// OpenCV specific
|
||||||
|
if (--recursion_limit < 0) {
|
||||||
|
ReportError("Message is too deep (SkipFieldValue)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
|
if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
|
||||||
while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
|
while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
|
||||||
tokenizer_.Next();
|
tokenizer_.Next();
|
||||||
@ -785,9 +818,9 @@ label_skip_parsing:
|
|||||||
if (TryConsume("[")) {
|
if (TryConsume("[")) {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!LookingAt("{") && !LookingAt("<")) {
|
if (!LookingAt("{") && !LookingAt("<")) {
|
||||||
DO(SkipFieldValue(unknown_field));
|
DO(SkipFieldValue(unknown_field, recursion_limit));
|
||||||
} else {
|
} else {
|
||||||
DO(SkipFieldMessage(unknown_field));
|
DO(SkipFieldMessage(unknown_field, recursion_limit));
|
||||||
}
|
}
|
||||||
if (TryConsume("]")) {
|
if (TryConsume("]")) {
|
||||||
break;
|
break;
|
||||||
@ -1156,6 +1189,7 @@ label_skip_parsing:
|
|||||||
const bool allow_field_number_;
|
const bool allow_field_number_;
|
||||||
const bool allow_partial_;
|
const bool allow_partial_;
|
||||||
bool had_errors_;
|
bool had_errors_;
|
||||||
|
int recursion_limit_; // backported from 3.8.0
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef DO
|
#undef DO
|
||||||
@ -1306,17 +1340,19 @@ class TextFormat::Printer::TextGenerator
|
|||||||
TextFormat::Finder::~Finder() {
|
TextFormat::Finder::~Finder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextFormat::Parser::Parser(bool allow_unknown_field)
|
TextFormat::Parser::Parser()
|
||||||
: error_collector_(NULL),
|
: error_collector_(NULL),
|
||||||
finder_(NULL),
|
finder_(NULL),
|
||||||
parse_info_tree_(NULL),
|
parse_info_tree_(NULL),
|
||||||
allow_partial_(false),
|
allow_partial_(false),
|
||||||
allow_case_insensitive_field_(false),
|
allow_case_insensitive_field_(false),
|
||||||
allow_unknown_field_(allow_unknown_field),
|
allow_unknown_field_(false),
|
||||||
allow_unknown_enum_(false),
|
allow_unknown_enum_(false),
|
||||||
allow_field_number_(false),
|
allow_field_number_(false),
|
||||||
allow_relaxed_whitespace_(false),
|
allow_relaxed_whitespace_(false),
|
||||||
allow_singular_overwrites_(false) {
|
allow_singular_overwrites_(false),
|
||||||
|
recursion_limit_(std::numeric_limits<int>::max())
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TextFormat::Parser::~Parser() {}
|
TextFormat::Parser::~Parser() {}
|
||||||
@ -1335,7 +1371,7 @@ bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
|
|||||||
overwrites_policy,
|
overwrites_policy,
|
||||||
allow_case_insensitive_field_, allow_unknown_field_,
|
allow_case_insensitive_field_, allow_unknown_field_,
|
||||||
allow_unknown_enum_, allow_field_number_,
|
allow_unknown_enum_, allow_field_number_,
|
||||||
allow_relaxed_whitespace_, allow_partial_);
|
allow_relaxed_whitespace_, allow_partial_, recursion_limit_);
|
||||||
return MergeUsingImpl(input, output, &parser);
|
return MergeUsingImpl(input, output, &parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1353,7 +1389,7 @@ bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
|
|||||||
ParserImpl::ALLOW_SINGULAR_OVERWRITES,
|
ParserImpl::ALLOW_SINGULAR_OVERWRITES,
|
||||||
allow_case_insensitive_field_, allow_unknown_field_,
|
allow_case_insensitive_field_, allow_unknown_field_,
|
||||||
allow_unknown_enum_, allow_field_number_,
|
allow_unknown_enum_, allow_field_number_,
|
||||||
allow_relaxed_whitespace_, allow_partial_);
|
allow_relaxed_whitespace_, allow_partial_, recursion_limit_);
|
||||||
return MergeUsingImpl(input, output, &parser);
|
return MergeUsingImpl(input, output, &parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1388,7 +1424,7 @@ bool TextFormat::Parser::ParseFieldValueFromString(
|
|||||||
ParserImpl::ALLOW_SINGULAR_OVERWRITES,
|
ParserImpl::ALLOW_SINGULAR_OVERWRITES,
|
||||||
allow_case_insensitive_field_, allow_unknown_field_,
|
allow_case_insensitive_field_, allow_unknown_field_,
|
||||||
allow_unknown_enum_, allow_field_number_,
|
allow_unknown_enum_, allow_field_number_,
|
||||||
allow_relaxed_whitespace_, allow_partial_);
|
allow_relaxed_whitespace_, allow_partial_, recursion_limit_);
|
||||||
return parser.ParseField(field, output);
|
return parser.ParseField(field, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,7 +457,7 @@ class LIBPROTOBUF_EXPORT TextFormat {
|
|||||||
// For more control over parsing, use this class.
|
// For more control over parsing, use this class.
|
||||||
class LIBPROTOBUF_EXPORT Parser {
|
class LIBPROTOBUF_EXPORT Parser {
|
||||||
public:
|
public:
|
||||||
Parser(bool allow_unknown_field = false);
|
Parser();
|
||||||
~Parser();
|
~Parser();
|
||||||
|
|
||||||
// Like TextFormat::Parse().
|
// Like TextFormat::Parse().
|
||||||
@ -508,10 +508,24 @@ class LIBPROTOBUF_EXPORT TextFormat {
|
|||||||
Message* output);
|
Message* output);
|
||||||
|
|
||||||
|
|
||||||
|
// backported from 3.8.0
|
||||||
|
// When an unknown field is met, parsing will fail if this option is set
|
||||||
|
// to false(the default). If true, unknown fields will be ignored and
|
||||||
|
// a warning message will be generated.
|
||||||
|
// Please aware that set this option true may hide some errors (e.g.
|
||||||
|
// spelling error on field name). Avoid to use this option if possible.
|
||||||
|
void AllowUnknownField(bool allow) { allow_unknown_field_ = allow; }
|
||||||
|
|
||||||
|
|
||||||
void AllowFieldNumber(bool allow) {
|
void AllowFieldNumber(bool allow) {
|
||||||
allow_field_number_ = allow;
|
allow_field_number_ = allow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// backported from 3.8.0
|
||||||
|
// Sets maximum recursion depth which parser can use. This is effectively
|
||||||
|
// the maximum allowed nesting of proto messages.
|
||||||
|
void SetRecursionLimit(int limit) { recursion_limit_ = limit; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Forward declaration of an internal class used to parse text
|
// Forward declaration of an internal class used to parse text
|
||||||
// representations (see text_format.cc for implementation).
|
// representations (see text_format.cc for implementation).
|
||||||
@ -533,6 +547,7 @@ class LIBPROTOBUF_EXPORT TextFormat {
|
|||||||
bool allow_field_number_;
|
bool allow_field_number_;
|
||||||
bool allow_relaxed_whitespace_;
|
bool allow_relaxed_whitespace_;
|
||||||
bool allow_singular_overwrites_;
|
bool allow_singular_overwrites_;
|
||||||
|
int recursion_limit_; // backported from 3.8.0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1120,11 +1120,12 @@ bool ReadProtoFromTextFile(const char* filename, Message* proto) {
|
|||||||
std::ifstream fs(filename, std::ifstream::in);
|
std::ifstream fs(filename, std::ifstream::in);
|
||||||
CHECK(fs.is_open()) << "Can't open \"" << filename << "\"";
|
CHECK(fs.is_open()) << "Can't open \"" << filename << "\"";
|
||||||
IstreamInputStream input(&fs);
|
IstreamInputStream input(&fs);
|
||||||
|
google::protobuf::TextFormat::Parser parser;
|
||||||
#ifndef OPENCV_DNN_EXTERNAL_PROTOBUF
|
#ifndef OPENCV_DNN_EXTERNAL_PROTOBUF
|
||||||
return google::protobuf::TextFormat::Parser(true).Parse(&input, proto);
|
parser.AllowUnknownField(true);
|
||||||
#else
|
parser.SetRecursionLimit(1000);
|
||||||
return google::protobuf::TextFormat::Parser().Parse(&input, proto);
|
|
||||||
#endif
|
#endif
|
||||||
|
return parser.Parse(&input, proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadProtoFromBinaryFile(const char* filename, Message* proto) {
|
bool ReadProtoFromBinaryFile(const char* filename, Message* proto) {
|
||||||
@ -1137,12 +1138,12 @@ bool ReadProtoFromBinaryFile(const char* filename, Message* proto) {
|
|||||||
|
|
||||||
bool ReadProtoFromTextBuffer(const char* data, size_t len, Message* proto) {
|
bool ReadProtoFromTextBuffer(const char* data, size_t len, Message* proto) {
|
||||||
ArrayInputStream input(data, len);
|
ArrayInputStream input(data, len);
|
||||||
|
google::protobuf::TextFormat::Parser parser;
|
||||||
#ifndef OPENCV_DNN_EXTERNAL_PROTOBUF
|
#ifndef OPENCV_DNN_EXTERNAL_PROTOBUF
|
||||||
return google::protobuf::TextFormat::Parser(true).Parse(&input, proto);
|
parser.AllowUnknownField(true);
|
||||||
#else
|
parser.SetRecursionLimit(1000);
|
||||||
return google::protobuf::TextFormat::Parser().Parse(&input, proto);
|
|
||||||
#endif
|
#endif
|
||||||
|
return parser.Parse(&input, proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user