未验证 提交 322f0fc8 编写于 作者: A arhag 提交者: GitHub

Merge pull request #3644 from EOSIO/gh#3635-abi-gen-segfault

Gh#3635 abi gen segfault
......@@ -124,7 +124,7 @@ bool abi_generator::inspect_type_methods_for_actions(const Decl* decl) { try {
qt.setLocalFastQualifiers(0);
string field_name = p->getNameAsString();
string field_type_name = add_type(qt);
string field_type_name = add_type(qt, 0);
field_def struct_field{field_name, field_type_name};
ABI_ASSERT(is_builtin_type(get_vector_element_type(struct_field.type))
......@@ -236,7 +236,7 @@ void abi_generator::handle_decl(const Decl* decl) { try {
auto qt = action_decl->getTypeForDecl()->getCanonicalTypeInternal();
auto type_name = add_struct(qt);
auto type_name = add_struct(qt, "", 0);
ABI_ASSERT(!is_builtin_type(type_name),
"A built-in type with the same name exists, try using another name: ${type_name}", ("type_name",type_name));
......@@ -259,7 +259,7 @@ void abi_generator::handle_decl(const Decl* decl) { try {
ABI_ASSERT(table_decl != nullptr);
auto qt = table_decl->getTypeForDecl()->getCanonicalTypeInternal();
auto type_name = add_struct(qt);
auto type_name = add_struct(qt, "", 0);
ABI_ASSERT(!is_builtin_type(type_name),
"A built-in type with the same name exists, try using another name: ${type_name}", ("type_name",type_name));
......@@ -433,7 +433,11 @@ const struct_def* abi_generator::find_struct(const type_name& name) {
type_name abi_generator::resolve_type(const type_name& type){
const auto* td = find_type(type);
if( td ) {
return resolve_type(td->type);
for( auto i = output->types.size(); i > 0; --i ) { // avoid infinite recursion
const type_name& t = td->type;
td = find_type(t);
if( td == nullptr ) return t;
}
}
return type;
}
......@@ -505,7 +509,9 @@ string abi_generator::get_type_name(const clang::QualType& qt, bool with_namespa
return name;
}
clang::QualType abi_generator::add_typedef(const clang::QualType& tqt) {
clang::QualType abi_generator::add_typedef(const clang::QualType& tqt, size_t recursion_depth) {
ABI_ASSERT( ++recursion_depth < max_recursion_depth, "recursive definition, max_recursion_depth" );
clang::QualType qt(get_named_type_if_elaborated(tqt));
......@@ -516,7 +522,7 @@ clang::QualType abi_generator::add_typedef(const clang::QualType& tqt) {
auto underlying_type_name = get_type_name(underlying_type);
if ( is_vector(underlying_type) ) {
underlying_type_name = add_vector(underlying_type);
underlying_type_name = add_vector(underlying_type, recursion_depth);
}
type_def abi_typedef;
......@@ -531,7 +537,7 @@ clang::QualType abi_generator::add_typedef(const clang::QualType& tqt) {
}
if( is_typedef(underlying_type) && !is_builtin_type(get_type_name(underlying_type)) )
return add_typedef(underlying_type);
return add_typedef(underlying_type, recursion_depth);
return underlying_type;
}
......@@ -568,14 +574,16 @@ const clang::RecordDecl::field_range abi_generator::get_struct_fields(const clan
return record_type->getDecl()->fields();
}
string abi_generator::add_vector(const clang::QualType& vqt) {
string abi_generator::add_vector(const clang::QualType& vqt, size_t recursion_depth) {
ABI_ASSERT( ++recursion_depth < max_recursion_depth, "recursive definition, max_recursion_depth" );
clang::QualType qt(get_named_type_if_elaborated(vqt));
auto vector_element_type = get_vector_element_type(qt);
ABI_ASSERT(!is_vector(vector_element_type), "Only one-dimensional arrays are supported");
add_type(vector_element_type);
add_type(vector_element_type, recursion_depth);
auto vector_element_type_str = translate_type(get_type_name(vector_element_type));
vector_element_type_str += "[]";
......@@ -583,7 +591,9 @@ string abi_generator::add_vector(const clang::QualType& vqt) {
return vector_element_type_str;
}
string abi_generator::add_type(const clang::QualType& tqt) {
string abi_generator::add_type(const clang::QualType& tqt, size_t recursion_depth) {
ABI_ASSERT( ++recursion_depth < max_recursion_depth, "recursive definition, max_recursion_depth" );
clang::QualType qt(get_named_type_if_elaborated(tqt));
......@@ -596,7 +606,7 @@ string abi_generator::add_type(const clang::QualType& tqt) {
}
if( is_typedef(qt) ) {
qt = add_typedef(qt);
qt = add_typedef(qt, recursion_depth);
if( is_builtin_type(translate_type(get_type_name(qt))) ) {
return type_name;
}
......@@ -604,12 +614,12 @@ string abi_generator::add_type(const clang::QualType& tqt) {
}
if( is_vector(qt) ) {
auto vector_type_name = add_vector(qt);
auto vector_type_name = add_vector(qt, recursion_depth);
return is_type_def ? type_name : vector_type_name;
}
if( is_struct(qt) ) {
return add_struct(qt, full_type_name);
return add_struct(qt, full_type_name, recursion_depth);
}
ABI_ASSERT(false, "types can only be: vector, struct, class or a built-in type. (${type}) ", ("type",get_type_name(qt)));
......@@ -623,7 +633,9 @@ clang::QualType abi_generator::get_named_type_if_elaborated(const clang::QualTyp
return qt;
}
string abi_generator::add_struct(const clang::QualType& sqt, string full_name) {
string abi_generator::add_struct(const clang::QualType& sqt, string full_name, size_t recursion_depth) {
ABI_ASSERT( ++recursion_depth < max_recursion_depth, "recursive definition, max_recursion_depth" );
clang::QualType qt(get_named_type_if_elaborated(sqt));
......@@ -653,7 +665,7 @@ string abi_generator::add_struct(const clang::QualType& sqt, string full_name) {
const auto* record_type = base_qt->getAs<clang::RecordType>();
if( record_type && is_struct(base_qt) && !record_type->getDecl()->field_empty() ) {
ABI_ASSERT(total_bases == 0, "Multiple inheritance not supported - ${type}", ("type",full_name));
base_name = add_type(base_qt);
base_name = add_type(base_qt, recursion_depth);
++total_bases;
}
++bitr;
......@@ -664,7 +676,7 @@ string abi_generator::add_struct(const clang::QualType& sqt, string full_name) {
clang::QualType qt = field->getType();
string field_name = field->getNameAsString();
string field_type_name = add_type(qt);
string field_type_name = add_type(qt, recursion_depth);
field_def struct_field{field_name, field_type_name};
ABI_ASSERT(is_builtin_type(get_vector_element_type(struct_field.type))
......
......@@ -159,7 +159,8 @@ namespace eosio {
* @brief Generates eosio::abi_def struct handling events from ASTConsumer
*/
class abi_generator {
private:
private:
static constexpr size_t max_recursion_depth = 25; // arbitrary depth to prevent infinite recursion
bool verbose;
int optimizations;
abi_def* output;
......@@ -171,6 +172,7 @@ namespace eosio {
string target_contract;
vector<string> target_actions;
ricardian_contracts rc;
public:
enum optimization {
......@@ -178,7 +180,8 @@ namespace eosio {
};
abi_generator()
:optimizations(0)
: verbose(false)
, optimizations(0)
, output(nullptr)
, compiler_instance(nullptr)
, ast_context(nullptr)
......@@ -283,17 +286,17 @@ namespace eosio {
string decl_to_string(clang::Decl* d);
bool is_typedef(const clang::QualType& qt);
QualType add_typedef(const clang::QualType& qt);
QualType add_typedef(const clang::QualType& qt, size_t recursion_depth);
bool is_vector(const clang::QualType& qt);
bool is_vector(const string& type_name);
string add_vector(const clang::QualType& qt);
string add_vector(const clang::QualType& qt, size_t recursion_depth);
bool is_struct(const clang::QualType& qt);
string add_struct(const clang::QualType& qt, string full_type_name="");
string add_struct(const clang::QualType& qt, string full_type_name, size_t recursion_depth);
string get_type_name(const clang::QualType& qt, bool no_namespace);
string add_type(const clang::QualType& tqt);
string add_type(const clang::QualType& tqt, size_t recursion_depth);
bool is_elaborated(const clang::QualType& qt);
bool is_struct_specialization(const clang::QualType& qt);
......
......@@ -3297,6 +3297,31 @@ BOOST_AUTO_TEST_CASE(abi_type_redefine_to_name)
} FC_LOG_AND_RETHROW() }
BOOST_AUTO_TEST_CASE(abi_type_nested_in_vector)
{ try {
// inifinite loop in types
const char* repeat_abi = R"=====(
{
"types": [],
"structs": [{
"name": "store_t",
"base": "",
"fields": [{
"name": "id",
"type": "uint64"
},{
"name": "childs",
"type": "store_t[]"
}],
"actions": [],
"tables": []
}
)=====";
BOOST_CHECK_THROW( abi_serializer abis(fc::json::from_string(repeat_abi).as<abi_def>()), fc::exception );
} FC_LOG_AND_RETHROW() }
BOOST_AUTO_TEST_CASE(abi_account_name_in_eosio_abi)
{ try {
// inifinite loop in types
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册