[ruby-core:34337] DATA.seek allows to read file

Hi,

I just noticed this:

09:57:58 ~$ allruby /c/Temp/d.rb
CYGWIN_NT-5.1 padrklemme2 1.7.7(0.230/5/3) 2010-08-31 09:58 i686 Cygwin

···

========================================
ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]
"line 1\nline 2\n"
"\np DATA.read\nDATA.seek 0\np DATA.read\n\n__END__\nline 1\nline 2\n"

ruby 1.9.2p136 (2010-12-25 revision 30365) [i386-cygwin]
"line 1\nline 2\n"
"\np DATA.read\nDATA.seek 0\np DATA.read\n\n__END__\nline 1\nline 2\n"

jruby 1.4.0 (ruby 1.8.7 patchlevel 174) (2009-11-02 69fbfa3) (Java
HotSpot(TM) Client VM 1.6.0_23) [x86-java]
"line 1\nline 2\n"
""
09:58:31 ~$ cat /c/Temp/d.rb

p DATA.read
DATA.seek 0
p DATA.read

__END__
line 1
line 2
09:58:37 ~$

In other words, I can read what's before __END__ if I simply seek.
IMHO that is a bad thing and may even be used for attacks.

Btw, I stumbled across this by doing this:

10:01:24 ~$ ruby19 /c/Temp/dd.rb
["require 'csv'"]
[]
["CSV.foreach DATA do |rec|"]
[" p rec"]
["end"]
[]
["__END__"]
["line 1"]
["line 2"]
10:01:33 ~$ cat /c/Temp/dd.rb
require 'csv'

CSV.foreach DATA do |rec|
  p rec
end

__END__
line 1
line 2
10:01:37 ~$

Maybe it's not such a good idea for CSV.foreach to seek to 0 before
starting to read. As a user of CSV I would always want it to start
off where the IO currently points to. James, what do you think?

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

I've written a script in the past that (ab)used that to use DATA as a small datastore, rather than writing out to a separate data file. I had to write out the entire file though, including the source code, so being able to just seek back to 0 and read from there was helpful for writing the script.

C

···

On 11 Jan 2011, at 09:03, Robert Klemme wrote:

In other words, I can read what's before __END__ if I simply seek.
IMHO that is a bad thing and may even be used for attacks.

---
Caius Durling
caius@caius.name
+44 (0) 7960 268 100
http://caius.name/

In other words, I can read what's before __END__ if I simply seek.
IMHO that is a bad thing and may even be used for attacks.

I love the feature. It's one of those fun things to abuse. :slight_smile:

I've written a script in the past that (ab)used that to use DATA as a small datastore…

I've done that too. :slight_smile:

rather than writing out to a separate data file. I had to write out the entire file though, including the source code…

You don't have to rewrite the code, if you are careful:

  #!/usr/bin/env ruby -wKU

  pos = DATA.pos # memorize position after __END__

  # do whatever
  count = DATA.read.to_i
  puts "Count: #{count}"
  count += 1

  DATA.reopen(__FILE__, "a+") # turn on writing mode
  DATA.truncate(pos) # remove the DATA section
  DATA.puts count # update DATA

  __END__
  0

James Edward Gray II

···

On Jan 11, 2011, at 4:55 AM, Caius Durling wrote:

On 11 Jan 2011, at 09:03, Robert Klemme wrote: