Skip to content

Unexplained difference around spawning .bat scripts in CI #19762

Description

@squeek502

This is a follow up from #19698. It's not necessarily a bug, but it is something that should be understood better at the very least.

In CI, this part of the windows_bat_args standalone test was failing:

var env = env: {
var env = try std.process.getEnvMap(allocator);
errdefer env.deinit();
// No escaping
try env.put("FOO", "123");
// Some possible escaping of %FOO% that could be expanded
// when escaping cmd.exe meta characters with ^
try env.put("FOO^", "123"); // only escaping %
try env.put("^F^O^O^", "123"); // escaping every char
break :env env;
};
defer env.deinit();
try testExec(allocator, &.{"%FOO%"}, &env);

when the EnvMap was initialized as empty instead of using getEnvMap:

        var env = std.process.EnvMap.init(allocator);
        errdefer env.deinit();

but was working fine for me locally.

The failure looked like this:

====== expected this output: =========
%FOO%␃

======== instead found this: =========
␃

======================================
First difference occurs on line 1:
expected:
%FOO%
^ ('\x25')
found:

^ (end of string)
error: TestExpectedEqual
C:\actions-runner0\_work\zig\zig\lib\std\testing.zig:622:9: 0x7ff693156467 in expectEqualStrings (test.exe.obj)
        return error.TestExpectedEqual;
        ^
C:\actions-runner0\_work\zig\zig\test\standalone\windows_bat_args\test.zig:129:9: 0x7ff693157447 in testExecBat (test.exe.obj)
        try std.testing.expectEqualStrings(expected_arg, actual_arg);
        ^
C:\actions-runner0\_work\zig\zig\test\standalone\windows_bat_args\test.zig:99:5: 0x7ff69315805f in testExec (test.exe.obj)
    try testExecBat(allocator, "args1.bat", args, env);
    ^
C:\actions-runner0\_work\zig\zig\test\standalone\windows_bat_args\test.zig:88:5: 0x7ff693154243 in main (test.exe.obj)
    try testExec(allocator, &.{"%FOO%"}, &path_env);
    ^

That is, when running args1.bat which looks like this:

@echo off
"path/to/echo-args.exe" %*

and passing it %FOO% (escaped using the BatBadBut mitigation), the argument ends up empty in echo-args.exe instead of the expected %FOO% (note: the BatBadBut mitigation failing would mean it'd end up as 123 since that's what we're setting the FOO environment variable to in the EnvMap).

(the source of echo-args.exe can be seen here, it prints std.process.argsAlloc to stdout and the test compares the result to ensure that the arguments roundtrip through the .bat successfully)


As I said, the test with an empty EnvMap works just fine for me locally, but it failed on all the Windows CI runners (x86_64-debug, x86_64-release, aarch64), so I'm unsure what's happening here.

Would appreciate it if anyone running Windows could patch their windows_bat_args standalone test locally to use the empty EnvMap like so:

        var env = std.process.EnvMap.init(allocator);
        errdefer env.deinit();

and then try reproducing the failure (zig build test within the windows_bat_args subdir would be enough, or zig build test-standalone to run all the standalone tests).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavioros-windowsMicrosoft Windows

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions