Gui: fix memory leak in SelectionParser::yyparse()

This commit is contained in:
wmayer
2021-04-22 23:16:03 +02:00
parent b4823e8606
commit ef4f74aa94
6 changed files with 41 additions and 17 deletions

View File

@@ -363,6 +363,31 @@ int fileno(FILE *stream) {return _fileno(stream);}
namespace SelectionParser {
/*!
* \brief The StringFactory class
* Helper class to record the created strings used by the parser.
*/
class StringFactory {
std::list<std::unique_ptr<std::string>> data;
std::size_t max_elements = 20;
public:
static StringFactory* instance() {
static StringFactory* inst = new StringFactory();
return inst;
}
std::string* make(const std::string& str) {
data.push_back(std::make_unique<std::string>(str));
return data.back().get();
}
static std::string* New(const std::string& str) {
return StringFactory::instance()->make(str);
}
void clear() {
if (data.size() > max_elements)
data.clear();
}
};
// show the parser the lexer method
#define yylex SelectionFilterlex
int SelectionFilterlex(void);
@@ -401,6 +426,7 @@ bool SelectionFilter::parse(void)
Ast.reset(TopBlock);
TopBlock = 0;
SelectionParser::SelectionFilter_delete_buffer (my_string_buffer);
SelectionParser::StringFactory::instance()->clear();
if (Errors.empty()) {
return true;

View File

@@ -207,10 +207,8 @@ struct Node_Object
:Slice(slc)
{
ObjectType = Base::Type::fromName(type->c_str());
delete (type);
if(subname){
if (subname) {
SubName = *subname;
delete subname;
}
}
~Node_Object(){

View File

@@ -58,7 +58,7 @@
"::" return TNAMESPACE;
[a-zA-Z_][a-zA-Z0-9_]* {
yylval.string = new std::string(yytext);
yylval.string = StringFactory::New(yytext);
return TIDENTIFIER;
}
[0-9]+ {

View File

@@ -1345,7 +1345,7 @@ yyreduce:
/* Line 1464 of yacc.c */
#line 40 "SelectionFilter.y"
{ (yyval.string) = new std::string(*(yyvsp[(2) - (4)].string) + "::" + *(yyvsp[(4) - (4)].string)) ;}
{ (yyval.string) = StringFactory::New(*(yyvsp[(2) - (4)].string) + "::" + *(yyvsp[(4) - (4)].string)) ;}
break;
case 4:

View File

@@ -55,25 +55,25 @@
type : TSELECT TIDENTIFIER { $$ = $2 }
| TSELECT TIDENTIFIER TNAMESPACE TIDENTIFIER { $$ = new std::string(*$2 + "::" + *$4) }
type : TSELECT TIDENTIFIER { $$ = $2; }
| TSELECT TIDENTIFIER TNAMESPACE TIDENTIFIER { $$ = StringFactory::New(*$2 + "::" + *$4); }
subname : { $$ = 0 }
| TSUB TIDENTIFIER { $$ = $2 }
subname : { $$ = 0; }
| TSUB TIDENTIFIER { $$ = $2; }
count : { $$ = 0 }
| TCOUNT TNUMBER TSLICE TNUMBER { $$ = new Node_Slice($2,$4) }
| TCOUNT TNUMBER TSLICE { $$ = new Node_Slice($2) }
| TCOUNT TNUMBER { $$ = new Node_Slice($2,$2) }
count : { $$ = 0; }
| TCOUNT TNUMBER TSLICE TNUMBER { $$ = new Node_Slice($2,$4); }
| TCOUNT TNUMBER TSLICE { $$ = new Node_Slice($2); }
| TCOUNT TNUMBER { $$ = new Node_Slice($2,$2); }
matchline : type subname count { $$ = new Node_Object($1,$2,$3) }
matchline : type subname count { $$ = new Node_Object($1,$2,$3); }
matchlines : matchline { $$ = new Node_Block($1); }
| matchlines matchline { $$ = $1 ; $$->Objects.emplace_back($2); }
block : matchlines { $$ = $1 }
block : matchlines { $$ = $1; }
filter: block { TopBlock = $1 }
filter: block { TopBlock = $1; }
;

View File

@@ -856,7 +856,7 @@ case 8:
YY_RULE_SETUP
#line 41 "SelectionFilter.l"
{
yylval.string = new std::string(SelectionFiltertext);
yylval.string = StringFactory::New(SelectionFiltertext);
return TIDENTIFIER;
}
YY_BREAK