setup: make sure git_dir path is in a permanent buffer, getenv(3) case
authorKirill Smelkov <kirr@mns.spb.ru>
Thu, 11 Nov 2010 18:08:23 +0000 (21:08 +0300)
committerJunio C Hamano <gitster@pobox.com>
Sat, 13 Nov 2010 00:03:27 +0000 (16:03 -0800)
commit15431ca651050ba315fa4e2e74527f6d115e706c
tree0bb3612efc438456a7a744125bcee2f16704c001
parent60aa9cf8f370b69eb7feaad2e1cbcd04280bc799
setup: make sure git_dir path is in a permanent buffer, getenv(3) case

getenv(3) returns not-permanent buffer which may be changed by e.g.
putenv(3) call (*).

In practice I've noticed this when trying to do `git commit -m abc`
inside msysgit under wine, getting

    $ git commit -m abc
    fatal: could not open 'DIR=.git/COMMIT_EDITMSG': No such file or directory
                           ^^^^
    (notice introduced 'DIR=' artifact.)

The problem was showing itself only with -m option, and actually, as
debugging showed, originally

    git_dir = getenv("GIT_DIR")

returned pointer to

        "GIT_DIR=.git\0"
                 ^
               git_dir

, we stored it in git_dir, than, after processing -m git-commit option,
we did setenv("GIT_EDITOR", ":") which as (*) says changed environment
variables memory layout - something like this

       "...\0GIT_DIR=.git\0"
                 ^
               git_dir

and oops - we got wrong git_dir.

Avoid that by strdupping getenv("GIT_DIR") result like we did in 06f354
(setup: make sure git dir path is in a permanent buffer). Unfortunately
this also shows that other getenv usage inside git needs auditing...

(*) from man 3 getenv:

       The implementation of getenv() is not required to  be  reentrant.   The
       string  pointed  to  by  the return value of getenv() may be statically
       allocated, and can be  modified  by  a  subsequent  call  to  getenv(),
       putenv(3), setenv(3), or unsetenv(3).

Cc: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
environment.c