File regcomp-memory-leak.patch of Package glibc.openSUSE_13.2_Update

2014-06-20  Andreas Schwab  <schwab@linux-m68k.org>

	[BZ #17069]
	* posix/regcomp.c (parse_reg_exp): Deallocate partially
	constructed tree before returning error.
	* posix/bug-regexp36.c: Expand test case.

2014-06-19  Andreas Schwab  <schwab@linux-m68k.org>

	[BZ #17069]
	* posix/regcomp.c (parse_expression): Deallocate partially
	constructed tree before returning error.
	* posix/Makefile.c (tests): Add bug-regex36.
	(generated): Add bug-regex36.mtrace.
	(tests-special): Add $(objpfx)bug-regex36-mem.out
	(bug-regex36-ENV): New variable.
	($(objpfx)bug-regex36-mem.out): New rule.
	* posix/bug-regex36.c: New file.

Index: glibc-2.19/posix/Makefile
===================================================================
--- glibc-2.19.orig/posix/Makefile
+++ glibc-2.19/posix/Makefile
@@ -86,7 +86,7 @@ tests		:= tstgetopt testfnm runtests run
 		   tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
 		   bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
 		   bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
-		   tst-pathconf tst-getaddrinfo4 \
+		   tst-pathconf tst-getaddrinfo4 bug-regex36 \
 		   tst-fnmatch3
 xtests		:= bug-ga2
 ifeq (yes,$(build-shared))
@@ -111,7 +111,7 @@ generated := $(addprefix wordexp-test-re
 	     tst-pcre-mem tst-pcre.mtrace tst-boost-mem tst-boost.mtrace \
 	     bug-ga2.mtrace bug-ga2-mem bug-glob2.mtrace bug-glob2-mem \
 	     tst-vfork3-mem tst-vfork3.mtrace getconf.speclist \
-	     tst-fnmatch-mem tst-fnmatch.mtrace
+	     tst-fnmatch-mem tst-fnmatch.mtrace bug-regex36.mtrace
 
 include ../Rules
 
@@ -261,6 +261,12 @@ bug-regex31-ENV = MALLOC_TRACE=$(objpfx)
 $(objpfx)bug-regex31-mem: $(objpfx)bug-regex31.out
 	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex31.mtrace > $@
 
+bug-regex36-ENV = MALLOC_TRACE=$(objpfx)bug-regex36.mtrace
+
+$(objpfx)bug-regex36-mem.out: $(objpfx)bug-regex36.out
+	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex36.mtrace > $@; \
+	$(evaluate-test)
+
 tst-vfork3-ENV = MALLOC_TRACE=$(objpfx)tst-vfork3.mtrace
 
 $(objpfx)tst-vfork3-mem: $(objpfx)tst-vfork3.out
Index: glibc-2.19/posix/bug-regex36.c
===================================================================
--- /dev/null
+++ glibc-2.19/posix/bug-regex36.c
@@ -0,0 +1,29 @@
+/* Test regcomp not leaking memory on parse errors
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <mcheck.h>
+#include <regex.h>
+
+int
+main (int argc, char **argv)
+{
+  regex_t r;
+  mtrace ();
+  regcomp (&r, "[a]\\|[a]\\{-2,}", 0);
+  regfree (&r);
+}
Index: glibc-2.19/posix/regcomp.c
===================================================================
--- glibc-2.19.orig/posix/regcomp.c
+++ glibc-2.19/posix/regcomp.c
@@ -2154,7 +2154,11 @@ parse_reg_exp (re_string_t *regexp, rege
 	{
 	  branch = parse_branch (regexp, preg, token, syntax, nest, err);
 	  if (BE (*err != REG_NOERROR && branch == NULL, 0))
-	    return NULL;
+	    {
+	      if (tree != NULL)
+		postorder (tree, free_tree, NULL);
+	      return NULL;
+	    }
 	}
       else
 	branch = NULL;
@@ -2415,14 +2419,21 @@ parse_expression (re_string_t *regexp, r
   while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
 	 || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
     {
-      tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-	return NULL;
+      bin_tree_t *dup_tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
+      if (BE (*err != REG_NOERROR && dup_tree == NULL, 0))
+	{
+	  if (tree != NULL)
+	    postorder (tree, free_tree, NULL);
+	  return NULL;
+	}
+      tree = dup_tree;
       /* In BRE consecutive duplications are not allowed.  */
       if ((syntax & RE_CONTEXT_INVALID_DUP)
 	  && (token->type == OP_DUP_ASTERISK
 	      || token->type == OP_OPEN_DUP_NUM))
 	{
+	  if (tree != NULL)
+	    postorder (tree, free_tree, NULL);
 	  *err = REG_BADRPT;
 	  return NULL;
 	}
openSUSE Build Service is sponsored by