Core: fix possible memory leaks when using parser

This commit is contained in:
wmayer
2024-04-26 21:42:34 +02:00
parent f2647448ec
commit 88893f7524
2 changed files with 48 additions and 9 deletions

View File

@@ -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<std::tuple<int, int, std::string> > tokenize(const std::string &str)
{
ExpressionParser::YY_BUFFER_STATE buf = ExpressionParser_scan_string(str.c_str());
ExpressionParser::StringBufferCleaner cleaner(buf);
std::vector<std::tuple<int, int, std::string> > result;
int token;
@@ -3722,7 +3744,6 @@ std::vector<std::tuple<int, int, std::string> > 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<int, int> 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);
}