Bug #22340
closedWin32: File.stat succeeds on symbolic-link loops on Windows
Description
On Windows, File.stat succeeds on a self-referential symbolic link instead of raising Errno::ELOOP, and File.exist? returns true. Opening the same link raises Errno::ELOOP.
I noticed this while adding symbolic-link tests to FileUtils, whose Windows CI reported the unexpected File.exist? result.
Reproduction¶
require 'tmpdir'
Dir.mktmpdir do |dir|
Dir.chdir(dir) do
File.symlink('a', 'a')
p File.readlink('a') # => "a"
p File.exist?('a') # => true; expected false
p File.stat('a') # succeeds; expected Errno::ELOOP
File.open('a') # raises Errno::ELOOP
ensure
File.unlink('a') if File.symlink?('a')
end
end
File.lstat('a') should continue to succeed and identify the entry as a symbolic link.
Cause¶
In winnt_stat, failure to open the resolved path falls back to stat_by_find unless open_error matches one of the listed errors. The symbolic-link-following implementation introduced in f5b96e594c769cf309b70fd7736caaf90372a3b6 retained this fallback, which was intended to handle sharing violations for files such as pagefile.sys.
ERROR_CANT_RESOLVE_FILENAME is not listed, so a symbolic-link loop also reaches the fallback, which retrieves information about the link itself and reports success.
Updated by nobu (Nobuyoshi Nakada) about 18 hours ago
- Status changed from Open to Closed
Applied in changeset git|ad23fd4a519fde4fc96c7326fb9b0347cbc347b8.
[Bug #22340] Fix stat on symbolic-link loops on Windows
Preserve ELOOP instead of hiding symbolic-link resolution errors
with the file-enumeration fallback, so existence checks return false.
Updated by nagachika (Tomoyuki Chikanaga) about 4 hours ago
- Backport changed from 3.3: REQUIRED, 3.4: REQUIRED, 4.0: REQUIRED to 3.3: REQUIRED, 3.4: DONE, 4.0: REQUIRED
ruby_3_4 7bbe8e88007f8283a421cb31db86da32076126a6 merged revision(s) ad23fd4a519fde4fc96c7326fb9b0347cbc347b8.