fix memory leak in regex parser (wrong free for compiled patterns)

Tue, 30 Jun 2026 11:55:30 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 30 Jun 2026 11:55:30 +0200
changeset 92
51270d470cda
parent 91
d34797fcf600
child 93
cd3013126129

fix memory leak in regex parser (wrong free for compiled patterns)

src/regex_parser.c file | annotate | diff | comparison | revisions
src/regex_parser.h file | annotate | diff | comparison | revisions
--- a/src/regex_parser.c	Tue Jun 30 11:32:22 2026 +0200
+++ b/src/regex_parser.c	Tue Jun 30 11:55:30 2026 +0200
@@ -47,9 +47,7 @@
 void regex_destcomppats(regex_parser_t* parser) {
   if (parser->compiled_patterns != NULL) {
     for (unsigned i = 0 ; i < parser->compiled_pattern_count ; i++) {
-      if (parser->compiled_patterns[i] != NULL) {
-        free(parser->compiled_patterns[i]);
-      }
+        regfree(parser->compiled_patterns + i);
     }
     free(parser->compiled_patterns);
     parser->compiled_patterns = NULL;
@@ -89,7 +87,7 @@
         parser->matched_counted++;
       }
 
-      err = regexec(parser->compiled_patterns[parser->pattern_match],
+      err = regexec(parser->compiled_patterns + parser->pattern_match,
           input, 1, &match, 0);
       if (err > 0 && err != REG_NOMATCH) {
         fprintf(stderr, "Regex-Error: 0x%08x", err);
@@ -110,7 +108,7 @@
       }
     } else {
       for (unsigned i = 0 ; i < parser->compiled_pattern_count - 1 ; i += 2) {
-        err = regexec(parser->compiled_patterns[i], input, 1, &match, 0);
+        err = regexec(parser->compiled_patterns + i, input, 1, &match, 0);
         if (err > 0 && err != REG_NOMATCH) {
           fprintf(stderr, "Regex-Error: 0x%08x", err);
         }
@@ -142,25 +140,21 @@
 }
 
 bool regex_compile_all(regex_parser_t* parser) {
-  bool success = true;
   size_t pcount = parser->pattern_list->count;
   if (pcount > 0) {
     regex_destcomppats(parser);
     parser->compiled_patterns = calloc(pcount, sizeof(regex_t));
-    parser->compiled_pattern_count = pcount;
 
-    regex_t* re;
-    for (unsigned i = 0 ; i < pcount ; i++) {
-      re = malloc(sizeof(regex_t));
-      if (regcomp(re, parser->pattern_list->items[i], REG_EXTENDED) == 0) {
-        parser->compiled_patterns[i] = re;
-      } else {
+    for (size_t i = 0 ; i < pcount ; i++) {
+      if (regcomp(parser->compiled_patterns + i,
+          parser->pattern_list->items[i], REG_EXTENDED) != 0) {
         fprintf(stderr, "Cannot compile pattern: %s\n",
             (parser->pattern_list->items[i]));
-        parser->compiled_patterns[i] = NULL;
-        success = false;
+        parser->compiled_pattern_count = i;
+        return false;
       }
     }
   }
-  return success;
+  parser->compiled_pattern_count = pcount;
+  return true;
 }
--- a/src/regex_parser.h	Tue Jun 30 11:32:22 2026 +0200
+++ b/src/regex_parser.h	Tue Jun 30 11:55:30 2026 +0200
@@ -41,7 +41,7 @@
 
 typedef struct {
   string_list_t* pattern_list; /* even entries: start ; odd entries: end */
-  regex_t** compiled_patterns;
+  regex_t* compiled_patterns;
   size_t compiled_pattern_count;
   unsigned int pattern_match; /* save position of end pattern to match -
                                  NULL when a start pattern shall match first */

mercurial