1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/csv.rb: Remove the dangerous serialization feature.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39077 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
jeg2 2013-02-05 18:28:26 +00:00
parent 3221e7d29c
commit b614d7823c
4 changed files with 20 additions and 302 deletions

View file

@ -1,3 +1,7 @@
Wed Feb 6 03:27:19 2013 James Edward Gray II <james@graysoftinc.com>
* lib/csv.rb: Remove the dangerous serialization feature.
Wed Feb 6 00:56:00 2013 Zachary Scott <zachary@zacharyscott.net> Wed Feb 6 00:56:00 2013 Zachary Scott <zachary@zacharyscott.net>
* lib/irb.rb: Remove example from restrictions, it works [Github #246] * lib/irb.rb: Remove example from restrictions, it works [Github #246]
@ -4633,7 +4637,7 @@ Thu Nov 29 15:10:45 2012 NARUSE, Yui <naruse@ruby-lang.org>
* test/minitest/test_minitest_unit.rb: restore orig_verbose only * test/minitest/test_minitest_unit.rb: restore orig_verbose only
if it is set. This broke rdoc's tests. if it is set. This broke rdoc's tests.
http://u64.rubyci.org/~chkbuild/ruby-trunk/log/20121129T050102Z.diff.html.gz http://u64.rubyci.org/~chkbuild/ruby-trunk/log/20121129T050102Z.diff.html.gz
Thu Nov 29 14:56:30 2012 Koichi Sasada <ko1@atdot.net> Thu Nov 29 14:56:30 2012 Koichi Sasada <ko1@atdot.net>
@ -8695,7 +8699,7 @@ Fri Sep 28 17:26:27 2012 NARUSE, Yui <naruse@ruby-lang.org>
fails on Windows with msys bash. It makes comparing paths fails on Windows with msys bash. It makes comparing paths
case-insensitive. case-insensitive.
pick from upstream to fix a failure of test-all [ruby-core:47711] pick from upstream to fix a failure of test-all [ruby-core:47711]
https://github.com/rubygems/rubygems/commit/c474edb2f3704206f04da1c8c6cf9fb079d84abe https://github.com/rubygems/rubygems/commit/c474edb2f3704206f04da1c8c6cf9fb079d84abe
Fri Sep 28 15:44:45 2012 Shugo Maeda <shugo@ruby-lang.org> Fri Sep 28 15:44:45 2012 Shugo Maeda <shugo@ruby-lang.org>
@ -10573,7 +10577,7 @@ Sun Jul 22 23:58:48 2012 NARUSE, Yui <naruse@ruby-lang.org>
Sat Jul 21 06:21:45 2012 NARUSE, Yui <naruse@ruby-lang.org> Sat Jul 21 06:21:45 2012 NARUSE, Yui <naruse@ruby-lang.org>
* lib/net/http.rb: fixes for r36476. [Feature #6546] * lib/net/http.rb: fixes for r36476. [Feature #6546]
http://u64.rubyci.org/~chkbuild/ruby-trunk/log/20120720T030101Z.diff.html.gz http://u64.rubyci.org/~chkbuild/ruby-trunk/log/20120720T030101Z.diff.html.gz
* lib/net/http.rb (Net::HTTP.newobj): return back for compatibility. * lib/net/http.rb (Net::HTTP.newobj): return back for compatibility.
@ -12225,7 +12229,7 @@ Wed Jun 13 10:20:27 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* process.c (rb_exec_fillarg): use shell if the first word is reserved * process.c (rb_exec_fillarg): use shell if the first word is reserved
or special built-in name. or special built-in name.
http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
* process.c (rb_exec_fillarg): treat '=' only in the first word. if * process.c (rb_exec_fillarg): treat '=' only in the first word. if
the first word does not contain '=', it is the command name and the first word does not contain '=', it is the command name and
@ -12378,7 +12382,7 @@ Mon Jun 11 06:17:06 2012 NARUSE, Yui <naruse@ruby-lang.org>
* thread_pthread.c (native_cond_initialize): fix typo in r36022. * thread_pthread.c (native_cond_initialize): fix typo in r36022.
this cause a failure on FreeBSD 8.2 amd64. this cause a failure on FreeBSD 8.2 amd64.
http://fbsd.rubyci.org/~chkbuild/ruby-trunk/log/20120610T130201Z.diff.html.gz http://fbsd.rubyci.org/~chkbuild/ruby-trunk/log/20120610T130201Z.diff.html.gz
Mon Jun 11 05:21:57 2012 Koichi Sasada <ko1@atdot.net> Mon Jun 11 05:21:57 2012 Koichi Sasada <ko1@atdot.net>
@ -12457,7 +12461,7 @@ Sun Jun 10 15:49:47 2012 Tanaka Akira <akr@fsij.org>
Sun Jun 10 14:19:33 2012 NARUSE, Yui <naruse@ruby-lang.org> Sun Jun 10 14:19:33 2012 NARUSE, Yui <naruse@ruby-lang.org>
* configure.in: NetBSD 6 adds libexecinfo but it only works on amd64. * configure.in: NetBSD 6 adds libexecinfo but it only works on amd64.
http://www.mail-archive.com/source-changes-full@netbsd.org/msg38729.html http://www.mail-archive.com/source-changes-full@netbsd.org/msg38729.html
Sun Jun 10 12:43:23 2012 Tanaka Akira <akr@fsij.org> Sun Jun 10 12:43:23 2012 Tanaka Akira <akr@fsij.org>
@ -14150,7 +14154,7 @@ Tue May 8 07:44:18 2012 NARUSE, Yui <naruse@ruby-lang.org>
* ext/openssl/ossl_ssl.c (ossl_start_ssl): remove useless rb_sys_fail * ext/openssl/ossl_ssl.c (ossl_start_ssl): remove useless rb_sys_fail
before ossl_raise. this cause a test failure on Linux. before ossl_raise. this cause a test failure on Linux.
http://u64.rubyci.org/~chkbuild/ruby-trunk/log/20120507T190102Z.log.html.gz http://u64.rubyci.org/~chkbuild/ruby-trunk/log/20120507T190102Z.log.html.gz
Tue May 8 05:35:18 2012 Eric Hodel <drbrain@segment7.net> Tue May 8 05:35:18 2012 Eric Hodel <drbrain@segment7.net>
@ -14185,13 +14189,13 @@ Tue May 8 02:34:26 2012 NARUSE, Yui <naruse@ruby-lang.org>
* lib/minitest/unit.rb (assert_match): refix of r35563. * lib/minitest/unit.rb (assert_match): refix of r35563.
r35563 breaks the intention of the original change. r35563 breaks the intention of the original change.
https://github.com/seattlerb/minitest/commit/68858105b2eb11c85105ffac5f32b662c59397f3 https://github.com/seattlerb/minitest/commit/68858105b2eb11c85105ffac5f32b662c59397f3
* lib/minitest/unit.rb (refute_match): ditto. * lib/minitest/unit.rb (refute_match): ditto.
Mon May 7 21:19:17 2012 NARUSE, Yui <naruse@ruby-lang.org> Mon May 7 21:19:17 2012 NARUSE, Yui <naruse@ruby-lang.org>
* ext/json: Merge JSON 1.7.1. * ext/json: Merge JSON 1.7.1.
https://github.com/flori/json/commit/e5b9a9465c1159fae533bca320d950b772bcb4ac https://github.com/flori/json/commit/e5b9a9465c1159fae533bca320d950b772bcb4ac
Mon May 7 22:54:22 2012 Martin Bosslet <Martin.Bosslet@googlemail.com> Mon May 7 22:54:22 2012 Martin Bosslet <Martin.Bosslet@googlemail.com>
@ -14483,7 +14487,7 @@ Fri Apr 27 07:15:07 2012 Tanaka Akira <akr@fsij.org>
* ext/socket/socket.c (sock_s_pack_sockaddr_un): support the longest * ext/socket/socket.c (sock_s_pack_sockaddr_un): support the longest
path in sockaddr_un, really. path in sockaddr_un, really.
reported by nagachika. reported by nagachika.
http://d.hatena.ne.jp/nagachika/20120426/ruby_trunk_changes_35474_35476 http://d.hatena.ne.jp/nagachika/20120426/ruby_trunk_changes_35474_35476
Thu Apr 26 12:28:06 2012 Tanaka Akira <akr@fsij.org> Thu Apr 26 12:28:06 2012 Tanaka Akira <akr@fsij.org>
@ -14648,7 +14652,7 @@ Mon Apr 23 20:11:02 2012 Tanaka Akira <akr@fsij.org>
* lib/drb/ssl.rb: generate 1024 bits RSA key instead of 512 bits. * lib/drb/ssl.rb: generate 1024 bits RSA key instead of 512 bits.
OpenSSL 1.0.1 rejects 512 bits RSA key for TLS1.2 with SHA512. OpenSSL 1.0.1 rejects 512 bits RSA key for TLS1.2 with SHA512.
http://rt.openssl.org/Ticket/Display.html?id=2769&user=guest&pass=guest http://rt.openssl.org/Ticket/Display.html?id=2769&user=guest&pass=guest
reported by Bohuslav Kabrda. reported by Bohuslav Kabrda.
[ruby-core:43844] [ruby-trunk - Bug #6221] [ruby-core:43844] [ruby-trunk - Bug #6221]
@ -15128,7 +15132,7 @@ Sun Apr 8 22:46:01 2012 NARUSE, Yui <naruse@ruby-lang.org>
* ext/json/generator/generator.c (generate_json_bignum): * ext/json/generator/generator.c (generate_json_bignum):
add RB_GC_GUARD. add RB_GC_GUARD.
http://fb.rubyci.org/~chkbuild/ruby-trunk/log/20120407T210301Z.diff.html.gz http://fb.rubyci.org/~chkbuild/ruby-trunk/log/20120407T210301Z.diff.html.gz
Sun Apr 8 07:26:40 2012 NARUSE, Yui <naruse@ruby-lang.org> Sun Apr 8 07:26:40 2012 NARUSE, Yui <naruse@ruby-lang.org>
@ -21871,7 +21875,7 @@ Wed Aug 31 17:28:23 2011 Hiroshi Nakamura <nahi@ruby-lang.org>
* variable.c (rb_autoload_load): Move RB_GC_GUARD() to proper * variable.c (rb_autoload_load): Move RB_GC_GUARD() to proper
position based on suggestion by CHIKANAGA Tomoyuki at position based on suggestion by CHIKANAGA Tomoyuki at
http://d.hatena.ne.jp/nagachika/20110826/ruby_trunk_changes_33070_33078 http://d.hatena.ne.jp/nagachika/20110826/ruby_trunk_changes_33070_33078
* variable.c (autoload_defined_p): Fix incompatible autoload behavior * variable.c (autoload_defined_p): Fix incompatible autoload behavior
that causes Rails crash. Class definition instruction defined in that causes Rails crash. Class definition instruction defined in
@ -22074,8 +22078,8 @@ Sat Aug 27 11:18:12 2011 Hiroshi Nakamura <nahi@ruby-lang.org>
* Revert r33078. It caused a Rails application NoMethodError. * Revert r33078. It caused a Rails application NoMethodError.
/home/nahi/git/emptyApp/ruby/1.9.1/gems/rack-mount-0.6.14/lib/rack/mount/utils.rb:157: warning: toplevel constant ScanError referenced by Regin::Parser::ScanError /home/nahi/git/emptyApp/ruby/1.9.1/gems/rack-mount-0.6.14/lib/rack/mount/utils.rb:157: warning: toplevel constant ScanError referenced by Regin::Parser::ScanError
/home/nahi/git/emptyApp/ruby/1.9.1/gems/rack-mount-0.6.14/lib/rack/mount/vendor/regin/regin/parser.rb:17:in `parse_regexp': undefined method `scan_str' for #<Regin::Parser:0x00000002344548> (NoMethodError) /home/nahi/git/emptyApp/ruby/1.9.1/gems/rack-mount-0.6.14/lib/rack/mount/vendor/regin/regin/parser.rb:17:in `parse_regexp': undefined method `scan_str' for #<Regin::Parser:0x00000002344548> (NoMethodError)
Sat Aug 27 08:44:58 2011 Eric Hodel <drbrain@segment7.net> Sat Aug 27 08:44:58 2011 Eric Hodel <drbrain@segment7.net>
@ -22669,7 +22673,7 @@ Sun Aug 7 00:42:55 2011 NARUSE, Yui <naruse@ruby-lang.org>
* ext/tk/lib/tk/wm.rb (Tk::Wm.command): Add the missing receiver * ext/tk/lib/tk/wm.rb (Tk::Wm.command): Add the missing receiver
before calling epath. patched by flori before calling epath. patched by flori
https://github.com/flori/ruby/commit/aa9474d32e5f2c57f8b0e2e0c528a03f06a4d433 https://github.com/flori/ruby/commit/aa9474d32e5f2c57f8b0e2e0c528a03f06a4d433
Sat Aug 6 07:06:34 2011 Eric Hodel <drbrain@segment7.net> Sat Aug 6 07:06:34 2011 Eric Hodel <drbrain@segment7.net>

View file

@ -1050,133 +1050,6 @@ class CSV
end end
end end
#
# This method allows you to serialize an Array of Ruby objects to a String or
# File of CSV data. This is not as powerful as Marshal or YAML, but perhaps
# useful for spreadsheet and database interaction.
#
# Out of the box, this method is intended to work with simple data objects or
# Structs. It will serialize a list of instance variables and/or
# Struct.members().
#
# If you need need more complicated serialization, you can control the process
# by adding methods to the class to be serialized.
#
# A class method csv_meta() is responsible for returning the first row of the
# document (as an Array). This row is considered to be a Hash of the form
# key_1,value_1,key_2,value_2,... CSV::load() expects to find a class key
# with a value of the stringified class name and CSV::dump() will create this,
# if you do not define this method. This method is only called on the first
# object of the Array.
#
# The next method you can provide is an instance method called csv_headers().
# This method is expected to return the second line of the document (again as
# an Array), which is to be used to give each column a header. By default,
# CSV::load() will set an instance variable if the field header starts with an
# @ character or call send() passing the header as the method name and
# the field value as an argument. This method is only called on the first
# object of the Array.
#
# Finally, you can provide an instance method called csv_dump(), which will
# be passed the headers. This should return an Array of fields that can be
# serialized for this object. This method is called once for every object in
# the Array.
#
# The +io+ parameter can be used to serialize to a File, and +options+ can be
# anything CSV::new() accepts.
#
def self.dump(ary_of_objs, io = "", options = Hash.new)
obj_template = ary_of_objs.first
csv = new(io, options)
# write meta information
begin
csv << obj_template.class.csv_meta
rescue NoMethodError
csv << [:class, obj_template.class]
end
# write headers
begin
headers = obj_template.csv_headers
rescue NoMethodError
headers = obj_template.instance_variables.sort
if obj_template.class.ancestors.find { |cls| cls.to_s =~ /\AStruct\b/ }
headers += obj_template.members.map { |mem| "#{mem}=" }.sort
end
end
csv << headers
# serialize each object
ary_of_objs.each do |obj|
begin
csv << obj.csv_dump(headers)
rescue NoMethodError
csv << headers.map do |var|
if var[0] == ?@
obj.instance_variable_get(var)
else
obj[var[0..-2]]
end
end
end
end
if io.is_a? String
csv.string
else
csv.close
end
end
#
# This method is the reading counterpart to CSV::dump(). See that method for
# a detailed description of the process.
#
# You can customize loading by adding a class method called csv_load() which
# will be passed a Hash of meta information, an Array of headers, and an Array
# of fields for the object the method is expected to return.
#
# Remember that all fields will be Strings after this load. If you need
# something else, use +options+ to setup converters or provide a custom
# csv_load() implementation.
#
def self.load(io_or_str, options = Hash.new)
csv = new(io_or_str, options)
# load meta information
meta = Hash[*csv.shift]
cls = meta["class".encode(csv.encoding)].split("::".encode(csv.encoding)).
inject(Object) do |c, const|
c.const_get(const)
end
# load headers
headers = csv.shift
# unserialize each object stored in the file
results = csv.inject(Array.new) do |all, row|
begin
obj = cls.csv_load(meta, headers, row)
rescue NoMethodError
obj = cls.allocate
headers.zip(row) do |name, value|
if name[0] == ?@
obj.instance_variable_set(name, value)
else
obj.send(name, value)
end
end
end
all << obj
end
csv.close unless io_or_str.is_a? String
results
end
# #
# :call-seq: # :call-seq:
# filter( options = Hash.new ) { |row| ... } # filter( options = Hash.new ) { |row| ... }

View file

@ -1,158 +0,0 @@
#!/usr/bin/env ruby -w
# encoding: UTF-8
# tc_serialization.rb
#
# Created by James Edward Gray II on 2005-10-31.
# Copyright 2005 James Edward Gray II. You can redistribute or modify this code
# under the terms of Ruby's license.
require_relative "base"
require "tempfile"
# An example of how to provide custom CSV serialization.
class Hash
def self.csv_load( meta, headers, fields )
self[*headers.zip(fields).to_a.flatten.map { |e| eval(e) }]
end
def csv_headers
keys.map { |key| key.inspect }
end
def csv_dump( headers )
headers.map { |header| fetch(eval(header)).inspect }
end
end
class TestCSV::Serialization < TestCSV
extend DifferentOFS
### Classes Used to Test Serialization ###
class ReadOnlyName
def initialize( first, last )
@first, @last = first, last
end
attr_reader :first, :last
def ==( other )
%w{first last}.all? { |att| send(att) == other.send(att) }
end
end
Name = Struct.new(:first, :last)
class FullName < Name
def initialize( first, last, suffix = nil )
super(first, last)
@suffix = suffix
end
attr_accessor :suffix
def ==( other )
%w{first last suffix}.all? { |att| send(att) == other.send(att) }
end
end
### Tests ###
def test_class_dump
@names = [ %w{James Gray},
%w{Dana Gray},
%w{Greg Brown} ].map do |first, last|
ReadOnlyName.new(first, last)
end
assert_nothing_raised(Exception) do
@data = CSV.dump(@names)
end
assert_equal(<<-END_CLASS_DUMP.gsub(/^\s*/, ""), @data)
class,TestCSV::Serialization::ReadOnlyName
@first,@last
James,Gray
Dana,Gray
Greg,Brown
END_CLASS_DUMP
end
def test_struct_dump
@names = [ %w{James Gray},
%w{Dana Gray},
%w{Greg Brown} ].map do |first, last|
Name.new(first, last)
end
assert_nothing_raised(Exception) do
@data = CSV.dump(@names)
end
assert_equal(<<-END_STRUCT_DUMP.gsub(/^\s*/, ""), @data)
class,TestCSV::Serialization::Name
first=,last=
James,Gray
Dana,Gray
Greg,Brown
END_STRUCT_DUMP
end
def test_inherited_struct_dump
@names = [ %w{James Gray II},
%w{Dana Gray},
%w{Greg Brown} ].map do |first, last, suffix|
FullName.new(first, last, suffix)
end
assert_nothing_raised(Exception) do
@data = CSV.dump(@names)
end
assert_equal(<<-END_STRUCT_DUMP.gsub(/^\s*/, ""), @data)
class,TestCSV::Serialization::FullName
@suffix,first=,last=
II,James,Gray
,Dana,Gray
,Greg,Brown
END_STRUCT_DUMP
end
def test_load
%w{ test_class_dump
test_struct_dump
test_inherited_struct_dump }.each do |test|
send(test)
CSV.load(@data).each do |loaded|
assert_instance_of(@names.first.class, loaded)
assert_equal(@names.shift, loaded)
end
end
end
def test_io
test_class_dump
tempfile = Tempfile.new(%w"serialization .csv")
tempfile.close
data_file = tempfile.path
CSV.dump(@names, File.open(data_file, "wb"))
assert(File.exist?(data_file))
assert_equal(<<-END_IO_DUMP.gsub(/^\s*/, ""), File.read(data_file))
class,TestCSV::Serialization::ReadOnlyName
@first,@last
James,Gray
Dana,Gray
Greg,Brown
END_IO_DUMP
assert_equal(@names, CSV.load(File.open(data_file)))
tempfile.close(true)
end
def test_custom_dump_and_load
obj = {1 => "simple", test: Hash}
assert_equal(obj, CSV.load(CSV.dump([obj])).first)
end
end

View file

@ -17,5 +17,4 @@ require "test_data_converters"
require "test_row" require "test_row"
require "test_table" require "test_table"
require "test_headers" require "test_headers"
require "test_serialization"
require "test_encodings" require "test_encodings"