Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite loop in read() on directory file handle on at least some non-C locales #8096

Open
mstock opened this issue Feb 9, 2024 · 0 comments

Comments

@mstock
Copy link

mstock commented Feb 9, 2024

Environment Information

  • JRuby versions:
    • jruby 9.3.9.0 (2.6.8) 2023-01-16 9.3.9.0+ds-8 OpenJDK 64-Bit Server VM 17.0.10+7-Debian-1deb12u1 on 17.0.10+7-Debian-1deb12u1 +jit [x86_64-linux] from Debian Bookworm
    • jruby 9.4.3.0 (3.1.4) 2023-12-20 9.4.3.0+ds OpenJDK 64-Bit Server VM 17.0.10+7-Debian-1 on 17.0.10+7-Debian-1 +jit [x86_64-linux] from Debian Experimental installed in a Debian Sid chroot
  • Empty JRUBY_OPTS and no command line flags used.
  • Operating system and platform: Linux [...] 6.1.0-17-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.69-1 (2023-12-30) x86_64 GNU/Linux

Other relevant info:

  • Environment variables:
    • LANG=de_CH.utf8 or LANG=de_CH.UTF-8
    • LANGUAGE=de_CH:de in some of the environments where I observed this

Expected Behavior

When opening a directory using File.open() and read()ing from it, I'd expect some kind of error, exception or so, since that should not work. For example, the following code fragment stored in a file called example.rb throws an exception when run with regular Ruby:

File.open('.').read(1)

Running with ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux-gnu]:

$ ruby example.rb 
example.rb:1:in `read': Is a directory @ io_fread - . (Errno::EISDIR)
        from example.rb:1:in `<main>'

Or running it with JRuby under the C locale:

$ LANG=C jruby example.rb 
Errno::EISDIR: Is a directory - .
    read at org/jruby/RubyIO.java:3248
    read at org/jruby/RubyIO.java:3203
  <main> at example.rb:1

Actual Behavior

Running the above script under my regular de_CH.utf8 locale (but I see the same behavior with e.g. LANG=en_US.UTF-8 or LANG=C.utf8/LANG=C.UTF-8 on my system, too - unsetting the LANGUAGE environment variable makes them work though), it does not throw an exception but just runs indefinitely and hangs using ~100% of one CPU core.

I noticed this issue when using Puppet Server running on JRuby on a machine which is using the de_CH.UTF-8 locale to deploy a directory structure containing a directory and a symbolic link to it. Puppet Server apparently tries to calculate a checksum over the linked directory in this case which is thus File.open()ed and read() from and appears to rely on read() throwing an exception, however, since read() never returned in this setup, Puppet Server just hung indefinitely.

My current, uneducated guess why JRuby behaves this way would be the current logic used to map certain exceptions to Errno.* constants which I assume to currently fail to do the right thing on at least some locales different from C.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant