Allow control characters in environment variable values
So far, we would allow certain control characters (NL sinceb4346b9a77, TAB since6294aa76d8), but not others. Having other control characters in environment variable *value* is expected and widely used, for various prompts like $LESS, $LESS_TERMCAP_*, and other similar variables. The typical environment exported by bash already contains a dozen or so such variables, so programs need to handle them. We handle then correctly too, for example in 'systemctl show-environment', since804ee07c13. But we would still disallow setting such variables by the user, in unit file Environment= and in set-environment/import-environment operations. This is unexpected and confusing and doesn't help with anything because such variables are present in the environment through other means. When printing such variables, 'show-environment' escapes all special characters, so variables with control characters are plainly visible. In other uses, e.g. 'cat -v' can be used in similar fashion. This would already need to be done to suppress color codes starting with \[. Note that we still forbid invalid utf-8 with this patch. (Control characters are valid, since they are valid 7-bit ascii.) I'm not sure if we should do that, but since people haven't been actually asking for invalid utf-8, and only for control characters, and invalid utf-8 causes other issues, I think it's OK to leave this unchanged. Fixes #4446, https://gitlab.gnome.org/GNOME/gnome-session/-/issues/45.
This commit is contained in:
+8
-13
@@ -57,16 +57,13 @@ bool env_value_is_valid(const char *e) {
|
||||
if (!utf8_is_valid(e))
|
||||
return false;
|
||||
|
||||
/* bash allows tabs and newlines in environment variables, and so
|
||||
* should we */
|
||||
if (string_has_cc(e, "\t\n"))
|
||||
return false;
|
||||
/* Note that variable *values* may contain control characters, in particular NL, TAB, BS, DEL, ESC…
|
||||
* When printing those variables with show-environment, we'll escape them. Make sure to print
|
||||
* environment variables carefully! */
|
||||
|
||||
/* POSIX says the overall size of the environment block cannot
|
||||
* be > ARG_MAX, an individual assignment hence cannot be
|
||||
* either. Discounting the shortest possible variable name of
|
||||
* length 1, the equal sign and trailing NUL this hence leaves
|
||||
* ARG_MAX-3 as longest possible variable value. */
|
||||
/* POSIX says the overall size of the environment block cannot be > ARG_MAX, an individual assignment
|
||||
* hence cannot be either. Discounting the shortest possible variable name of length 1, the equal
|
||||
* sign and trailing NUL this hence leaves ARG_MAX-3 as longest possible variable value. */
|
||||
if (strlen(e) > sc_arg_max() - 3)
|
||||
return false;
|
||||
|
||||
@@ -86,10 +83,8 @@ bool env_assignment_is_valid(const char *e) {
|
||||
if (!env_value_is_valid(eq + 1))
|
||||
return false;
|
||||
|
||||
/* POSIX says the overall size of the environment block cannot
|
||||
* be > ARG_MAX, hence the individual variable assignments
|
||||
* cannot be either, but let's leave room for one trailing NUL
|
||||
* byte. */
|
||||
/* POSIX says the overall size of the environment block cannot be > ARG_MAX, hence the individual
|
||||
* variable assignments cannot be either, but let's leave room for one trailing NUL byte. */
|
||||
if (strlen(e) > sc_arg_max() - 1)
|
||||
return false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user