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

Cleared environment variables still visible via PTY.spawn #2888

Open
rampion opened this issue Apr 29, 2015 · 0 comments
Open

Cleared environment variables still visible via PTY.spawn #2888

rampion opened this issue Apr 29, 2015 · 0 comments
Assignees

Comments

@rampion
Copy link

rampion commented Apr 29, 2015

I've found a bug with JRuby's ENV constant's #[]= and #delete methods.
Environment variables cleared via ENV["FOO"] = nil or ENV.delete("FOO"),
are still set to their pre-cleared value under certain conditions.

In particular, you can still see the pre-cleared value in a PTY terminal
spawned after the environment variable was cleared. This is in contrast
to subshells started via backtick, system, or exec, where the cleared
value does not seem to be visible.

Using the example.rb code defined at the end:

$ jruby example.rb
originally : {:pty=>nil, :backtick=>nil, :env=>nil}
clearing via ENV["FOO"] = nil
        after set   : {:pty=>"something", :backtick=>"something", :env=>"something"}
        after clear : {:pty=>"something", :backtick=>nil, :env=>nil}
clearing via ENV["FOO"] = ""
        after set   : {:pty=>"something else", :backtick=>"something else", :env=>"something else"}
        after clear : {:pty=>"", :backtick=>"", :env=>""}
clearing via ENV.delete("FOO")
        after set   : {:pty=>"yet something else", :backtick=>"yet something else", :env=>"yet something else"}
        after clear : {:pty=>"yet something else", :backtick=>nil, :env=>nil}

Note how the environment made available to the pty still has the old value of $FOO.

In contrast, MRI ruby does not leak the old environment variable to the PTY terminal:

$ mriruby example.rb
originally : {:pty=>nil, :backtick=>nil, :env=>nil}
clearing via ENV["FOO"] = nil
        after set   : {:pty=>"something", :backtick=>"something", :env=>"something"}
        after clear : {:pty=>nil, :backtick=>nil, :env=>nil}
clearing via ENV["FOO"] = ""
        after set   : {:pty=>"something else", :backtick=>"something else", :env=>"something else"}
        after clear : {:pty=>"", :backtick=>"", :env=>""}
clearing via ENV.delete("FOO")
        after set   : {:pty=>"yet something else", :backtick=>"yet something else", :env=>"yet something else"}
        after clear : {:pty=>nil, :backtick=>nil, :env=>nil}

Example code follows:

# example.rb
require 'tempfile'
require 'pty'

COMMAND = %!ruby -e "p ENV['FOO']"!

def test
  tf = Tempfile.new 'output'
  output = begin
             stdout, stdin, pid = PTY.spawn "#{COMMAND} | tee #{tf.path}"
             stdout.read
           rescue Errno::EIO, IOError
             tf.read
           ensure
             tf.close
             Process.wait pid
           end
  { :pty => eval(output), :backtick => eval(`#{COMMAND}`), :env => ENV["FOO"] }
end

original = ENV["FOO"]
puts "originally : #{test.inspect}"

puts 'clearing via ENV["FOO"] = nil'
ENV["FOO"] = "something"
puts "\tafter set   : #{test.inspect}"
ENV["FOO"] = nil
puts "\tafter clear : #{test.inspect}"

puts 'clearing via ENV["FOO"] = ""'
ENV["FOO"] = "something else"
puts "\tafter set   : #{test.inspect}"
ENV["FOO"] = ""
puts "\tafter clear : #{test.inspect}"

puts 'clearing via ENV.delete("FOO")'
ENV["FOO"] = "yet something else"
puts "\tafter set   : #{test.inspect}"
ENV.delete "FOO"
puts "\tafter clear : #{test.inspect}"
@byteit101 byteit101 self-assigned this Jan 22, 2023
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

2 participants