]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Support only simple access to shell variables, only ASCII names, and
authorBruno Haible <bruno@clisp.org>
Tue, 16 Sep 2003 08:52:23 +0000 (08:52 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:10:59 +0000 (12:10 +0200)
no $0 or $?.

gettext-tools/src/ChangeLog
gettext-tools/src/format-sh.c
gettext-tools/tests/ChangeLog
gettext-tools/tests/format-sh-1
gettext-tools/tests/format-sh-2

index 4028f77a48245daaf7c296ebb59eb8abbc7d0768..49f1fc96bf10576ed415d72577023e00d39c0833 100644 (file)
@@ -1,3 +1,9 @@
+2003-09-13  Bruno Haible  <bruno@clisp.org>
+
+       * format-sh.c (INVALID_SHELL_SYNTAX,
+       INVALID_CONTEXT_DEPENDENT_VARIABLE): New macros.
+       (format_parse): Reject constructs like ${variable-default} and $?.
+
 2003-09-13  Bruno Haible  <bruno@clisp.org>
 
        Fix behaviour of "<program> --help > /dev/full".
index 542e846bb0ce0cf03b3a3fcb0e484736ea0e5a2c..ae351b75d65bf4fe38a97d3331ad98afa42746ed 100644 (file)
    A variable substitution starts with '$' and is finished by either
    - a nonempty sequence of alphanumeric ASCII characters, the first being
      not a digit, or
-   - an opening brace '{', some other characters with balanced '{' and '}',
-     and a closing brace '}', or
-   - a single ASCII character, like '$' or '?'.
-
-   FIXME: POSIX has more complicated rules for determining the matching brace:
-     "Any '}' escaped by a backslash or within a quoted string, and characters
-      in embedded arithmetic expansions, command substitutions, and variable
-      expansions, shall not be examined in determining the matching '}'."
-   Not yet implemented here.
+   - an opening brace '{', a nonempty sequence of alphanumeric ASCII
+     characters, the first being not a digit, and a closing brace '}'.
+   We don't support variable references like $1, $$ or $? since they make
+   no sense when 'envsubst' is invoked.
+   We don't support non-ASCII variable names, to avoid dependencies w.r.t. the
+   current encoding: While "${\xe0}" looks like a variable access in ISO-8859-1
+   encoding, it doesn't look like one in the BIG5, BIG5-HKSCS, GBK, GB18030,
+   SHIFT_JIS, JOHAB encodings, because \xe0\x7d is a single character in these
+   encodings.
+   We don't support the POSIX syntax for default or alternate values:
+     ${variable-default}        ${variable:-default}
+     ${variable=default}        ${variable:=default}
+     ${variable+replacement}    ${variable:+replacement}
+     ${variable?ignored}        ${variable:?ignored}
+   because the translator might be tempted to change the default value; if
+   we allow it we have a security problem; if we don't allow it the translator
+   will be surprised.
  */
 
 struct named_arg
@@ -72,6 +80,10 @@ named_arg_compare (const void *p1, const void *p2)
 
 #define INVALID_NON_ASCII_VARIABLE() \
   xstrdup (_("The string refers to a shell variable with a non-ASCII name."))
+#define INVALID_SHELL_SYNTAX() \
+  xstrdup (_("The string refers to a shell variable with complex shell brace syntax. This syntax is unsupported here due to security reasons."))
+#define INVALID_CONTEXT_DEPENDENT_VARIABLE() \
+  xstrdup (_("The string refers to a shell variable whose value may be different inside shell functions."))
 #define INVALID_EMPTY_VARIABLE() \
   xstrdup (_("The string refers to a shell variable with an empty name."))
 
@@ -96,27 +108,31 @@ format_parse (const char *format, char **invalid_reason)
 
        if (*format == '{')
          {
-           unsigned int depth;
            const char *name_start;
            const char *name_end;
            size_t n;
 
            name_start = ++format;
-           depth = 0;
            for (; *format != '\0'; format++)
              {
-               if (*format == '{')
-                 depth++;
-               else if (*format == '}')
+               if (*format == '}')
+                 break;
+               if (!c_isascii (*format))
                  {
-                   if (depth == 0)
-                     break;
-                   else
-                     depth--;
+                   *invalid_reason = INVALID_NON_ASCII_VARIABLE ();
+                   goto bad_format;
                  }
-               if (!c_isascii (*format))
+               if (format > name_start
+                   && (*format == '-' || *format == '=' || *format == '+'
+                       || *format == '?' || *format == ':'))
+                 {
+                   *invalid_reason = INVALID_SHELL_SYNTAX ();
+                   goto bad_format;
+                 }
+               if (!(c_isalnum (*format) || *format == '_')
+                   || (format == name_start && c_isdigit (*format)))
                  {
-                   *invalid_reason = INVALID_NON_ASCII_VARIABLE();
+                   *invalid_reason = INVALID_CONTEXT_DEPENDENT_VARIABLE ();
                    goto bad_format;
                  }
              }
@@ -130,7 +146,7 @@ format_parse (const char *format, char **invalid_reason)
            n = name_end - name_start;
            if (n == 0)
              {
-               *invalid_reason = INVALID_EMPTY_VARIABLE();
+               *invalid_reason = INVALID_EMPTY_VARIABLE ();
                goto bad_format;
              }
            name = (char *) xmalloc (n + 1);
@@ -158,12 +174,14 @@ format_parse (const char *format, char **invalid_reason)
          {
            if (!c_isascii (*format))
              {
-               *invalid_reason = INVALID_NON_ASCII_VARIABLE();
+               *invalid_reason = INVALID_NON_ASCII_VARIABLE ();
+               goto bad_format;
+             }
+           else
+             {
+               *invalid_reason = INVALID_CONTEXT_DEPENDENT_VARIABLE ();
                goto bad_format;
              }
-           name = (char *) xmalloc (2);
-           name[0] = *format++;
-           name[1] = '\0';
          }
        else
          {
index 1f0acbe7933a9f8c4b065d281d4f86526420a011..19aa7acc6d9da0453a72d4c92009f0e10ca72896 100644 (file)
@@ -1,3 +1,8 @@
+2003-09-13  Bruno Haible  <bruno@clisp.org>
+
+       * format-sh-1: Update to match stricter format string definition.
+       * format-sh-2: Likewise.
+
 2003-09-13  Bruno Haible  <bruno@clisp.org>
 
        Fix behaviour of "<program> --help > /dev/full".
index d438eac1085eb3816f010d1c1cf9a8223e992342..6bbb32f9537d109efb798829386980a9680e68ab 100755 (executable)
@@ -13,11 +13,11 @@ cat <<\EOF > f-sh-1.data
 "abc$file"
 # Valid: one argument
 "abc$f_x"
-# Valid: one argument
+# Invalid: context dependent variable
 "abc$0"
-# Valid: one argument
+# Invalid: context dependent variable
 "abc$$"
-# Valid: one argument
+# Invalid: complex shell syntax
 "abc${tmpdir-/tmp}"
 # Invalid: unterminated
 "abc$"
index e19cc39d05ae44700324bfe7e5bfca4e1b46b7d0..cf8bbf0f76d5a283ba3d826c5646be3d79735d07 100755 (executable)
@@ -19,9 +19,12 @@ msgstr "xyz$file"
 # Invalid: added argument
 msgid  "abc$file"
 msgstr "xyz$file in $dir"
+# Valid: braces or not, doesn't matter
+msgid  "abc$file"
+msgstr "xyz${file}"
 # Invalid: different default value
-msgid  "abc${file-/tmpdir}"
-msgstr "xyz$file"
+msgid  "abc$file"
+msgstr "xyz${file-/tmpdir}"
 EOF
 
 : ${MSGFMT=msgfmt}