Collin Funk wrote:
> +     putenv tests: Silence -Wanalyzer-putenv-of-auto-var.
> +     * tests/test-putenv.c (main): Declare static variables to pass to
> +     putenv.

While fixing one problem, this patch reintroduced another one.

Namely, the argument to putenv needs to be
  - of unlimited lifetime (to cover the case of a getenv() call
    after the function terminates), and
  - in writable memory (since it becomes part of a 'char ** environ').

When you write
  static char *var = "TEST_VAR=abc";
the string is in read-only memory. See:

=========== foo.c ============
static char *var = "TEST_VAR";
int main () {}
==============================
$ gcc foo.c
$ hd < a.out
...
002000  01 00 02 00 54 45 53 54 5F 56 41 52 00 00 00 00  ....TEST_VAR....
...
$ objdump -x a.out
...
 15 .rodata       0000000d  0000000000002000  0000000000002000  00002000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
...

Whereas with this change the string is in writable memory:

=========== foo.c ============
static char var[] = "TEST_VAR";
int main () {}
==============================
$ gcc foo.c
$ hd < a.out
...
003010  54 45 53 54 5F 56 41 52 00 47 43 43 3A 20 28 55  TEST_VAR.GCC: (U
...
$ objdump -x a.out
...
 22 .data         00000019  0000000000004000  0000000000004000  00003000  2**3
                  CONTENTS, ALLOC, LOAD, DATA
...

I'm therefore applying this:


2024-05-24  Bruno Haible  <br...@clisp.org>

        putenv tests: Put the putenv() argument strings into writable memory.
        * tests/test-putenv.c (main): Declare static variables of type 'char[]',
        not 'char *'.

diff --git a/tests/test-putenv.c b/tests/test-putenv.c
index b772082d20..535fbbbb3a 100644
--- a/tests/test-putenv.c
+++ b/tests/test-putenv.c
@@ -42,7 +42,7 @@ main (void)
 
   /* Verify adding an environment variable.  */
   {
-    static char *var = "TEST_VAR=abc";
+    static char var[] = "TEST_VAR=abc";
     ASSERT (putenv (var) == 0);
     ptr = getenv ("TEST_VAR");
     ASSERT (ptr != NULL);
@@ -51,14 +51,14 @@ main (void)
 
   /* Verify removing an environment variable.  */
   {
-    static char *var = "TEST_VAR";
+    static char var[] = "TEST_VAR";
     ASSERT (putenv (var) == 0);
     ASSERT (getenv ("TEST_VAR") == NULL);
   }
 
   /* Verify the behavior when removing a variable not in the environment.  */
   {
-    static char *var = "TEST_VAR";
+    static char var[] = "TEST_VAR";
     ASSERT (putenv (var) == 0);
     ASSERT (getenv ("TEST_VAR") == NULL);
   }




Reply via email to