| author | |
| committer | |
| log | 21e195a1a96100cd5bcd47b6d9565b2141ad13e1 |
| tree | 30ab776c789eddd447b0a02190d15795734240d5 |
| parent | 2d7d98da0cd54e9dc12c5d4f97cdf2e7dac36446 |
4 files changed, 12 insertions(+), 29 deletions(-)
lib/std/fs/Dir.zig+1-1| ... | ... | @@ -1575,7 +1575,7 @@ pub fn symLink( |
| 1575 | 1575 | // when converting to an NT namespaced path. CreateSymbolicLink in |
| 1576 | 1576 | // symLinkW will handle the necessary conversion. |
| 1577 | 1577 | var target_path_w: windows.PathSpace = undefined; |
| 1578 | try std.unicode.checkWtf8ToWtf16LeOverflow(target_path, &target_path_w.data); | |
| 1578 | try windows.checkWtf8ToWtf16LeOverflow(target_path, &target_path_w.data); | |
| 1579 | 1579 | target_path_w.len = try std.unicode.wtf8ToWtf16Le(&target_path_w.data, target_path); |
| 1580 | 1580 | target_path_w.data[target_path_w.len] = 0; |
| 1581 | 1581 | // However, we need to canonicalize any path separators to `\`, since if |
lib/std/os/windows.zig+9| ... | ... | @@ -5739,3 +5739,12 @@ pub fn ProcessBaseAddress(handle: HANDLE) ProcessBaseAddressError!HMODULE { |
| 5739 | 5739 | const ppeb: *const PEB = @ptrCast(@alignCast(peb_out.ptr)); |
| 5740 | 5740 | return ppeb.ImageBaseAddress; |
| 5741 | 5741 | } |
| 5742 | ||
| 5743 | pub fn checkWtf8ToWtf16LeOverflow(wtf8: []const u8, wtf16le: []const u16) error{ BadPathName, NameTooLong }!void { | |
| 5744 | // Each u8 in UTF-8/WTF-8 correlates to at most one u16 in UTF-16LE/WTF-16LE. | |
| 5745 | if (wtf16le.len >= wtf8.len) return; | |
| 5746 | const utf16_len = std.unicode.calcUtf16LeLenImpl(wtf8, .can_encode_surrogate_half) catch | |
| 5747 | return error.BadPathName; | |
| 5748 | if (utf16_len > wtf16le.len) | |
| 5749 | return error.NameTooLong; | |
| 5750 | } |
lib/std/posix.zig+2-2| ... | ... | @@ -2918,7 +2918,7 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void { |
| 2918 | 2918 | @compileError("WASI does not support os.chdir"); |
| 2919 | 2919 | } else if (native_os == .windows) { |
| 2920 | 2920 | var wtf16_dir_path: [windows.PATH_MAX_WIDE]u16 = undefined; |
| 2921 | try std.unicode.checkWtf8ToWtf16LeOverflow(dir_path, &wtf16_dir_path); | |
| 2921 | try windows.checkWtf8ToWtf16LeOverflow(dir_path, &wtf16_dir_path); | |
| 2922 | 2922 | const len = try std.unicode.wtf8ToWtf16Le(&wtf16_dir_path, dir_path); |
| 2923 | 2923 | return chdirW(wtf16_dir_path[0..len]); |
| 2924 | 2924 | } else { |
| ... | ... | @@ -2935,7 +2935,7 @@ pub fn chdirZ(dir_path: [*:0]const u8) ChangeCurDirError!void { |
| 2935 | 2935 | if (native_os == .windows) { |
| 2936 | 2936 | const dir_path_span = mem.span(dir_path); |
| 2937 | 2937 | var wtf16_dir_path: [windows.PATH_MAX_WIDE]u16 = undefined; |
| 2938 | try std.unicode.checkWtf8ToWtf16LeOverflow(dir_path_span, &wtf16_dir_path); | |
| 2938 | try windows.checkWtf8ToWtf16LeOverflow(dir_path_span, &wtf16_dir_path); | |
| 2939 | 2939 | const len = try std.unicode.wtf8ToWtf16Le(&wtf16_dir_path, dir_path_span); |
| 2940 | 2940 | return chdirW(wtf16_dir_path[0..len]); |
| 2941 | 2941 | } else if (native_os == .wasi and !builtin.link_libc) { |
lib/std/unicode.zig-26| ... | ... | @@ -1809,31 +1809,6 @@ pub fn wtf8ToWtf16Le(wtf16le: []u16, wtf8: []const u8) error{InvalidWtf8}!usize |
| 1809 | 1809 | return utf8ToUtf16LeImpl(wtf16le, wtf8, .can_encode_surrogate_half); |
| 1810 | 1810 | } |
| 1811 | 1811 | |
| 1812 | fn checkUtf8ToUtf16LeOverflowImpl(utf8: []const u8, utf16le: []const u16, comptime surrogates: Surrogates) !void { | |
| 1813 | // Each u8 in UTF-8/WTF-8 correlates to at most one u16 in UTF-16LE/WTF-16LE. | |
| 1814 | if (utf16le.len >= utf8.len) return; | |
| 1815 | const utf16_len = calcUtf16LeLenImpl(utf8, surrogates) catch { | |
| 1816 | return switch (surrogates) { | |
| 1817 | .cannot_encode_surrogate_half => error.InvalidUtf8, | |
| 1818 | .can_encode_surrogate_half => error.InvalidWtf8, | |
| 1819 | }; | |
| 1820 | }; | |
| 1821 | if (utf16_len > utf16le.len) | |
| 1822 | return error.NameTooLong; | |
| 1823 | } | |
| 1824 | ||
| 1825 | /// Checks if calling `utf8ToUtf16Le` would overflow. Might fail if utf8 is not | |
| 1826 | /// valid UTF-8. | |
| 1827 | pub fn checkUtf8ToUtf16LeOverflow(utf8: []const u8, utf16le: []const u16) error{ InvalidUtf8, NameTooLong }!void { | |
| 1828 | return checkUtf8ToUtf16LeOverflowImpl(utf8, utf16le, .cannot_encode_surrogate_half); | |
| 1829 | } | |
| 1830 | ||
| 1831 | /// Checks if calling `utf8ToUtf16Le` would overflow. Might fail if wtf8 is not | |
| 1832 | /// valid WTF-8. | |
| 1833 | pub fn checkWtf8ToWtf16LeOverflow(wtf8: []const u8, wtf16le: []const u16) error{ InvalidWtf8, NameTooLong }!void { | |
| 1834 | return checkUtf8ToUtf16LeOverflowImpl(wtf8, wtf16le, .can_encode_surrogate_half); | |
| 1835 | } | |
| 1836 | ||
| 1837 | 1812 | /// Surrogate codepoints (U+D800 to U+DFFF) are replaced by the Unicode replacement |
| 1838 | 1813 | /// character (U+FFFD). |
| 1839 | 1814 | /// All surrogate codepoints and the replacement character are encoded as three |
| ... | ... | @@ -2040,7 +2015,6 @@ fn testRoundtripWtf8(wtf8: []const u8) !void { |
| 2040 | 2015 | var wtf16_buf: [32]u16 = undefined; |
| 2041 | 2016 | const wtf16_len = try wtf8ToWtf16Le(&wtf16_buf, wtf8); |
| 2042 | 2017 | try testing.expectEqual(wtf16_len, calcWtf16LeLen(wtf8)); |
| 2043 | try checkWtf8ToWtf16LeOverflow(wtf8, &wtf16_buf); | |
| 2044 | 2018 | const wtf16 = wtf16_buf[0..wtf16_len]; |
| 2045 | 2019 | |
| 2046 | 2020 | var roundtripped_buf: [32]u8 = undefined; |