From f29febdc8697b7e3f41012293a7a53ea18ab2da3 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Fri, 3 Sep 2021 10:30:40 +0200 Subject: [PATCH] patterns: Fix unions causing crashes on cleanup --- .../include/hex/lang/pattern_data.hpp | 1 + plugins/libimhex/source/lang/evaluator.cpp | 4 +-- plugins/libimhex/source/lang/parser.cpp | 26 +++++-------------- 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/plugins/libimhex/include/hex/lang/pattern_data.hpp b/plugins/libimhex/include/hex/lang/pattern_data.hpp index c4d6a1336..36141a2d3 100644 --- a/plugins/libimhex/include/hex/lang/pattern_data.hpp +++ b/plugins/libimhex/include/hex/lang/pattern_data.hpp @@ -858,6 +858,7 @@ namespace hex::lang { } void setMembers(const std::vector & members) { + this->m_members.clear(); for (auto &member : members) { if (member == nullptr) continue; diff --git a/plugins/libimhex/source/lang/evaluator.cpp b/plugins/libimhex/source/lang/evaluator.cpp index e437852f3..21cf1dd73 100644 --- a/plugins/libimhex/source/lang/evaluator.cpp +++ b/plugins/libimhex/source/lang/evaluator.cpp @@ -771,8 +771,8 @@ namespace hex::lang { auto startOffset = this->m_currOffset; for (auto &member : node->getMembers()) { this->evaluateMember(member, memberPatterns, true); - structPattern->setMembers(memberPatterns); } + structPattern->setMembers(memberPatterns); structPattern->setSize(this->m_currOffset - startOffset); this->m_currRecursionDepth--; @@ -801,8 +801,8 @@ namespace hex::lang { for (auto &member : node->getMembers()) { this->evaluateMember(member, memberPatterns, false); - unionPattern->setMembers(memberPatterns); } + unionPattern->setMembers(memberPatterns); this->m_currRecursionDepth--; diff --git a/plugins/libimhex/source/lang/parser.cpp b/plugins/libimhex/source/lang/parser.cpp index 9ac137e55..8c25be33e 100644 --- a/plugins/libimhex/source/lang/parser.cpp +++ b/plugins/libimhex/source/lang/parser.cpp @@ -667,19 +667,15 @@ namespace hex::lang { variables.push_back(new ASTNodeVariableDecl(getValue(-1), type->clone())); } while (MATCHES(sequence(SEPARATOR_COMMA, IDENTIFIER))); - delete type; - variableCleanup.release(); return new ASTNodeMultiVariableDecl(variables); } else - return new ASTNodeVariableDecl(getValue(-1), type); + return new ASTNodeVariableDecl(getValue(-1), type->clone()); } // (parseType) Identifier[(parseMathematicalExpression)] ASTNode* Parser::parseMemberArrayVariable(ASTNodeTypeDecl *type) { - if (type == nullptr) throwParseError("invalid type used in variable declaration", -1); - auto name = getValue(-2); ASTNode *size = nullptr; @@ -697,7 +693,7 @@ namespace hex::lang { sizeCleanup.release(); - return new ASTNodeArrayVariableDecl(name, type, size); + return new ASTNodeArrayVariableDecl(name, type->clone(), size); } // (parseType) *Identifier : (parseType) @@ -713,7 +709,7 @@ namespace hex::lang { throwParseError("invalid type used for pointer size", -1); } - return new ASTNodePointerVariableDecl(name, type, sizeType); + return new ASTNodePointerVariableDecl(name, type->clone(), sizeType); } // [(parsePadding)|(parseMemberVariable)|(parseMemberArrayVariable)|(parseMemberPointerVariable)] @@ -725,6 +721,7 @@ namespace hex::lang { // Some kind of variable definition auto type = parseType(); + ON_SCOPE_EXIT { delete type; }; if (MATCHES(sequence(IDENTIFIER, SEPARATOR_SQUAREBRACKETOPEN)) && sequence(SEPARATOR_SQUAREBRACKETOPEN)) member = parseMemberArrayVariable(type); @@ -759,9 +756,6 @@ namespace hex::lang { const auto &typeName = getValue(-2); auto structGuard = SCOPE_GUARD { delete structNode; }; - if (this->m_types.contains(typeName)) - throwParseError(hex::format("redefinition of type '{}'", typeName)); - while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { structNode->addMember(parseMember()); } @@ -777,9 +771,6 @@ namespace hex::lang { const auto &typeName = getValue(-2); auto unionGuard = SCOPE_GUARD { delete unionNode; }; - if (this->m_types.contains(typeName)) - throwParseError(hex::format("redefinition of type '{}'", typeName)); - while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { unionNode->addMember(parseMember()); } @@ -799,9 +790,6 @@ namespace hex::lang { const auto enumNode = new ASTNodeEnum(underlyingType); auto enumGuard = SCOPE_GUARD { delete enumNode; }; - if (this->m_types.contains(typeName)) - throwParseError(hex::format("redefinition of type '{}'", typeName)); - if (!MATCHES(sequence(SEPARATOR_CURLYBRACKETOPEN))) throwParseError("expected '{' after enum definition", -1); @@ -849,9 +837,6 @@ namespace hex::lang { const auto bitfieldNode = new ASTNodeBitfield(); auto enumGuard = SCOPE_GUARD { delete bitfieldNode; }; - if (this->m_types.contains(typeName)) - throwParseError(hex::format("redefinition of type '{}'", typeName)); - while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { if (MATCHES(sequence(IDENTIFIER, OPERATOR_INHERIT))) { auto name = getValue(-2); @@ -1024,6 +1009,9 @@ namespace hex::lang { if (auto typeDecl = dynamic_cast(statement); typeDecl != nullptr) { auto typeName = getNamespacePrefixedName(typeDecl->getName().data()); + if (this->m_types.contains(typeName)) + throwParseError(hex::format("redefinition of type '{}'", typeName)); + typeDecl->setName(typeName); this->m_types.insert({ typeName, typeDecl }); }