--- bash-4.0/y.tab.c 2009-01-08 09:30:24.000000000 -0500 +++ bash-4.0-safelocale/y.tab.c 2009-02-28 13:22:11.133393093 -0500 @@ -459,6 +459,12 @@ static REDIRECTEE redir; +/* If non-zero, the result of a $"..." locale expansion is treated as if it + were single-quoted, instead of double-quoted. This allows the script to + use $"..." without introducing security holes, but breaks backward + compatibility with bash 2.x/3.x $"..." treatment. */ +int safe_locale = 0; + /* Enabling traces. */ #ifndef YYDEBUG @@ -5378,9 +5384,17 @@ ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen); xfree (nestret); - nestret = sh_mkdoublequoted (ttrans, ttranslen, 0); + if (safe_locale) + { + nestret = sh_single_quote (ttrans); + nestlen = strlen (nestret); + } + else + { + nestret = sh_mkdoublequoted (ttrans, ttranslen, 0); + nestlen = ttranslen + 2; + } free (ttrans); - nestlen = ttranslen + 2; retind -= 2; /* back up before the $" */ } @@ -5747,9 +5761,17 @@ ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen); xfree (nestret); - nestret = sh_mkdoublequoted (ttrans, ttranslen, 0); + if (safe_locale) + { + nestret = sh_single_quote (ttrans); + nestlen = strlen (nestret); + } + else + { + nestret = sh_mkdoublequoted (ttrans, ttranslen, 0); + nestlen = ttranslen + 2; + } free (ttrans); - nestlen = ttranslen + 2; retind -= 2; /* back up before the $" */ } @@ -6460,10 +6482,18 @@ ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen); free (ttok); - /* Add the double quotes back */ - ttok = sh_mkdoublequoted (ttrans, ttranslen, 0); + /* Add the double quotes back (or single-quote it) */ + if (safe_locale) + { + ttok = sh_single_quote (ttrans); + ttranslen = strlen (ttok); + } + else + { + ttok = sh_mkdoublequoted (ttrans, ttranslen, 0); + ttranslen += 2; + } free (ttrans); - ttranslen += 2; ttrans = ttok; } --- bash-4.0/builtins/shopt.def 2009-01-13 08:43:16.000000000 -0500 +++ bash-4.0-safelocale/builtins/shopt.def 2009-02-28 13:22:14.037392967 -0500 @@ -84,6 +84,7 @@ extern int check_jobs_at_exit; extern int autocd; extern int glob_star; +extern int safe_locale; #if defined (EXTENDED_GLOB) extern int extended_glob; @@ -191,6 +192,7 @@ #if defined (RESTRICTED_SHELL) { "restricted_shell", &restricted_shell, set_restricted_shell }, #endif + { "safelocale", &safe_locale, (shopt_set_func_t *)NULL }, { "shift_verbose", &print_shift_error, (shopt_set_func_t *)NULL }, { "sourcepath", &source_uses_path, (shopt_set_func_t *)NULL }, { "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL }, --- bash-4.0/doc/bash.1 2009-02-18 15:13:56.000000000 -0500 +++ bash-4.0-safelocale/doc/bash.1 2009-02-28 15:19:06.381392106 -0500 @@ -8689,6 +8689,14 @@ This is not reset when the startup files are executed, allowing the startup files to discover whether or not a shell is restricted. .TP 8 +.B safelocale +If set, the result of a \fB$"..."\fP locale expansion is treated +as if it were single-quoted. +If unset, the result is treated as if it were double-quoted, with the +translated strings being subject to parameter expansion, command +substitution and arithmetic expansion. +This option is disabled by default. +.TP 8 .B shift_verbose If set, the .B shift