summary refs log tree commit diff
path: root/posix
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2002-11-06 08:34:35 +0000
committerUlrich Drepper <drepper@redhat.com>2002-11-06 08:34:35 +0000
commit71ccd3308c2ea1a9d2790f00d36c38e245651825 (patch)
tree8a7dc768275ea1b2823775cb71fc227d9decf52f /posix
parentd97426b7d765a78b102e3e70b13c80d76095e108 (diff)
downloadglibc-71ccd3308c2ea1a9d2790f00d36c38e245651825.tar.gz
glibc-71ccd3308c2ea1a9d2790f00d36c38e245651825.tar.xz
glibc-71ccd3308c2ea1a9d2790f00d36c38e245651825.zip
Update.
2002-11-06  Ulrich Drepper  <drepper@redhat.com>

	* posix/regcomp.c (regcomp): __re_compile_fastmap can never fail.
	If re_compile_internal failed free fastmap buffer.
	(free_dfa_content): Broken out of regfree function.  Frees all dfa
	related data.
	(regfree): Add free_dfa_content.
	(re_compile_internal): If any of the called functions fails free
	all dfa related memory.
Diffstat (limited to 'posix')
-rw-r--r--posix/regcomp.c145
1 files changed, 78 insertions, 67 deletions
diff --git a/posix/regcomp.c b/posix/regcomp.c
index b4f273a6ce..4655329267 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -499,16 +499,14 @@ regcomp (preg, pattern, cflags)
 
   /* We have already checked preg->fastmap != NULL.  */
   if (BE (ret == REG_NOERROR, 1))
+    /* Compute the fastmap now, since regexec cannot modify the pattern
+       buffer.  This function nevers fails in this implementation.  */
+    (void) __re_compile_fastmap (preg);
+  else
     {
-      /* Compute the fastmap now, since regexec cannot modify the pattern
-	 buffer.  */
-      if (BE (re_compile_fastmap (preg) == -2, 0))
-	{
-	  /* Some error occurred while computing the fastmap, just forget
-	     about it.  */
-	  re_free (preg->fastmap);
-	  preg->fastmap = NULL;
-	}
+      /* Some error occurred while compiling the expression.  */
+      re_free (preg->fastmap);
+      preg->fastmap = NULL;
     }
 
   return (int) ret;
@@ -564,71 +562,80 @@ regerror (errcode, preg, errbuf, errbuf_size)
 weak_alias (__regerror, regerror)
 #endif
 
-/* Free dynamically allocated space used by PREG.  */
 
-void
-regfree (preg)
-    regex_t *preg;
+static void
+free_dfa_content (re_dfa_t *dfa)
 {
   int i, j;
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  if (BE (dfa != NULL, 1))
-    {
-      re_free (dfa->subexps);
 
-      for (i = 0; i < dfa->nodes_len; ++i)
-        {
-          re_token_t *node = dfa->nodes + i;
+  re_free (dfa->subexps);
+
+  for (i = 0; i < dfa->nodes_len; ++i)
+    {
+      re_token_t *node = dfa->nodes + i;
 #ifdef RE_ENABLE_I18N
-          if (node->type == COMPLEX_BRACKET && node->duplicated == 0)
-            free_charset (node->opr.mbcset);
-          else
+      if (node->type == COMPLEX_BRACKET && node->duplicated == 0)
+	free_charset (node->opr.mbcset);
+      else
 #endif /* RE_ENABLE_I18N */
-          if (node->type == SIMPLE_BRACKET && node->duplicated == 0)
-            re_free (node->opr.sbcset);
-        }
-      re_free (dfa->nexts);
-      for (i = 0; i < dfa->nodes_len; ++i)
-        {
-          if (dfa->eclosures != NULL)
-            re_node_set_free (dfa->eclosures + i);
-          if (dfa->inveclosures != NULL)
-            re_node_set_free (dfa->inveclosures + i);
-          if (dfa->edests != NULL)
-            re_node_set_free (dfa->edests + i);
-        }
-      re_free (dfa->edests);
-      re_free (dfa->eclosures);
-      re_free (dfa->inveclosures);
-      re_free (dfa->nodes);
+	if (node->type == SIMPLE_BRACKET && node->duplicated == 0)
+	  re_free (node->opr.sbcset);
+    }
+  re_free (dfa->nexts);
+  for (i = 0; i < dfa->nodes_len; ++i)
+    {
+      if (dfa->eclosures != NULL)
+	re_node_set_free (dfa->eclosures + i);
+      if (dfa->inveclosures != NULL)
+	re_node_set_free (dfa->inveclosures + i);
+      if (dfa->edests != NULL)
+	re_node_set_free (dfa->edests + i);
+    }
+  re_free (dfa->edests);
+  re_free (dfa->eclosures);
+  re_free (dfa->inveclosures);
+  re_free (dfa->nodes);
 
-      for (i = 0; i <= dfa->state_hash_mask; ++i)
-        {
-          struct re_state_table_entry *entry = dfa->state_table + i;
-          for (j = 0; j < entry->num; ++j)
-            {
-              re_dfastate_t *state = entry->array[j];
-              if (state->entrance_nodes != &state->nodes)
-                {
-                  re_node_set_free (state->entrance_nodes);
-                  re_free (state->entrance_nodes);
-                }
-              re_node_set_free (&state->nodes);
-              re_free (state->trtable);
-              re_free (state->trtable_search);
-              re_free (state);
-            }
-          re_free (entry->array);
-        }
-      re_free (dfa->state_table);
+  for (i = 0; i <= dfa->state_hash_mask; ++i)
+    {
+      struct re_state_table_entry *entry = dfa->state_table + i;
+      for (j = 0; j < entry->num; ++j)
+	{
+	  re_dfastate_t *state = entry->array[j];
+	  if (state->entrance_nodes != &state->nodes)
+	    {
+	      re_node_set_free (state->entrance_nodes);
+	      re_free (state->entrance_nodes);
+	    }
+	  re_node_set_free (&state->nodes);
+	  re_free (state->trtable);
+	  re_free (state->trtable_search);
+	  re_free (state);
+	}
+      re_free (entry->array);
+    }
+  re_free (dfa->state_table);
 
-      if (dfa->word_char != NULL)
-        re_free (dfa->word_char);
+  if (dfa->word_char != NULL)
+    re_free (dfa->word_char);
 #ifdef DEBUG
-      re_free (dfa->re_str);
+  re_free (dfa->re_str);
 #endif
-      re_free (dfa);
-    }
+
+  re_free (dfa);
+}
+
+
+/* Free dynamically allocated space used by PREG.  */
+
+void
+regfree (preg)
+    regex_t *preg;
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  if (BE (dfa != NULL, 1))
+    free_dfa_content (dfa);
+
   re_free (preg->fastmap);
 }
 #ifdef _LIBC
@@ -778,14 +785,18 @@ re_compile_internal (preg, pattern, length, syntax)
 
   /* Then create the initial state of the dfa.  */
   err = create_initial_state (dfa);
-  if (BE (err != REG_NOERROR, 0))
-    goto re_compile_internal_free_return;
 
- re_compile_internal_free_return:
   /* Release work areas.  */
   free_workarea_compile (preg);
   re_string_destruct (&regexp);
 
+  if (BE (err != REG_NOERROR, 0))
+    {
+    re_compile_internal_free_return:
+      free_dfa_content (dfa);
+      preg->buffer = NULL;
+    }
+
   return err;
 }