[Bug 48471] New: Mismatching behavior of GetEnvironmentVariableW for empty / long values

WineHQ Bugzilla wine-bugs at winehq.org
Wed Jan 15 23:59:35 CST 2020


https://bugs.winehq.org/show_bug.cgi?id=48471

            Bug ID: 48471
           Summary: Mismatching behavior of GetEnvironmentVariableW for
                    empty / long values
           Product: Wine
           Version: 5.0-rc4
          Hardware: x86
                OS: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: kernelbase
          Assignee: wine-bugs at winehq.org
          Reporter: wine at thecybershadow.net
      Distribution: ---

Attempting to build the Windows version of DMD, the reference compiler for the
D programming language, fails under Wine. This seems to be caused by the
following chain of events:

1. The makefile invokes a build program with a "VERBOSE=" on the command-line:

  
https://github.com/dlang/dmd/blob/49dfbe54f4a0f62a0694aec9fb4184739903a0c2/src/win32.mak#L81

   (Here "$(VERBOSE)" is not set and expands to the empty string.)

2. The build program registers the command-line arguments into the process
environment:

  
https://github.com/dlang/dmd/blob/49dfbe54f4a0f62a0694aec9fb4184739903a0c2/src/build.d#L1359

   This sets the environment variable VERBOSE to the empty string.

3. Later, it attempts to check if the "VERBOSE" variable is in the environment:

  
https://github.com/dlang/dmd/blob/49dfbe54f4a0f62a0694aec9fb4184739903a0c2/src/build.d#L1379

4. This calls the following Windows code in the standard library to read the
environment:

  
https://github.com/dlang/phobos/blob/e373b4e77448bc11c6e4ea6c85bcdb8f7ab86f20/std/process.d#L3506-L3515

5. For empty variables, the code behaves differently in Windows and Wine -
Wine's implementation returns 0, while Windows returns 1. As a result, the
standard library code throws an exception under Wine.

Writing a test program reveals further differences. The program:


#include <stdio.h>
#include <windows.h>

void main()
{
    WCHAR buf[4];
    DWORD size;
    int len, i;

    for (len = 0; len <= 2; len++)
    {
        for (i = 0; i < len; i++)
            buf[i] = 'a';
        buf[len] = 0;    

        SetEnvironmentVariableW(L"TESTVAR", buf);

        for (i = 0; i <= len + 1; i++)
        {
            DWORD err;
            SetLastError(1);
            buf[0] = 1;
            size = GetEnvironmentVariableW(L"TESTVAR", buf, i);
            err = GetLastError();
            printf("%d->%d: size=%d error=%d buf[0]=%d\n", 
                len, i, size, err, buf[0]);
        }
        printf("\n");
    }    
}


Output on Windows [Version 10.0.17134.648]:

0->0: size=1 error=1 buf[0]=1
0->1: size=0 error=1 buf[0]=0

1->0: size=2 error=1 buf[0]=1
1->1: size=2 error=1 buf[0]=0
1->2: size=1 error=1 buf[0]=97

2->0: size=3 error=1 buf[0]=1
2->1: size=3 error=1 buf[0]=0
2->2: size=3 error=1 buf[0]=0
2->3: size=2 error=1 buf[0]=97

Output on Wine:

0->0: size=0 error=1 buf[0]=1
0->1: size=0 error=1 buf[0]=0

1->0: size=2 error=122 buf[0]=1
1->1: size=2 error=122 buf[0]=1
1->2: size=1 error=1 buf[0]=97

2->0: size=3 error=122 buf[0]=1
2->1: size=3 error=122 buf[0]=1
2->2: size=3 error=122 buf[0]=1
2->3: size=2 error=1 buf[0]=97

We can observe these differences:

1. Wine returns 0 and not 1 when the variable is empty and the function is
given a zero-length buffer.

2. Wine sets the last error to ERROR_INSUFFICIENT_BUFFER, while Windows
doesn't.

3. Windows zeroes the buffer if the size is non-zero but still insufficient to
hold the value. (This is not a bug as the behavior is specified in the
documentation to be undefined.)

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list