shell/read: check that variable names are sane
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 13 Jan 2010 17:22:35 +0000 (18:22 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 13 Jan 2010 17:22:35 +0000 (18:22 +0100)
function                                             old     new   delta
shell_builtin_read                                  1000    1055     +55
parse_command                                       1460    1463      +3
builtin_umask                                        121     123      +2
is_well_formed_var_name                               73      66      -7

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c
shell/builtin_read.c
shell/hush.c
shell/shell_common.c
shell/shell_common.h

index 31dc5925318305ab58ae28292953e3afc0257f3f..798d15a4c4dc1b2216a04707bfc7ffd67a85b744 100644 (file)
@@ -1768,11 +1768,7 @@ static const struct {
        const char *text;
        void (*func)(const char *) FAST_FUNC;
 } varinit_data[] = {
-#if IFS_BROKEN
        { VSTRFIXED|VTEXTFIXED       , defifsvar   , NULL            },
-#else
-       { VSTRFIXED|VTEXTFIXED|VUNSET, "IFS\0"     , NULL            },
-#endif
 #if ENABLE_ASH_MAIL
        { VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL\0"    , changemail      },
        { VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH\0", changemail      },
index 73b0949cf0b7f58d8ce3044b4ff8669a56c32e1b..954e4cd14c94a8bc9b6d0fe34957b3539b381f59 100644 (file)
@@ -39,6 +39,7 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val),
        unsigned end_ms; /* -t TIMEOUT */
        int fd; /* -u FD */
        int nchars; /* -n NUM */
+       char **pp;
        char *buffer;
        struct termios tty, old_tty;
        const char *retval;
@@ -46,6 +47,16 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val),
        int startword;
        smallint backslash;
 
+       pp = argv;
+       while (*pp) {
+               if (!is_well_formed_var_name(*pp, '\0')) {
+                       /* Mimic bash message */
+                       bb_error_msg("read: '%s': not a valid identifier", *pp);
+                       return (const char *)(uintptr_t)1;
+               }
+               pp++;
+       }
+
        nchars = 0; /* if != 0, -n is in effect */
        if (opt_n) {
                nchars = bb_strtou(opt_n, NULL, 10);
index bb0ab84083eb900f059335c8d76e451d7da64b35..810009ae8dc63f2607473d085d3785509632646f 100644 (file)
@@ -893,16 +893,6 @@ static void cmdedit_update_prompt(void);
 
 /* Utility functions
  */
-static int is_well_formed_var_name(const char *s, char terminator)
-{
-       if (!s || !(isalpha(*s) || *s == '_'))
-               return 0;
-       s++;
-       while (isalnum(*s) || *s == '_')
-               s++;
-       return *s == terminator;
-}
-
 /* Replace each \x with x in place, return ptr past NUL. */
 static char *unbackslash(char *src)
 {
index 99bb91c6f3bc67b03dee0f7c907ad1a554b88518..669a18dfd56e091fcad2094aa9c79d9c2a7fcebf 100644 (file)
 #include "libbb.h"
 #include "shell_common.h"
 
-#if IFS_BROKEN
 const char defifsvar[] ALIGN1 = "IFS= \t\n";
-#else
-const char defifs[] ALIGN1 = " \t\n";
-#endif
+
+
+int FAST_FUNC is_well_formed_var_name(const char *s, char terminator)
+{
+       if (!s || !(isalpha(*s) || *s == '_'))
+               return 0;
+
+       do
+               s++;
+       while (isalnum(*s) || *s == '_');
+
+       return *s == terminator;
+}
index a9e9a22395757f3f235d8899695b644355f898f9..7c8e8c356e5b8915ea5d1e7bd765b275599d60a8 100644 (file)
 
 PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
 
-#define IFS_BROKEN 1
-
-#if IFS_BROKEN
 extern const char defifsvar[]; /* "IFS= \t\n" */
 #define defifs (defifsvar + 4)
-#else
-extern const char defifs[]; /* " \t\n" */
-#endif
+
+int FAST_FUNC is_well_formed_var_name(const char *s, char terminator);
 
 POP_SAVED_FUNCTION_VISIBILITY