[10/18] posix: Remove alloca usage for GLOB_BRACE on glob

Submitted by Adhemerval Zanella on Aug. 11, 2017, 2:50 p.m.

Details

Message ID 1502463044-4042-11-git-send-email-adhemerval.zanella@linaro.org
State New
Headers show

Commit Message

Adhemerval Zanella Aug. 11, 2017, 2:50 p.m.
GNU GLOB_BRACE internal implementation constructs a new expression and
calls glob recursively.  It then requires a possible large temporary
buffer place the new pattern.

This patch removes the alloca/malloc usage and replaces it with
char_array.

Checked on x86_64-linux-gnu.

	* posix/glob.c (glob): Remove alloca usage for onealt.
---
 posix/glob.c | 63 ++++++++++++++++++++++++++++++------------------------------
 1 file changed, 32 insertions(+), 31 deletions(-)

Patch hide | download patch | download mbox

diff --git a/posix/glob.c b/posix/glob.c
index 858b709..1892f48 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -398,44 +398,32 @@  glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
 	  /* Allocate working buffer large enough for our work.  Note that
 	     we have at least an opening and closing brace.  */
 	  size_t firstc;
-	  char *alt_start;
 	  const char *p;
 	  const char *next;
 	  const char *rest;
 	  size_t rest_len;
-	  char *onealt;
-	  size_t pattern_len = strlen (pattern) - 1;
-	  int alloca_onealt = glob_use_alloca (alloca_used, pattern_len);
-	  if (alloca_onealt)
-	    onealt = alloca_account (pattern_len, alloca_used);
-	  else
+	  struct char_array onealt;
+
+	  /* We know the prefix for all sub-patterns.  */
+	  ptrdiff_t onealtlen = begin - pattern;
+	  if (!char_array_init_str_size (&onealt, pattern, onealtlen))
 	    {
-	      onealt = malloc (pattern_len);
-	      if (onealt == NULL)
+	      if (!(flags & GLOB_APPEND))
 		{
-		  if (!(flags & GLOB_APPEND))
-		    {
-		      pglob->gl_pathc = 0;
-		      pglob->gl_pathv = NULL;
-		    }
-		  goto err_nospace;
+		  pglob->gl_pathc = 0;
+		  pglob->gl_pathv = NULL;
 		}
+	      goto err_nospace;
 	    }
 
-	  /* We know the prefix for all sub-patterns.  */
-	  alt_start = mempcpy (onealt, pattern, begin - pattern);
-
 	  /* Find the first sub-pattern and at the same time find the
 	     rest after the closing brace.  */
 	  next = next_brace_sub (begin + 1, flags);
 	  if (next == NULL)
 	    {
 	      /* It is an invalid expression.  */
-	    illegal_brace:
-	      if (__glibc_unlikely (!alloca_onealt))
-		free (onealt);
-	      char_array_free (&dirname);
-	      return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
+	      char_array_free (&onealt);
+	      goto illegal_brace;
 	    }
 
 	  /* Now find the end of the whole brace expression.  */
@@ -444,8 +432,11 @@  glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
 	    {
 	      rest = next_brace_sub (rest + 1, flags);
 	      if (rest == NULL)
-		/* It is an illegal expression.  */
-		goto illegal_brace;
+		{
+		  /* It is an illegal expression.  */
+		  char_array_free (&onealt);
+		  goto illegal_brace;
+		}
 	    }
 	  /* Please note that we now can be sure the brace expression
 	     is well-formed.  */
@@ -464,17 +455,24 @@  glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
 	      int result;
 
 	      /* Construct the new glob expression.  */
-	      mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
+	      ptrdiff_t nextlen = next - p;
+	      if (!char_array_replace_str_pos (&onealt, onealtlen, p, nextlen)
+		  || !char_array_replace_str_pos (&onealt, onealtlen + nextlen,
+						  rest, rest_len))
+		{
+		  char_array_free (&onealt);
+		  retval = GLOB_NOSPACE;
+		  goto out;
+		}
 
-	      result = glob (onealt,
+	      result = glob (char_array_str (&onealt),
 			     ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
 			      | GLOB_APPEND), errfunc, pglob);
 
 	      /* If we got an error, return it.  */
 	      if (result && result != GLOB_NOMATCH)
 		{
-		  if (__glibc_unlikely (!alloca_onealt))
-		    free (onealt);
+		  char_array_free (&onealt);
 		  if (!(flags & GLOB_APPEND))
 		    {
 		      globfree (pglob);
@@ -493,8 +491,7 @@  glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
 	      assert (next != NULL);
 	    }
 
-	  if (__glibc_unlikely (!alloca_onealt))
-	    free (onealt);
+	  char_array_free (&onealt);
 
 	  if (pglob->gl_pathc != firstc)
 	    /* We found some entries.  */
@@ -1182,6 +1179,10 @@  glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
  err_nospace:
   char_array_free (&dirname);
   return GLOB_NOSPACE;
+
+ illegal_brace:
+  char_array_free (&dirname);
+  return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
 }
 #if defined _LIBC && !defined glob
 libc_hidden_def (glob)