fixed: lexer memory leak due to strdup

This commit is contained in:
Sven Vogel 2024-06-05 15:03:23 +02:00
parent 2de4f7b460
commit 1e2f3c263a
4 changed files with 37 additions and 5 deletions

View File

@ -148,6 +148,8 @@ static void build_target(ModuleFileStack *unit, const TargetConfig *target) {
AST_delete_node(ast); AST_delete_node(ast);
lex_purge_str_cache();
print_file_statistics(file); print_file_statistics(file);
} }

View File

@ -89,20 +89,20 @@
"lineno" {DEBUG("\"%s\" tokenized with \'FunLineno\'", yytext); return(FunLineno);}; "lineno" {DEBUG("\"%s\" tokenized with \'FunLineno\'", yytext); return(FunLineno);};
"extsupport" {DEBUG("\"%s\" tokenized with \'FunExtsupport\'", yytext); return(FunExtsupport);}; "extsupport" {DEBUG("\"%s\" tokenized with \'FunExtsupport\'", yytext); return(FunExtsupport);};
[0-9]+ {DEBUG("\"%s\" tokenized with \'ValInt\'", yytext); yylval.string = strdup(yytext); return(ValInt); }; [0-9]+ {DEBUG("\"%s\" tokenized with \'ValInt\'", yytext); yylval.string = lex_cached_strdup(yytext); return(ValInt); };
[0-9]*\.[0-9]+ {DEBUG("\"%s\" tokenized with \'ValFloat\'", yytext); yylval.string = strdup(yytext); return(ValFloat);}; [0-9]*\.[0-9]+ {DEBUG("\"%s\" tokenized with \'ValFloat\'", yytext); yylval.string = lex_cached_strdup(yytext); return(ValFloat);};
[a-zA-Z_0-9]+ {DEBUG("\"%s\" tokenized with \'Ident\'", yytext); yylval.string = strdup(yytext); return(Ident); }; [a-zA-Z_0-9]+ {DEBUG("\"%s\" tokenized with \'Ident\'", yytext); yylval.string = lex_cached_strdup(yytext); return(Ident); };
\"([^\"\n])*\" { \"([^\"\n])*\" {
yytext = yytext +1; yytext = yytext +1;
yytext[yyleng - 2] = 0; yytext[yyleng - 2] = 0;
DEBUG("\"%s\" tokenized with \'ValStr\'", yytext); yylval.string = strdup(yytext); return(ValStr);}; DEBUG("\"%s\" tokenized with \'ValStr\'", yytext); yylval.string = lex_cached_strdup(yytext); return(ValStr);};
\"\"\"[^\"]*\"\"\" { \"\"\"[^\"]*\"\"\" {
yytext = yytext +3; yytext = yytext +3;
yytext[yyleng - 4] = 0; yytext[yyleng - 4] = 0;
DEBUG("\"%s\" tokenized with \'ValMultistr\'", yytext); yylval.string = strdup(yytext); return(ValMultistr);}; DEBUG("\"%s\" tokenized with \'ValMultistr\'", yytext); yylval.string = lex_cached_strdup(yytext); return(ValMultistr);};
[ \r\t] { /* ignore whitespace */ }; [ \r\t] { /* ignore whitespace */ };
. { return yytext[0]; /* passthrough unknown token, let parser handle the error */ }; . { return yytext[0]; /* passthrough unknown token, let parser handle the error */ };
%% %%

View File

@ -2,6 +2,7 @@
#include <lex/util.h> #include <lex/util.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <glib.h>
// implementation based on: // implementation based on:
// https://github.com/sunxfancy/flex-bison-examples/blob/master/error-handling/ccalc.c // https://github.com/sunxfancy/flex-bison-examples/blob/master/error-handling/ccalc.c
@ -16,12 +17,37 @@ static int nTokenStart = 0;
static int nTokenLength = 0; static int nTokenLength = 0;
static int nTokenNextStart = 0; static int nTokenNextStart = 0;
static GArray* stringCache = NULL;
char* lex_cached_strdup(char* string) {
char* dup = strdup(string);
g_array_append_val(stringCache, dup);
return dup;
}
void lex_purge_str_cache() {
DEBUG("purging string cache...");
const guint count = stringCache->len;
for (guint i = 0; i < count; i++) {
free(((char**) stringCache->data)[i]);
}
g_array_remove_range(stringCache, 0, count);
}
static void lex_deinit(void) { static void lex_deinit(void) {
lex_purge_str_cache();
g_array_free(stringCache, TRUE);
free(buffer); free(buffer);
} }
void lex_init(void) { void lex_init(void) {
buffer = malloc(MAX_READ_BUFFER_SIZE); buffer = malloc(MAX_READ_BUFFER_SIZE);
stringCache = g_array_new(FALSE, FALSE, sizeof(char*));
atexit(lex_deinit); atexit(lex_deinit);
} }

View File

@ -18,6 +18,10 @@ void lex_init(void);
void lex_reset(void); void lex_reset(void);
char* lex_cached_strdup(char* string);
void lex_purge_str_cache();
/** /**
* @brief Begin counting a new token. This will fill the global struct yylloc. * @brief Begin counting a new token. This will fill the global struct yylloc.
* @param t the text of the token. Must be null terminated * @param t the text of the token. Must be null terminated