From ba1a8b64c44b9b99e9f0002555b9b4a35092e8f6 Mon Sep 17 00:00:00 2001 From: Ilmari Autio Date: Mon, 2 Mar 2020 23:15:36 +0200 Subject: [PATCH] make std.os.getenvW case insensitive partially addresses #4603 Fixing std.process.getEnvMap is NOT included in this commit. --- lib/std/os.zig | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/std/os.zig b/lib/std/os.zig index 467badca95..07d4c19a89 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -21,6 +21,7 @@ const assert = std.debug.assert; const math = std.math; const mem = std.mem; const elf = std.elf; +const unicode = std.unicode; const dl = @import("dynamic_library.zig"); const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES; @@ -1206,6 +1207,19 @@ pub fn getenvZ(key: [*:0]const u8) ?[]const u8 { return getenv(mem.spanZ(key)); } +fn utf16LeAsciiEqlIgnoreCase(a: []const u16, b: []const u16) bool { + if (a.len != b.len) return false; + var a_it = unicode.Utf16LeIterator.init(a); + var b_it = unicode.Utf16LeIterator.init(b); + while (a_it.nextCodepoint() catch return false) |a_codepoint| { + const b_codepoint = (b_it.nextCodepoint() catch return false) orelse return false; + const upper_a = if (a_codepoint >= 97 and a_codepoint <= 122) a_codepoint & 0b11011111 else a_codepoint; + const upper_b = if (b_codepoint >= 97 and b_codepoint <= 122) b_codepoint & 0b11011111 else b_codepoint; + if (upper_a != upper_b) return false; + } + return true; +} + /// Windows-only. Get an environment variable with a null-terminated, WTF-16 encoded name. /// See also `getenv`. pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 { @@ -1227,7 +1241,7 @@ pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 { while (ptr[i] != 0) : (i += 1) {} const this_value = ptr[value_start..i :0]; - if (mem.eql(u16, key_slice, this_key)) return this_value; + if (utf16LeAsciiEqlIgnoreCase(key_slice, this_key)) return this_value; i += 1; // skip over null byte }