]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
wordexp: Rewrite parse_tilde to use struct scratch_buffer [BZ #18023]
authorFlorian Weimer <fweimer@redhat.com>
Wed, 27 Jun 2018 15:54:44 +0000 (17:54 +0200)
committerFlorian Weimer <fweimer@redhat.com>
Wed, 27 Jun 2018 15:54:44 +0000 (17:54 +0200)
ChangeLog
posix/wordexp.c

index 72badfe3f5fe185f69c3a169a0e03271411acb9c..261e76baf1500b041f9f1f8fb0730247c95b45f8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-06-27  Florian Weimer  <fweimer@redhat.com>
+
+       [BZ #18023]
+       * posix/wordexp.c (parse_tilde): Use struct scratch_buffer
+       instead of extend_alloca.
+
 2018-06-26  Joseph Myers  <joseph@codesourcery.com>
 
        [BZ #13888]
index 0b669a8f5e05ed15565c60c3afb6735f1055e21c..7548e0329fdeafaa9adcc9e57a68f1eae2e74b7a 100644 (file)
@@ -17,7 +17,6 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <alloca.h>
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -41,6 +40,7 @@
 #include <wchar.h>
 #include <wordexp.h>
 #include <kernel-features.h>
+#include <scratch_buffer.h>
 
 #include <libc-lock.h>
 #include <_itoa.h>
@@ -299,12 +299,7 @@ parse_tilde (char **word, size_t *word_length, size_t *max_length,
   if (i == 1 + *offset)
     {
       /* Tilde appears on its own */
-      uid_t uid;
-      struct passwd pwd, *tpwd;
-      int buflen = 1000;
       char* home;
-      char* buffer;
-      int result;
 
       /* POSIX.2 says ~ expands to $HOME and if HOME is unset the
         results are unspecified.  We do a lookup on the uid if
@@ -319,25 +314,38 @@ parse_tilde (char **word, size_t *word_length, size_t *max_length,
        }
       else
        {
-         uid = __getuid ();
-         buffer = __alloca (buflen);
-
-         while ((result = __getpwuid_r (uid, &pwd, buffer, buflen, &tpwd)) != 0
+         struct passwd pwd, *tpwd;
+         uid_t uid = __getuid ();
+         int result;
+         struct scratch_buffer tmpbuf;
+         scratch_buffer_init (&tmpbuf);
+
+         while ((result = __getpwuid_r (uid, &pwd,
+                                        tmpbuf.data, tmpbuf.length,
+                                        &tpwd)) != 0
                 && errno == ERANGE)
-           buffer = extend_alloca (buffer, buflen, buflen + 1000);
+           if (!scratch_buffer_grow (&tmpbuf))
+             return WRDE_NOSPACE;
 
          if (result == 0 && tpwd != NULL && pwd.pw_dir != NULL)
            {
              *word = w_addstr (*word, word_length, max_length, pwd.pw_dir);
              if (*word == NULL)
-               return WRDE_NOSPACE;
+               {
+                 scratch_buffer_free (&tmpbuf);
+                 return WRDE_NOSPACE;
+               }
            }
          else
            {
              *word = w_addchar (*word, word_length, max_length, '~');
              if (*word == NULL)
-               return WRDE_NOSPACE;
+               {
+                 scratch_buffer_free (&tmpbuf);
+                 return WRDE_NOSPACE;
+               }
            }
+         scratch_buffer_free (&tmpbuf);
        }
     }
   else
@@ -345,13 +353,15 @@ parse_tilde (char **word, size_t *word_length, size_t *max_length,
       /* Look up user name in database to get home directory */
       char *user = strndupa (&words[1 + *offset], i - (1 + *offset));
       struct passwd pwd, *tpwd;
-      int buflen = 1000;
-      char* buffer = __alloca (buflen);
       int result;
+      struct scratch_buffer tmpbuf;
+      scratch_buffer_init (&tmpbuf);
 
-      while ((result = __getpwnam_r (user, &pwd, buffer, buflen, &tpwd)) != 0
+      while ((result = __getpwnam_r (user, &pwd, tmpbuf.data, tmpbuf.length,
+                                    &tpwd)) != 0
             && errno == ERANGE)
-       buffer = extend_alloca (buffer, buflen, buflen + 1000);
+       if (!scratch_buffer_grow (&tmpbuf))
+         return WRDE_NOSPACE;
 
       if (result == 0 && tpwd != NULL && pwd.pw_dir)
        *word = w_addstr (*word, word_length, max_length, pwd.pw_dir);
@@ -363,6 +373,8 @@ parse_tilde (char **word, size_t *word_length, size_t *max_length,
            *word = w_addstr (*word, word_length, max_length, user);
        }
 
+      scratch_buffer_free (&tmpbuf);
+
       *offset = i - 1;
     }
   return *word ? 0 : WRDE_NOSPACE;