diff --git a/src/App/Expression.cpp b/src/App/Expression.cpp index 183d6ace68..a7dfe77fc1 100644 --- a/src/App/Expression.cpp +++ b/src/App/Expression.cpp @@ -3609,6 +3609,27 @@ int ExpressionParserlex(); #include "lex.ExpressionParser.c" #endif // DOXYGEN_SHOULD_SKIP_THIS +class StringBufferCleaner +{ +public: + explicit StringBufferCleaner(YY_BUFFER_STATE buffer) + : my_string_buffer {buffer} + {} + ~StringBufferCleaner() + { + // free the scan buffer + yy_delete_buffer(my_string_buffer); + } + + StringBufferCleaner(const StringBufferCleaner&) = delete; + StringBufferCleaner(StringBufferCleaner&&) = delete; + StringBufferCleaner& operator=(const StringBufferCleaner&) = delete; + StringBufferCleaner& operator=(StringBufferCleaner&&) = delete; + +private: + YY_BUFFER_STATE my_string_buffer; +}; + #if defined(__clang__) # pragma clang diagnostic pop #elif defined (__GNUC__) @@ -3710,6 +3731,7 @@ static void initParser(const App::DocumentObject *owner) std::vector > tokenize(const std::string &str) { ExpressionParser::YY_BUFFER_STATE buf = ExpressionParser_scan_string(str.c_str()); + ExpressionParser::StringBufferCleaner cleaner(buf); std::vector > result; int token; @@ -3722,7 +3744,6 @@ std::vector > tokenize(const std::string &str) // Ignore all exceptions } - ExpressionParser_delete_buffer(buf); return result; } @@ -3745,15 +3766,13 @@ Expression * App::ExpressionParser::parse(const App::DocumentObject *owner, cons { // parse from buffer ExpressionParser::YY_BUFFER_STATE my_string_buffer = ExpressionParser::ExpressionParser_scan_string (buffer); + ExpressionParser::StringBufferCleaner cleaner(my_string_buffer); initParser(owner); // run the parser int result = ExpressionParser::ExpressionParser_yyparse (); - // free the scan buffer - ExpressionParser::ExpressionParser_delete_buffer (my_string_buffer); - if (result != 0) throw ParserError("Failed to parse expression."); @@ -3772,15 +3791,13 @@ UnitExpression * ExpressionParser::parseUnit(const App::DocumentObject *owner, c { // parse from buffer ExpressionParser::YY_BUFFER_STATE my_string_buffer = ExpressionParser::ExpressionParser_scan_string (buffer); + ExpressionParser::StringBufferCleaner cleaner(my_string_buffer); initParser(owner); // run the parser int result = ExpressionParser::ExpressionParser_yyparse (); - // free the scan buffer - ExpressionParser::ExpressionParser_delete_buffer (my_string_buffer); - if (result != 0) throw ParserError("Failed to parse expression."); @@ -3823,9 +3840,9 @@ namespace { std::tuple getTokenAndStatus(const std::string & str) { ExpressionParser::YY_BUFFER_STATE buf = ExpressionParser::ExpressionParser_scan_string(str.c_str()); + ExpressionParser::StringBufferCleaner cleaner(buf); int token = ExpressionParser::ExpressionParserlex(); int status = ExpressionParser::ExpressionParserlex(); - ExpressionParser::ExpressionParser_delete_buffer(buf); return std::make_tuple(token, status); } diff --git a/src/Gui/SelectionFilter.cpp b/src/Gui/SelectionFilter.cpp index fb10eeece5..51f0f5c716 100644 --- a/src/Gui/SelectionFilter.cpp +++ b/src/Gui/SelectionFilter.cpp @@ -297,12 +297,35 @@ int SelectionFilterlex(); # pragma GCC diagnostic pop #endif #endif // DOXYGEN_SHOULD_SKIP_THIS + +class StringBufferCleaner +{ +public: + explicit StringBufferCleaner(YY_BUFFER_STATE buffer) + : my_string_buffer {buffer} + {} + ~StringBufferCleaner() + { + // free the scan buffer + yy_delete_buffer(my_string_buffer); + } + + StringBufferCleaner(const StringBufferCleaner&) = delete; + StringBufferCleaner(StringBufferCleaner&&) = delete; + StringBufferCleaner& operator=(const StringBufferCleaner&) = delete; + StringBufferCleaner& operator=(StringBufferCleaner&&) = delete; + +private: + YY_BUFFER_STATE my_string_buffer; +}; + } bool SelectionFilter::parse() { Errors = ""; SelectionParser::YY_BUFFER_STATE my_string_buffer = SelectionParser::SelectionFilter_scan_string (Filter.c_str()); + SelectionParser::StringBufferCleaner cleaner(my_string_buffer); // be aware that this parser is not reentrant! Don't use with Threats!!! assert(!ActFilter); ActFilter = this; @@ -310,7 +333,6 @@ bool SelectionFilter::parse() ActFilter = nullptr; Ast.reset(TopBlock); TopBlock = nullptr; - SelectionParser::SelectionFilter_delete_buffer (my_string_buffer); SelectionParser::StringFactory::instance()->clear(); if (Errors.empty()) {