Skip to content

mate-session doesn't push 1024+ character environment variables into systemd (and dbus) #322

Description

@twhitehead

If mate-session encounters an environment variable of length 1024 or greater

$ FOO=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef mate-session

it won't update it in the systemd user environment

$ systemctl --user show-environment | grep ^FOO

The following code

#include <glib.h>

int main() {
  char           **entry_names;
  int              i = 0;
  GVariantBuilder  builder;
  GRegex          *name_regex, *value_regex;
  GError          *error = 0;

  name_regex = g_regex_new ("^[a-zA-Z_][a-zA-Z0-9_]*$", G_REGEX_OPTIMIZE, 0, &error);

  if (name_regex == NULL) {
    return 1;
  }

  value_regex = g_regex_new ("^([[:blank:]]|[^[:cntrl:]])*$", G_REGEX_OPTIMIZE, 0, &error);

  if (value_regex == NULL) {
    return 1;
  }

  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
  for (entry_names = g_listenv (); entry_names[i] != NULL; i++) {
    const char *entry_name = entry_names[i];
    const char *entry_value = g_getenv (entry_name);

    if (!g_utf8_validate (entry_name, -1, NULL)) {
      g_print("g_utf8_validate entry_name failed: %s\n", entry_name);
      continue;
    }

    if (!g_regex_match (name_regex, entry_name, 0, NULL)) {
      g_print("g_regex_match entry_name failed: %s\n", entry_name);
      continue;
    }

    if (!g_utf8_validate (entry_value, -1, NULL)) {
      g_print("g_utf8_validate entry_value failed: %s\n", entry_name);
      continue;
    }

    if (!g_regex_match (value_regex, entry_value, 0, NULL)) {
      g_print("g_regex_match entry_value failed: %s\n", entry_name);
      continue;
    }

    g_variant_builder_add (&builder, "{ss}", entry_name, entry_value);
  }
  g_regex_unref (name_regex);
  g_regex_unref (value_regex);

  g_strfreev (entry_names);

  return 0;
}

is the first of the export routines. Compiling

$ gcc $(pkg-config --cflags --libs glib-2.0) test.c -o test

and running it with a 1024 or greater environment variable reveals the issue is that g_regex_match doesn't match when the string is 1024+

$ FOO=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef ./test
g_regex_match entry_value failed: FOO

but it has no issues with 1023 characters

$ FOO=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde ./test

In my case the actual variable is PATH which is 1024+ due to some unfortunately long prefixes. I played a bit with the regex, and the length of what can be matched seems to depend on the regex.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions