From b614d7823c4d3dcb263577127db5e7e333573a4e Mon Sep 17 00:00:00 2001 From: jeg2 Date: Tue, 5 Feb 2013 18:28:26 +0000 Subject: * 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 --- lib/csv.rb | 127 ------------------------------------------------------------- 1 file changed, 127 deletions(-) (limited to 'lib/csv.rb') diff --git a/lib/csv.rb b/lib/csv.rb index 279890e7e0..fe153153be 100644 --- a/lib/csv.rb +++ b/lib/csv.rb @@ -1050,133 +1050,6 @@ class CSV 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: # filter( options = Hash.new ) { |row| ... } -- cgit v1.2.3