From 1075c80e8aa85462893a1996b947da04d9fc6f85 Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Wed, 25 Nov 2015 15:50:30 -0800 Subject: [PATCH] Fixed crash related to flatc parsing duplicate input files. Thanks @Chaosvex for reporting. Change-Id: I73f60ab0bf875a3e0849eaec5f42f6d036881094 Tested: on Linux. --- include/flatbuffers/idl.h | 2 +- src/idl_parser.cpp | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index ad755f8c9..f1276f01b 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -419,7 +419,7 @@ class Parser { const char *source_, *cursor_; int line_; // the current line being parsed int token_; - std::stack files_being_parsed_; + std::string files_being_parsed_; bool proto_mode_; bool strict_json_; std::string attribute_; diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 13290e74b..233eeceef 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -892,7 +892,7 @@ EnumDef &Parser::ParseEnum(bool is_union) { Expect(kTokenIdentifier); auto &enum_def = *new EnumDef(); enum_def.name = enum_name; - if (!files_being_parsed_.empty()) enum_def.file = files_being_parsed_.top(); + enum_def.file = files_being_parsed_; enum_def.doc_comment = enum_comment; enum_def.is_union = is_union; enum_def.defined_namespace = namespaces_.back(); @@ -973,7 +973,7 @@ StructDef &Parser::StartStruct(const std::string &name) { if (!struct_def.predecl) Error("datatype already exists: " + name); struct_def.predecl = false; struct_def.name = name; - if (!files_being_parsed_.empty()) struct_def.file = files_being_parsed_.top(); + struct_def.file = files_being_parsed_; // Move this struct to the back of the vector just in case it was predeclared, // to preserve declaration order. *remove(structs_.vec.begin(), structs_.vec.end(), &struct_def) = &struct_def; @@ -1352,11 +1352,11 @@ Type Parser::ParseTypeFromProtoType() { bool Parser::Parse(const char *source, const char **include_paths, const char *source_filename) { + files_being_parsed_ = source_filename ? source_filename : ""; if (source_filename && included_files_.find(source_filename) == included_files_.end()) { included_files_[source_filename] = true; files_included_per_file_[source_filename] = std::set(); - files_being_parsed_.push(source_filename); } if (!include_paths) { static const char *current_directory[] = { "", nullptr }; @@ -1499,10 +1499,8 @@ bool Parser::Parse(const char *source, const char **include_paths, error_ += NumToString(line_) + ":0"; // gcc alike #endif error_ += ": error: " + msg; - if (source_filename) files_being_parsed_.pop(); return false; } - if (source_filename) files_being_parsed_.pop(); return true; }