https://bugs.winehq.org/show_bug.cgi?id=55835
Bug ID: 55835 Summary: putenv clobbers previous getenv Product: Wine Version: 8.17 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: msvcrt Assignee: wine-bugs@winehq.org Reporter: blitzkriegoutlaw@hotmail.com Distribution: ---
Created attachment 75335 --> https://bugs.winehq.org/attachment.cgi?id=75335 Sample code
performing a putenv/_putenv_s to an empty string will clobber a previous getenv. There may be other cases, but this is the one I ran into. I've attached sample code.
On Windows it returns: AMD64 Family 23 Model 1 Stepping 2, AuthenticAMD AMD64 Family 23 Model 1 Stepping 2, AuthenticAMD
On Wine it returns: x86 Family 6 Model 79 Stepping 1, GenuineIntel Family 6 Model 79 Stepping 1, GenuineIntel
The string is globbered by the _setenv_s due to the shift in memory by removing another environment variable.
https://bugs.winehq.org/show_bug.cgi?id=55835
Bartosz gang65@poczta.onet.pl changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |gang65@poczta.onet.pl
https://bugs.winehq.org/show_bug.cgi?id=55835
Eric Pouech eric.pouech@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |eric.pouech@gmail.com
--- Comment #1 from Eric Pouech eric.pouech@gmail.com --- took a quick glance at it: tested on Win10.
32bit version looks it behaves as Wine (_environ[] points to a global chunk of memory containing all pointers) while 64bit has a different allocation for each string in _environ[]).
do you have an application that depends on this behavior?
https://bugs.winehq.org/show_bug.cgi?id=55835
--- Comment #2 from blitzkriegoutlaw@hotmail.com --- I worked around it by copying the value to a local variable. It took me a while to track it down as what was happening didn't make sense immediately.
https://bugs.winehq.org/show_bug.cgi?id=55835
--- Comment #3 from Eric Pouech eric.pouech@gmail.com --- can you share which application it is (if possible)
Side note: comment in #2 about difference between 32 & 64 bit is inacurate. Further testings show that they both behave the same way and msvcrt provides a distinct allocation bucket for each entry in the _environ[] array (native seems to do this separate allocation __after__ an entry is added/removed/updated, so order of operation matters)
https://bugs.winehq.org/show_bug.cgi?id=55835
Fabian Maurer dark.shadow4@web.de changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |dark.shadow4@web.de
https://bugs.winehq.org/show_bug.cgi?id=55835
--- Comment #4 from blitzkriegoutlaw@hotmail.com --- It is internal software so not publicly available. I can't state what it is.
The unix man page for getenv states: 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).
The Microsoft help page has no such note. However, that part of the code compiles and runs on Windows and Linux and I don't have this problem. That unix note probably doesn't apply to Linux as haven't seen the problem there. It wasn't until I tried to run our legacy HMI in Wine that I ran into this problem. Since I have the source code, it wasn't hard to work around the issue by copying the result of getenv into an character array. I believe it is a bug since Windows getenv is reentrant.
https://bugs.winehq.org/show_bug.cgi?id=55835
Eric Pouech eric.pouech@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |ASSIGNED Ever confirmed|0 |1
--- Comment #5 from Eric Pouech eric.pouech@gmail.com --- (In reply to blitzkriegoutlaw from comment #4)
It is internal software so not publicly available. I can't state what it is.
Nevermind. It's always interesting to log in bug entry if app is public, so that it can be retested afterwards. When possible.
The unix man page for getenv states: 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).
The Microsoft help page has no such note. However, that part of the code compiles and runs on Windows and Linux and I don't have this problem. That unix note probably doesn't apply to Linux as haven't seen the problem there. It wasn't until I tried to run our legacy HMI in Wine that I ran into this problem. Since I have the source code, it wasn't hard to work around the issue by copying the result of getenv into an character array. I believe it is a bug since Windows getenv is reentrant.
yes, msvcrt puts in place a per-entry allocation in _environ (and _wenviron) (so that _environ[i] isn't changed after a putenv if variable isn't stored at location [i])
so, it looks like for native: - (w)getenv("foo") is unchanged (pointer value and pointed string) after (w)putenv calls, iff "foo" variable isn't modified - I would be less confident in the stability of the index inside _(w)environ[]. I haven't tested what happens if one removes a variable at index before i. I fear it could well be that the _(w)environ array is compacted, moving the entry at _(w)environ[i-1].
Anyway, I posted https://gitlab.winehq.org/wine/wine/-/merge_requests/4313 that should solve your issue.
https://bugs.winehq.org/show_bug.cgi?id=55835
--- Comment #6 from Bartosz gang65@poczta.onet.pl --- The issue was already resolved and it should be closed as fixed.
https://bugs.winehq.org/show_bug.cgi?id=55835
--- Comment #7 from Eric Pouech eric.pouech@gmail.com --- actually it's not fixed (yet) MR 4313 has been reduced in scope and only contains mainly tests (and a fix for something not related to this bug) fix for this bug has been moved into MR 4377
https://bugs.winehq.org/show_bug.cgi?id=55835
--- Comment #8 from Eric Pouech eric.pouech@gmail.com --- this should be fixed by commit bdb624fffb1c1acc1feb2baec396d9b805cb0ce9 can you retest from git tree or when wine 8-21 is released? TIA
https://bugs.winehq.org/show_bug.cgi?id=55835
Piotr Caban piotr.caban@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |piotr.caban@gmail.com Resolution|--- |FIXED Status|ASSIGNED |RESOLVED
--- Comment #9 from Piotr Caban piotr.caban@gmail.com --- The attached example works as expected now. Marking as fixed.
https://bugs.winehq.org/show_bug.cgi?id=55835
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #10 from Alexandre Julliard julliard@winehq.org --- Closing bugs fixed in 9.1.