authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-03-16 12:01:41+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-18 13:45:52-04:00
loge15605e1c1f28e06035a6740619295151195dabb
tree509c20a421f00f663da4f52e5503e260905bfa85
parent4843c3b4c386008418ff8ab7238feebab3711352
signaturelock-open Commit is signed but in an unrecognized format.

std: Safety check for iterate()

Calling iterate() on a Dir object returned by openDirTraverse is always an error.

1 files changed, 30 insertions(+), 0 deletions(-)

lib/std/fs.zig+30
...@@ -555,6 +555,36 @@ pub const Dir = struct {...@@ -555,6 +555,36 @@ pub const Dir = struct {
555 };555 };
556556
557 pub fn iterate(self: Dir) Iterator {557 pub fn iterate(self: Dir) Iterator {
558 // Make sure the directory was not open with openDirTraverse
559 if (std.debug.runtime_safety) {
560 var ok = true;
561
562 if (builtin.os.tag == .windows) {
563 const w = os.windows;
564
565 var io_status_block: w.IO_STATUS_BLOCK = undefined;
566 var info: w.FILE_ACCESS_INFORMATION = undefined;
567
568 const rc = w.ntdll.NtQueryInformationFile(
569 self.fd,
570 &io_status_block,
571 &info,
572 @sizeOf(w.FILE_ACCESS_INFORMATION),
573 .FileAccessInformation,
574 );
575 assert(rc == .SUCCESS);
576
577 ok = (info.AccessFlags & w.FILE_LIST_DIRECTORY) != 0;
578 } else if (@hasDecl(os, "O_PATH")) {
579 const f = os.fcntl(self.fd, os.F_GETFL, 0) catch unreachable;
580 ok = (f & os.O_PATH) == 0;
581 }
582
583 if (!ok) {
584 std.debug.panic("iterate() called on Dir open with openDirTraverse", .{});
585 }
586 }
587
558 switch (builtin.os.tag) {588 switch (builtin.os.tag) {
559 .macosx, .ios, .freebsd, .netbsd, .dragonfly => return Iterator{589 .macosx, .ios, .freebsd, .netbsd, .dragonfly => return Iterator{
560 .dir = self,590 .dir = self,