Windows: Fix iterator name buffer size not handling all possible file name components
Each u16 within a file name component can be encoded as up to 3 UTF-8 bytes, so we need to use MAX_NAME_BYTES to account for all possible UTF-8 encoded names. Fixes #8268
This commit is contained in:
parent
33fdc43714
commit
c6ff1a7160
|
@ -58,7 +58,7 @@ pub const MAX_NAME_BYTES = switch (builtin.os.tag) {
|
|||
// Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
|
||||
// If it would require 4 UTF-8 bytes, then there would be a surrogate
|
||||
// pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
|
||||
.windows => os.NAME_MAX * 3,
|
||||
.windows => os.windows.NAME_MAX * 3,
|
||||
else => if (@hasDecl(root, "os") and @hasDecl(root.os, "NAME_MAX"))
|
||||
root.os.NAME_MAX
|
||||
else
|
||||
|
@ -697,7 +697,7 @@ pub const IterableDir = struct {
|
|||
index: usize,
|
||||
end_index: usize,
|
||||
first_iter: bool,
|
||||
name_data: [256]u8,
|
||||
name_data: [MAX_NAME_BYTES]u8,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
|
|
|
@ -703,6 +703,44 @@ test "makePath in a directory that no longer exists" {
|
|||
try testing.expectError(error.FileNotFound, tmp.dir.makePath("sub-path"));
|
||||
}
|
||||
|
||||
fn testFilenameLimits(iterable_dir: IterableDir, maxed_filename: []const u8) !void {
|
||||
// setup, create a dir and a nested file both with maxed filenames, and walk the dir
|
||||
{
|
||||
var maxed_dir = try iterable_dir.dir.makeOpenPath(maxed_filename, .{});
|
||||
defer maxed_dir.close();
|
||||
|
||||
try maxed_dir.writeFile(maxed_filename, "");
|
||||
|
||||
var walker = try iterable_dir.walk(testing.allocator);
|
||||
defer walker.deinit();
|
||||
|
||||
var count: usize = 0;
|
||||
while (try walker.next()) |entry| {
|
||||
try testing.expectEqualStrings(maxed_filename, entry.basename);
|
||||
count += 1;
|
||||
}
|
||||
try testing.expectEqual(@as(usize, 2), count);
|
||||
}
|
||||
|
||||
// ensure that we can delete the tree
|
||||
try iterable_dir.dir.deleteTree(maxed_filename);
|
||||
}
|
||||
|
||||
test "filename limits" {
|
||||
var tmp = tmpIterableDir(.{});
|
||||
defer tmp.cleanup();
|
||||
|
||||
if (builtin.os.tag == .windows) {
|
||||
// € is the character with the largest codepoint that is encoded as a single u16 in UTF-16,
|
||||
// so Windows allows for NAME_MAX of them
|
||||
const maxed_windows_filename = ("€".*) ** std.os.windows.NAME_MAX;
|
||||
try testFilenameLimits(tmp.iterable_dir, &maxed_windows_filename);
|
||||
} else {
|
||||
const maxed_ascii_filename = [_]u8{'1'} ** std.fs.MAX_NAME_BYTES;
|
||||
try testFilenameLimits(tmp.iterable_dir, &maxed_ascii_filename);
|
||||
}
|
||||
}
|
||||
|
||||
test "writev, readv" {
|
||||
var tmp = tmpDir(.{});
|
||||
defer tmp.cleanup();
|
||||
|
|
Loading…
Reference in New Issue
Block a user