diff -Nru ruby-bindata-2.3.5/bindata.gemspec ruby-bindata-2.4.8/bindata.gemspec --- ruby-bindata-2.3.5/bindata.gemspec 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/bindata.gemspec 2020-09-27 14:31:03.000000000 +0000 @@ -9,16 +9,14 @@ s.author = 'Dion Mendel' s.email = 'bindata@dm9.info' s.homepage = 'http://github.com/dmendel/bindata' - s.rubyforge_project = 'bindata' s.require_path = 'lib' - s.has_rdoc = true s.extra_rdoc_files = ['NEWS.rdoc'] s.rdoc_options << '--main' << 'NEWS.rdoc' s.files = `git ls-files`.split("\n") s.license = 'Ruby' s.add_development_dependency('rake') - s.add_development_dependency('minitest', "> 5.0.0") + s.add_development_dependency('minitest', "> 5.0.0", "< 5.12.0") s.add_development_dependency('coveralls') s.description = <<-END.gsub(/^ +/, "") BinData is a declarative way to read and write binary file formats. diff -Nru ruby-bindata-2.3.5/ChangeLog.rdoc ruby-bindata-2.4.8/ChangeLog.rdoc --- ruby-bindata-2.3.5/ChangeLog.rdoc 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/ChangeLog.rdoc 2020-09-27 14:31:03.000000000 +0000 @@ -1,5 +1,48 @@ = BinData Changelog +== Version 2.4.8 (2020-07-21) + +* Bug fix array self assignment. Thanks to Spencer McIntyre. +* Bug fix Stringz max_length. Thanks to cdelafuente-r7. + +== Version 2.4.7 (2020-03-31) + +* Fix choice assignment inside arrays. Reported by Spencer McIntyre. + +== Version 2.4.6 (2020-02-27) + +* More encoding fixes. Thanks to Aaron Patterson. + +== Version 2.4.5 (2020-02-21) + +* Small typo fixes to examples. +* Fix encoding issue for ruby 2.7. Thanks to Aaron Patterson. +* Quieter test output. + +== Version 2.4.4 (2018-10-03) + +* Display a hint when endian is omitted. Requested by Tails. +* Add thread safety to Integer/BitField creation. Requested by jbpeirce. +* Ensure windows sockets are unseekable. Thanks to Brent Cook. + +== Version 2.4.3 (2018-03-10) + +* Add Uint8Arrays. Requested by masarakki. + +== Version 2.4.2 (2018-01-31) + +* Allow boolean values as parameters. Requested by Patrik Wenger. + +== Version 2.4.1 (2017-08-30) + +* Fix crash with String :length invoking :rel_offset. Reported by Claudius + Coenen. + +== Version 2.4.0 (2017-04-09) + +* Reworked internal sanitizing API. +* Fix bit-based integers inside buffers. Reported by Claudius Coenen. + == Version 2.3.5 (2017-01-19) * Enforce Integer#nbits > 0. Reported by Keenan Tims. diff -Nru ruby-bindata-2.3.5/debian/changelog ruby-bindata-2.4.8/debian/changelog --- ruby-bindata-2.3.5/debian/changelog 2017-01-26 23:17:20.000000000 +0000 +++ ruby-bindata-2.4.8/debian/changelog 2020-11-03 01:22:33.000000000 +0000 @@ -1,3 +1,35 @@ +ruby-bindata (2.4.8-1) unstable; urgency=medium + + * Team Upload + + [ Utkarsh Gupta ] + * Add salsa-ci.yml + + [ Debian Janitor ] + * Use secure copyright file specification URI. + * Use secure URI in debian/watch. + * Use secure URI in Homepage field. + * Bump debhelper from old 9 to 12. + * Set debhelper-compat version in Build-Depends. + * Set upstream metadata fields: Bug-Database, Bug-Submit, Repository, + Repository-Browse. + * Update Vcs-* headers from URL redirect. + * Use canonical URL in Vcs-Git. + + [ Cédric Boutillier ] + * [ci skip] Update team name + * [ci skip] Add .gitattributes to keep unwanted files out of the source + package + + [ Abraham Raji ] + * New upstream version 2.4.8 + * pkg-ruby-extras.alioth.debian.org => gemwatch + * Bumps debhelper-compat version to 13 + * Declares compliance with standards version 4.5.0 + * Added Rules-Requires-Root: no + + -- Abraham Raji Tue, 03 Nov 2020 01:22:33 +0000 + ruby-bindata (2.3.5-1) unstable; urgency=medium * Team upload. diff -Nru ruby-bindata-2.3.5/debian/compat ruby-bindata-2.4.8/debian/compat --- ruby-bindata-2.3.5/debian/compat 2017-01-26 23:17:20.000000000 +0000 +++ ruby-bindata-2.4.8/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -9 diff -Nru ruby-bindata-2.3.5/debian/control ruby-bindata-2.4.8/debian/control --- ruby-bindata-2.3.5/debian/control 2017-01-26 23:17:20.000000000 +0000 +++ ruby-bindata-2.4.8/debian/control 2020-11-03 01:22:33.000000000 +0000 @@ -1,17 +1,18 @@ Source: ruby-bindata Section: ruby Priority: optional -Maintainer: Debian Ruby Extras Maintainers +Maintainer: Debian Ruby Team Uploaders: Pirate Praveen -Build-Depends: debhelper (>= 9~), +Build-Depends: debhelper-compat (= 13), gem2deb, rake -Standards-Version: 3.9.8 -Vcs-Git: https://anonscm.debian.org/git/pkg-ruby-extras/ruby-bindata.git -Vcs-Browser: https://anonscm.debian.org/cgit/pkg-ruby-extras/ruby-bindata.git -Homepage: http://github.com/dmendel/bindata +Standards-Version: 4.5.0 +Vcs-Git: https://salsa.debian.org/ruby-team/ruby-bindata.git +Vcs-Browser: https://salsa.debian.org/ruby-team/ruby-bindata +Homepage: https://github.com/dmendel/bindata Testsuite: autopkgtest-pkg-ruby XS-Ruby-Versions: all +Rules-Requires-Root: no Package: ruby-bindata Architecture: all diff -Nru ruby-bindata-2.3.5/debian/copyright ruby-bindata-2.4.8/debian/copyright --- ruby-bindata-2.3.5/debian/copyright 2017-01-26 23:17:20.000000000 +0000 +++ ruby-bindata-2.4.8/debian/copyright 2020-11-03 01:22:33.000000000 +0000 @@ -1,4 +1,4 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: bindata Source: http://github.com/dmendel/bindata diff -Nru ruby-bindata-2.3.5/debian/upstream/metadata ruby-bindata-2.4.8/debian/upstream/metadata --- ruby-bindata-2.3.5/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ ruby-bindata-2.4.8/debian/upstream/metadata 2020-11-03 01:22:33.000000000 +0000 @@ -0,0 +1,4 @@ +Bug-Database: https://github.com/dmendel/bindata/issues +Bug-Submit: https://github.com/dmendel/bindata/issues/new +Repository: https://github.com/dmendel/bindata.git +Repository-Browse: https://github.com/dmendel/bindata diff -Nru ruby-bindata-2.3.5/debian/watch ruby-bindata-2.4.8/debian/watch --- ruby-bindata-2.3.5/debian/watch 2017-01-26 23:17:20.000000000 +0000 +++ ruby-bindata-2.4.8/debian/watch 2020-11-03 01:22:33.000000000 +0000 @@ -1,2 +1,2 @@ -version=3 -http://pkg-ruby-extras.alioth.debian.org/cgi-bin/gemwatch/bindata .*/bindata-(.*).tar.gz +version=4 +https://gemwatch.debian.net/bindata .*/bindata-(.*).tar.gz diff -Nru ruby-bindata-2.3.5/examples/tcp_ip.rb ruby-bindata-2.4.8/examples/tcp_ip.rb --- ruby-bindata-2.3.5/examples/tcp_ip.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/examples/tcp_ip.rb 2020-09-27 14:31:03.000000000 +0000 @@ -14,7 +14,7 @@ array :octets, type: :uint8, initial_length: 6 def set(val) - self.octets = val.split(/\./).collect(&:to_i) + self.octets = val.split(/:/).collect(&:to_i) end def get @@ -23,7 +23,7 @@ end # Present IP addresses in a human readable way -class IPAddr < BinData::Primitive +class IP_Addr < BinData::Primitive array :octets, type: :uint8, initial_length: 4 def set(val) diff -Nru ruby-bindata-2.3.5/lib/bindata/array.rb ruby-bindata-2.4.8/lib/bindata/array.rb --- ruby-bindata-2.3.5/lib/bindata/array.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/array.rb 2020-09-27 14:31:03.000000000 +0000 @@ -80,9 +80,11 @@ end def assign(array) + return if self.equal?(array) # prevent self assignment raise ArgumentError, "can't set a nil value for #{debug_name}" if array.nil? - @element_list = to_storage_formats(array.to_ary) + @element_list = [] + concat(array) end def snapshot @@ -119,7 +121,17 @@ def insert(index, *objs) extend_array(index - 1) - elements.insert(index, *to_storage_formats(objs)) + abs_index = (index >= 0) ? index : index + 1 + length + + # insert elements before... + new_elements = objs.map { new_element } + elements.insert(index, *new_elements) + + # ...assigning values + objs.each_with_index do |obj, i| + self[abs_index + i] = obj + end + self end @@ -238,10 +250,6 @@ end end - def to_storage_formats(els) - els.collect { |el| new_element(el) } - end - def elements @element_list ||= [] end @@ -252,8 +260,8 @@ element end - def new_element(value = nil) - @element_prototype.instantiate(value, self) + def new_element + @element_prototype.instantiate(nil, self) end def sum_num_bytes_for_all_elements @@ -275,9 +283,8 @@ class ArrayArgProcessor < BaseArgProcessor def sanitize_parameters!(obj_class, params) #:nodoc: - unless params.has_parameter?(:initial_length) || - params.has_parameter?(:read_until) - # ensure one of :initial_length and :read_until exists + # ensure one of :initial_length and :read_until exists + unless params.has_at_least_one_of?(:initial_length, :read_until) params[:initial_length] = 0 end @@ -286,11 +293,7 @@ params.must_be_integer(:initial_length) params.merge!(obj_class.dsl_params) - - if params.needs_sanitizing?(:type) - el_type, el_params = params[:type] - params[:type] = params.create_sanitized_object_prototype(el_type, el_params) - end + params.sanitize_object_prototype(:type) end end @@ -300,8 +303,7 @@ loop do element = append_new_element element.do_read(io) - variables = { index: self.length - 1, element: self.last, - array: self } + variables = { index: self.length - 1, element: self.last, array: self } break if eval_parameter(:read_until, variables) end end diff -Nru ruby-bindata-2.3.5/lib/bindata/base_primitive.rb ruby-bindata-2.4.8/lib/bindata/base_primitive.rb --- ruby-bindata-2.3.5/lib/bindata/base_primitive.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/base_primitive.rb 2020-09-27 14:31:03.000000000 +0000 @@ -73,12 +73,13 @@ raise ArgumentError, "can't set a nil value for #{debug_name}" if val.nil? raw_val = val.respond_to?(:snapshot) ? val.snapshot : val - @value = begin - raw_val.dup - rescue TypeError - # can't dup Fixnums - raw_val - end + @value = + begin + raw_val.dup + rescue TypeError + # can't dup Fixnums + raw_val + end end def snapshot @@ -101,9 +102,10 @@ def method_missing(symbol, *args, &block) #:nodoc: child = snapshot if child.respond_to?(symbol) - self.class.class_eval "def #{symbol}(*args, &block);" \ - " snapshot.#{symbol}(*args, &block);" \ - "end" + self.class.class_eval \ + "def #{symbol}(*args, &block);" \ + " snapshot.#{symbol}(*args, &block);" \ + "end" child.__send__(symbol, *args, &block) else super @@ -179,13 +181,14 @@ current_value = snapshot expected = eval_parameter(:assert, value: current_value) - msg = if !expected - "value '#{current_value}' not as expected" - elsif expected != true && current_value != expected - "value is '#{current_value}' but expected '#{expected}'" - else - nil - end + msg = + if !expected + "value '#{current_value}' not as expected" + elsif expected != true && current_value != expected + "value is '#{current_value}' but expected '#{expected}'" + else + nil + end raise ValidityError, "#{msg} for #{debug_name}" if msg end diff -Nru ruby-bindata-2.3.5/lib/bindata/base.rb ruby-bindata-2.4.8/lib/bindata/base.rb --- ruby-bindata-2.3.5/lib/bindata/base.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/base.rb 2020-09-27 14:31:03.000000000 +0000 @@ -172,8 +172,7 @@ def to_binary_s(&block) io = BinData::IO.create_string_io write(io, &block) - io.rewind - io.read + io.string end # Returns the hexadecimal string representation of this data object. diff -Nru ruby-bindata-2.3.5/lib/bindata/bits.rb ruby-bindata-2.4.8/lib/bindata/bits.rb --- ruby-bindata-2.3.5/lib/bindata/bits.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/bits.rb 2020-09-27 14:31:03.000000000 +0000 @@ -1,3 +1,4 @@ +require 'thread' require 'bindata/base_primitive' module BinData @@ -5,14 +6,18 @@ # The integer is defined by endian and number of bits. module BitField #:nodoc: all + @@mutex = Mutex.new + class << self def define_class(name, nbits, endian, signed = :unsigned) - unless BinData.const_defined?(name) - BinData.module_eval <<-END - class #{name} < BinData::BasePrimitive - BitField.define_methods(self, #{nbits.inspect}, #{endian.inspect}, #{signed.inspect}) - end - END + @@mutex.synchronize do + unless BinData.const_defined?(name) + new_class = Class.new(BinData::BasePrimitive) + BitField.define_methods(new_class, nbits, endian.to_sym, signed.to_sym) + RegisteredClasses.register(name, new_class) + + BinData.const_set(name, new_class) + end end BinData.const_get(name) diff -Nru ruby-bindata-2.3.5/lib/bindata/buffer.rb ruby-bindata-2.4.8/lib/bindata/buffer.rb --- ruby-bindata-2.3.5/lib/bindata/buffer.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/buffer.rb 2020-09-27 14:31:03.000000000 +0000 @@ -110,13 +110,8 @@ def sanitize_parameters!(obj_class, params) params.merge!(obj_class.dsl_params) - params.must_be_integer(:length) - - if params.needs_sanitizing?(:type) - el_type, el_params = params[:type] - params[:type] = params.create_sanitized_object_prototype(el_type, el_params) - end + params.sanitize_object_prototype(:type) end end end diff -Nru ruby-bindata-2.3.5/lib/bindata/choice.rb ruby-bindata-2.4.8/lib/bindata/choice.rb --- ruby-bindata-2.3.5/lib/bindata/choice.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/choice.rb 2020-09-27 14:31:03.000000000 +0000 @@ -122,10 +122,10 @@ def sanitize_parameters!(obj_class, params) #:nodoc: params.merge!(obj_class.dsl_params) - if params.needs_sanitizing?(:choices) - choices = choices_as_hash(params[:choices]) - ensure_valid_keys(choices) - params[:choices] = params.create_sanitized_choices(choices) + params.sanitize_choices(:choices) do |choices| + hash_choices = choices_as_hash(choices) + ensure_valid_keys(hash_choices) + hash_choices end end diff -Nru ruby-bindata-2.3.5/lib/bindata/delayed_io.rb ruby-bindata-2.4.8/lib/bindata/delayed_io.rb --- ruby-bindata-2.3.5/lib/bindata/delayed_io.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/delayed_io.rb 2020-09-27 14:31:03.000000000 +0000 @@ -141,13 +141,8 @@ def sanitize_parameters!(obj_class, params) params.merge!(obj_class.dsl_params) - params.must_be_integer(:read_abs_offset) - - if params.needs_sanitizing?(:type) - el_type, el_params = params[:type] - params[:type] = params.create_sanitized_object_prototype(el_type, el_params) - end + params.sanitize_object_prototype(:type) end end @@ -157,10 +152,9 @@ # The +auto_call_delayed_io+ keyword sets a data object tree to perform # multi pass I/O automatically. def auto_call_delayed_io - include AutoCallDelayedIO - return if DelayedIO.method_defined? :initialize_instance_without_record_io + include AutoCallDelayedIO DelayedIO.send(:alias_method, :initialize_instance_without_record_io, :initialize_instance) DelayedIO.send(:define_method, :initialize_instance) do if @parent && !defined? @delayed_io_recorded diff -Nru ruby-bindata-2.3.5/lib/bindata/dsl.rb ruby-bindata-2.4.8/lib/bindata/dsl.rb --- ruby-bindata-2.3.5/lib/bindata/dsl.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/dsl.rb 2020-09-27 14:31:03.000000000 +0000 @@ -107,11 +107,7 @@ end def fields - @fields ||= begin - SanitizedFields.new(hints).tap do |san_fields| - san_fields.copy_fields(parent_fields) if parent_fields - end - end + @fields ||= SanitizedFields.new(hints, parent_fields) end def dsl_params diff -Nru ruby-bindata-2.3.5/lib/bindata/int.rb ruby-bindata-2.4.8/lib/bindata/int.rb --- ruby-bindata-2.3.5/lib/bindata/int.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/int.rb 2020-09-27 14:31:03.000000000 +0000 @@ -1,3 +1,4 @@ +require 'thread' require 'bindata/base_primitive' module BinData @@ -5,14 +6,18 @@ # is defined by endian, signedness and number of bytes. module Int #:nodoc: all + @@mutex = Mutex.new + class << self def define_class(name, nbits, endian, signed) - unless BinData.const_defined?(name) - BinData.module_eval <<-END - class #{name} < BinData::BasePrimitive - Int.define_methods(self, #{nbits}, :#{endian}, :#{signed}) - end - END + @@mutex.synchronize do + unless BinData.const_defined?(name) + new_class = Class.new(BinData::BasePrimitive) + Int.define_methods(new_class, nbits, endian.to_sym, signed.to_sym) + RegisteredClasses.register(name, new_class) + + BinData.const_set(name, new_class) + end end BinData.const_get(name) diff -Nru ruby-bindata-2.3.5/lib/bindata/io.rb ruby-bindata-2.4.8/lib/bindata/io.rb --- ruby-bindata-2.3.5/lib/bindata/io.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/io.rb 2020-09-27 14:31:03.000000000 +0000 @@ -29,7 +29,7 @@ def seekable? @raw_io.pos - rescue NoMethodError, Errno::ESPIPE, Errno::EPIPE + rescue NoMethodError, Errno::ESPIPE, Errno::EPIPE, Errno::EINVAL nil end @@ -213,7 +213,9 @@ # Creates a StringIO around +str+. def self.create_string_io(str = "") - StringIO.new(str.dup.force_encoding(Encoding::BINARY)) + s = StringIO.new(str.dup.force_encoding(Encoding::BINARY)) + s.binmode + s end # Create a new IO Read wrapper around +io+. +io+ must provide #read, @@ -273,11 +275,7 @@ # If the data read is too short an IOError is raised. def readbytes(n) reset_read_bits - - str = read(n) - raise EOFError, "End of file reached" if str.nil? - raise IOError, "data truncated" if str.size < n - str + read(n) end # Reads all remaining bytes from the stream. @@ -313,7 +311,12 @@ private def read(n = nil) - read_raw(buffer_limited_n(n)) + str = read_raw(buffer_limited_n(n)) + if n + raise EOFError, "End of file reached" if str.nil? + raise IOError, "data truncated" if str.size < n + end + str end def read_big_endian_bits(nbits) @@ -329,10 +332,7 @@ end def accumulate_big_endian_bits - byte = read(1) - raise EOFError, "End of file reached" if byte.nil? - byte = byte.unpack('C').at(0) & 0xff - + byte = read(1).unpack('C').at(0) & 0xff @rval = (@rval << 8) | byte @rnbits += 8 end @@ -350,10 +350,7 @@ end def accumulate_little_endian_bits - byte = read(1) - raise EOFError, "End of file reached" if byte.nil? - byte = byte.unpack('C').at(0) & 0xff - + byte = read(1).unpack('C').at(0) & 0xff @rval = @rval | (byte << @rnbits) @rnbits += 8 end diff -Nru ruby-bindata-2.3.5/lib/bindata/lazy.rb ruby-bindata-2.4.8/lib/bindata/lazy.rb --- ruby-bindata-2.3.5/lib/bindata/lazy.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/lazy.rb 2020-09-27 14:31:03.000000000 +0000 @@ -29,7 +29,7 @@ @overrides = overrides if overrides if val.is_a? Symbol __send__(val) - elsif val.respond_to? :arity + elsif callable?(val) instance_exec(&val) else val @@ -95,11 +95,15 @@ def recursively_eval(val, args) if val.is_a?(Symbol) parent.__send__(val, *args) - elsif val.respond_to?(:arity) + elsif callable?(val) parent.instance_exec(&val) else val end end + + def callable?(obj) + Proc === obj || Method === obj || UnboundMethod === obj + end end end diff -Nru ruby-bindata-2.3.5/lib/bindata/registry.rb ruby-bindata-2.4.8/lib/bindata/registry.rb --- ruby-bindata-2.3.5/lib/bindata/registry.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/registry.rb 2020-09-27 14:31:03.000000000 +0000 @@ -24,7 +24,7 @@ end def register(name, class_to_register) - return if class_to_register.nil? + return if name.nil? || class_to_register.nil? formatted_name = underscore_name(name) warn_if_name_is_already_registered(formatted_name, class_to_register) @@ -37,17 +37,25 @@ end def lookup(name, hints = {}) - key = normalize_name(name, hints) - @registry[key] || raise(UnRegisteredTypeError, name.to_s) + the_class = @registry[normalize_name(name, hints)] + if the_class + the_class + elsif @registry[normalize_name(name, hints.merge(endian: :big))] + raise(UnRegisteredTypeError, "#{name}, do you need to specify endian?") + else + raise(UnRegisteredTypeError, name) + end end # Convert CamelCase +name+ to underscore style. def underscore_name(name) - name.to_s.sub(/.*::/, ""). - gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2'). - gsub(/([a-z\d])([A-Z])/, '\1_\2'). - tr("-", "_"). - downcase + name. + to_s. + sub(/.*::/, ""). + gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2'). + gsub(/([a-z\d])([A-Z])/, '\1_\2'). + tr("-", "_"). + downcase end #--------------- diff -Nru ruby-bindata-2.3.5/lib/bindata/sanitize.rb ruby-bindata-2.4.8/lib/bindata/sanitize.rb --- ruby-bindata-2.3.5/lib/bindata/sanitize.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/sanitize.rb 2020-09-27 14:31:03.000000000 +0000 @@ -72,11 +72,14 @@ class SanitizedFields < SanitizedParameter include Enumerable - def initialize(hints) - @fields = [] - @hints = hints + def initialize(hints, base_fields = nil) + @hints = hints + if base_fields + @fields = base_fields.raw_fields + else + @fields = [] + end end - attr_reader :fields def add_field(type, name, params) name = nil if name == "" @@ -84,6 +87,10 @@ @fields << SanitizedField.new(name, type, params, @hints) end + def raw_fields + @fields.dup + end + def [](idx) @fields[idx] end @@ -119,10 +126,6 @@ def any_field_has_parameter?(parameter) @fields.any? { |f| f.has_parameter?(parameter) } end - - def copy_fields(other) - @fields.concat(other.fields) - end end #---------------------------------------------------------------------------- @@ -209,10 +212,12 @@ alias_method :has_parameter?, :key? - def needs_sanitizing?(key) - parameter = self[key] + def has_at_least_one_of?(*keys) + keys.each do |key| + return true if has_parameter?(key) + end - parameter && !parameter.is_a?(SanitizedParameter) + false end def warn_replacement_parameter(bad_key, suggested_key) @@ -245,36 +250,46 @@ end end - def hints - { endian: self[:endian], search_prefix: self[:search_prefix] } + def rename_parameter(old_key, new_key) + if has_parameter?(old_key) + self[new_key] = delete(old_key) + end end - def create_sanitized_endian(endian) - if endian == :big - BIG_ENDIAN - elsif endian == :little - LITTLE_ENDIAN - elsif endian == :big_and_little - raise ArgumentError, "endian: :big or endian: :little is required" - else - raise ArgumentError, "unknown value for endian '#{endian}'" + def sanitize_object_prototype(key) + sanitize(key) { |obj_type, obj_params| create_sanitized_object_prototype(obj_type, obj_params) } + end + + def sanitize_fields(key, &block) + sanitize(key) do |fields| + sanitized_fields = create_sanitized_fields + yield(fields, sanitized_fields) + sanitized_fields end end - def create_sanitized_params(params, the_class) - SanitizedParameters.new(params, the_class, hints) + def sanitize_choices(key, &block) + sanitize(key) do |obj| + create_sanitized_choices(yield(obj)) + end end - def create_sanitized_choices(choices) - SanitizedChoices.new(choices, hints) + def sanitize_endian(key) + sanitize(key) { |endian| create_sanitized_endian(endian) } end - def create_sanitized_fields - SanitizedFields.new(hints) + def sanitize(key, &block) + if needs_sanitizing?(key) + self[key] = yield(self[key]) + end end - def create_sanitized_object_prototype(obj_type, obj_params) - SanitizedPrototype.new(obj_type, obj_params, hints) + def create_sanitized_params(params, the_class) + SanitizedParameters.new(params, the_class, hints) + end + + def hints + { endian: self[:endian], search_prefix: self[:search_prefix] } end #--------------- @@ -290,6 +305,10 @@ ensure_mutual_exclusion_of_parameters end + def needs_sanitizing?(key) + has_key?(key) && ! self[key].is_a?(SanitizedParameter) + end + def ensure_no_nil_values each do |key, value| if value.nil? @@ -301,7 +320,7 @@ def merge_default_parameters! @the_class.default_parameters.each do |key, value| - self[key] ||= value + self[key] = value unless has_key?(key) end end @@ -324,6 +343,30 @@ end end end + + def create_sanitized_endian(endian) + if endian == :big + BIG_ENDIAN + elsif endian == :little + LITTLE_ENDIAN + elsif endian == :big_and_little + raise ArgumentError, "endian: :big or endian: :little is required" + else + raise ArgumentError, "unknown value for endian '#{endian}'" + end + end + + def create_sanitized_choices(choices) + SanitizedChoices.new(choices, hints) + end + + def create_sanitized_fields + SanitizedFields.new(hints) + end + + def create_sanitized_object_prototype(obj_type, obj_params) + SanitizedPrototype.new(obj_type, obj_params, hints) + end end #---------------------------------------------------------------------------- end diff -Nru ruby-bindata-2.3.5/lib/bindata/skip.rb ruby-bindata-2.4.8/lib/bindata/skip.rb --- ruby-bindata-2.3.5/lib/bindata/skip.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/skip.rb 2020-09-27 14:31:03.000000000 +0000 @@ -83,17 +83,12 @@ class SkipArgProcessor < BaseArgProcessor def sanitize_parameters!(obj_class, params) - unless params.has_parameter?(:length) || - params.has_parameter?(:to_abs_offset) || - params.has_parameter?(:until_valid) - raise ArgumentError, "#{obj_class} requires either :length, :to_abs_offset or :until_valid" + unless params.has_at_least_one_of?(:length, :to_abs_offset, :until_valid) + raise ArgumentError, + "#{obj_class} requires either :length, :to_abs_offset or :until_valid" end params.must_be_integer(:to_abs_offset, :length) - - if params.needs_sanitizing?(:until_valid) - el_type, el_params = params[:until_valid] - params[:until_valid] = params.create_sanitized_object_prototype(el_type, el_params) - end + params.sanitize_object_prototype(:until_valid) end end diff -Nru ruby-bindata-2.3.5/lib/bindata/string.rb ruby-bindata-2.4.8/lib/bindata/string.rb --- ruby-bindata-2.3.5/lib/bindata/string.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/string.rb 2020-09-27 14:31:03.000000000 +0000 @@ -127,15 +127,8 @@ def sanitize_parameters!(obj_class, params) params.warn_replacement_parameter(:initial_length, :read_length) params.must_be_integer(:read_length, :length) - - if params.has_parameter?(:pad_left) - params[:pad_front] = params.delete(:pad_left) - end - - if params.has_parameter?(:pad_byte) - byte = params[:pad_byte] - params[:pad_byte] = sanitized_pad_byte(byte) - end + params.rename_parameter(:pad_left, :pad_front) + params.sanitize(:pad_byte) { |byte| sanitized_pad_byte(byte) } end #------------- diff -Nru ruby-bindata-2.3.5/lib/bindata/stringz.rb ruby-bindata-2.4.8/lib/bindata/stringz.rb --- ruby-bindata-2.3.5/lib/bindata/stringz.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/stringz.rb 2020-09-27 14:31:03.000000000 +0000 @@ -80,7 +80,7 @@ def trim_to!(str, max_length = nil) if max_length max_length = 1 if max_length < 1 - str.slice!(max_length) + str.slice!(max_length..-1) if str.length == max_length && str[-1, 1] != "\0" str[-1, 1] = "\0" end diff -Nru ruby-bindata-2.3.5/lib/bindata/struct.rb ruby-bindata-2.4.8/lib/bindata/struct.rb --- ruby-bindata-2.3.5/lib/bindata/struct.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/struct.rb 2020-09-27 14:31:03.000000000 +0000 @@ -62,19 +62,20 @@ optional_parameters :endian, :search_prefix, :hide # These reserved words may not be used as field names - RESERVED = Hash[* - (Hash.instance_methods + - %w{alias and begin break case class def defined do else elsif - end ensure false for if in module next nil not or redo - rescue retry return self super then true undef unless until - when while yield} + - %w{array element index value} + - %w{type initial_length read_until} + - %w{fields endian search_prefix hide only_if byte_align} + - %w{choices selection copy_on_change} + - %w{read_abs_offset struct_params}).collect(&:to_sym). - uniq.collect { |key| [key, true] }.flatten - ] + RESERVED = + Hash[* + (Hash.instance_methods + + %w{alias and begin break case class def defined do else elsif + end ensure false for if in module next nil not or redo + rescue retry return self super then true undef unless until + when while yield} + + %w{array element index value} + + %w{type initial_length read_until} + + %w{fields endian search_prefix hide only_if byte_align} + + %w{choices selection copy_on_change} + + %w{read_abs_offset struct_params}).collect(&:to_sym). + uniq.collect { |key| [key, true] }.flatten + ] def initialize_shared_instance fields = get_parameter(:fields) @@ -277,7 +278,7 @@ end def method_missing(symbol, *args) - self[symbol] || super + key?(symbol) ? self[symbol] : super end end end @@ -349,44 +350,38 @@ private def sanitize_endian(params) - if params.needs_sanitizing?(:endian) - endian = params.create_sanitized_endian(params[:endian]) - params[:endian] = endian - end + params.sanitize_endian(:endian) end def sanitize_search_prefix(params) - if params.needs_sanitizing?(:search_prefix) + params.sanitize(:search_prefix) do |sprefix| search_prefix = [] - Array(params[:search_prefix]).each do |prefix| + Array(sprefix).each do |prefix| prefix = prefix.to_s.chomp("_") search_prefix << prefix if prefix != "" end - params[:search_prefix] = search_prefix + search_prefix end end def sanitize_fields(obj_class, params) - if params.needs_sanitizing?(:fields) - fields = params[:fields] - - params[:fields] = params.create_sanitized_fields + params.sanitize_fields(:fields) do |fields, sanitized_fields| fields.each do |ftype, fname, fparams| - params[:fields].add_field(ftype, fname, fparams) + sanitized_fields.add_field(ftype, fname, fparams) end - field_names = sanitized_field_names(params[:fields]) + field_names = sanitized_field_names(sanitized_fields) ensure_field_names_are_valid(obj_class, field_names) end end def sanitize_hide(params) - if params.needs_sanitizing?(:hide) && params.has_parameter?(:fields) + params.sanitize(:hide) do |hidden| field_names = sanitized_field_names(params[:fields]) - hfield_names = hidden_field_names(params[:hide]) + hfield_names = hidden_field_names(hidden) - params[:hide] = (hfield_names & field_names) + hfield_names & field_names end end diff -Nru ruby-bindata-2.3.5/lib/bindata/uint8_array.rb ruby-bindata-2.4.8/lib/bindata/uint8_array.rb --- ruby-bindata-2.3.5/lib/bindata/uint8_array.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/uint8_array.rb 2020-09-27 14:31:03.000000000 +0000 @@ -0,0 +1,62 @@ +require "bindata/base_primitive" + +module BinData + # Uint8Array is a specialised type of array that only contains + # bytes (Uint8). It is a faster and more memory efficient version + # of `BinData::Array.new(:type => :uint8)`. + # + # require 'bindata' + # + # obj = BinData::Uint8Array.new(initial_length: 5) + # obj.read("abcdefg") #=> [97, 98, 99, 100, 101] + # obj[2] #=> 99 + # obj.collect { |x| x.chr }.join #=> "abcde" + # + # == Parameters + # + # Parameters may be provided at initialisation to control the behaviour of + # an object. These params are: + # + # :initial_length:: The initial length of the array. + # :read_until:: May only have a value of `:eof`. This parameter + # instructs the array to read as much data from + # the stream as possible. + class Uint8Array < BinData::BasePrimitive + optional_parameters :initial_length, :read_until + mutually_exclusive_parameters :initial_length, :read_until + arg_processor :uint8_array + + #--------------- + private + + def value_to_binary_string(val) + val.pack("C*") + end + + def read_and_return_value(io) + if has_parameter?(:initial_length) + data = io.readbytes(eval_parameter(:initial_length)) + else + data = io.read_all_bytes + end + + data.unpack("C*") + end + + def sensible_default + [] + end + end + + class Uint8ArrayArgProcessor < BaseArgProcessor + def sanitize_parameters!(obj_class, params) #:nodoc: + # ensure one of :initial_length and :read_until exists + unless params.has_at_least_one_of?(:initial_length, :read_until) + params[:initial_length] = 0 + end + + msg = "Parameter :read_until must have a value of :eof" + params.sanitize(:read_until) { |val| raise ArgumentError, msg unless val == :eof } + end + end +end diff -Nru ruby-bindata-2.3.5/lib/bindata/version.rb ruby-bindata-2.4.8/lib/bindata/version.rb --- ruby-bindata-2.3.5/lib/bindata/version.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata/version.rb 2020-09-27 14:31:03.000000000 +0000 @@ -1,3 +1,3 @@ module BinData - VERSION = "2.3.5" + VERSION = "2.4.8" end diff -Nru ruby-bindata-2.3.5/lib/bindata.rb ruby-bindata-2.4.8/lib/bindata.rb --- ruby-bindata-2.3.5/lib/bindata.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/lib/bindata.rb 2020-09-27 14:31:03.000000000 +0000 @@ -1,13 +1,5 @@ # BinData -- Binary data manipulator. -# Copyright (c) 2007 - 2016 Dion Mendel. - -if RUBY_VERSION <= "1.9" - fail "BinData requires ruby >= 1.9.3. Use BinData version 1.8.x instead" -end - -if RUBY_VERSION == "2.1.0" and RUBY_PATCHLEVEL == "0" - fail "Ruby 2.1.0p0 has a bug that causes BinData to fail. Upgrade your ruby version" -end +# Copyright (c) 2007 - 2018 Dion Mendel. require 'bindata/version' require 'bindata/array' @@ -26,6 +18,7 @@ require 'bindata/stringz' require 'bindata/struct' require 'bindata/trace' +require 'bindata/uint8_array' require 'bindata/virtual' require 'bindata/alignment' require 'bindata/warnings' @@ -35,10 +28,10 @@ # A declarative way to read and write structured binary data. # # A full reference manual is available online at -# http://bindata.rubyforge.org/manual.html +# https://github.com/dmendel/bindata/wiki # # == License # # BinData is released under the same license as Ruby. # -# Copyright (c) 2007 - 2016 Dion Mendel. +# Copyright (c) 2007 - 2018 Dion Mendel. diff -Nru ruby-bindata-2.3.5/NEWS.rdoc ruby-bindata-2.4.8/NEWS.rdoc --- ruby-bindata-2.3.5/NEWS.rdoc 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/NEWS.rdoc 2020-09-27 14:31:03.000000000 +0000 @@ -1,3 +1,19 @@ += 2.4.0 + +This release changes the internal API for sanitizing parameters. This only +affects those that implement the `#sanitize_parameters` method. + += 2.3.x + + if params.needs_sanitizing?(:type) + el_type, el_params = params[:type] + params[:type] = params.create_sanitized_object_prototype(el_type, el_params) + end + += 2.4.0 + + params.sanitize_object_prototype(:type) + = 2.3.0 This release adds I/O features. diff -Nru ruby-bindata-2.3.5/README.md ruby-bindata-2.4.8/README.md --- ruby-bindata-2.3.5/README.md 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/README.md 2020-09-27 14:31:03.000000000 +0000 @@ -2,7 +2,6 @@ [![Version ](http://img.shields.io/gem/v/bindata.svg) ](https://rubygems.org/gems/bindata) [![Travis CI ](http://img.shields.io/travis/dmendel/bindata/master.svg) ](https://travis-ci.org/dmendel/bindata) -[![Quality ](http://img.shields.io/codeclimate/github/dmendel/bindata.svg)](https://codeclimate.com/github/dmendel/bindata) [![Coverage ](http://img.shields.io/coveralls/dmendel/bindata.svg) ](https://coveralls.io/r/dmendel/bindata) Do you ever find yourself writing code like this? diff -Nru ruby-bindata-2.3.5/test/array_test.rb ruby-bindata-2.4.8/test/array_test.rb --- ruby-bindata-2.3.5/test/array_test.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/test/array_test.rb 2020-09-27 14:31:03.000000000 +0000 @@ -266,6 +266,11 @@ lambda { obj["a"] }.must_raise TypeError lambda { obj[1, "a"] }.must_raise TypeError end + + it "is unaffected by self assignment" do + obj.assign(obj) + obj.snapshot.must_equal [1, 2, 3, 4, 5] + end end describe BinData::Array, "with :read_until" do diff -Nru ruby-bindata-2.3.5/test/buffer_test.rb ruby-bindata-2.4.8/test/buffer_test.rb --- ruby-bindata-2.3.5/test/buffer_test.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/test/buffer_test.rb 2020-09-27 14:31:03.000000000 +0000 @@ -153,4 +153,3 @@ obj.to_binary_s.must_equal_binary "abcdeABCDE12345" end end - diff -Nru ruby-bindata-2.3.5/test/offset_test.rb ruby-bindata-2.4.8/test/offset_test.rb --- ruby-bindata-2.3.5/test/offset_test.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/test/offset_test.rb 2020-09-27 14:31:03.000000000 +0000 @@ -74,9 +74,15 @@ end it "adjust offset when incorrect" do - io.seek(2) - obj = TenByteOffsetBase.create(adjust_offset: 13) - obj.read(io).snapshot.must_equal data[2 + 13, 3] + w, $-w = $-w, false + + begin + io.seek(2) + obj = TenByteOffsetBase.create(adjust_offset: 13) + obj.read(io).snapshot.must_equal data[2 + 13, 3] + ensure + $-w = w + end end it "succeeds when offset is correct" do diff -Nru ruby-bindata-2.3.5/test/registry_test.rb ruby-bindata-2.4.8/test/registry_test.rb --- ruby-bindata-2.3.5/test/registry_test.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/test/registry_test.rb 2020-09-27 14:31:03.000000000 +0000 @@ -36,10 +36,16 @@ end it "allows overriding of registered classes" do - r.register('A', A) - r.register('A', B) + w, $-w = $-w, false - r.lookup('a').must_equal B + begin + r.register('A', A) + r.register('A', B) + + r.lookup('a').must_equal B + ensure + $-w = w + end end it "converts CamelCase to underscores" do @@ -71,6 +77,14 @@ }.must_raise BinData::UnRegisteredTypeError end + it "provides a nice error message when endian is omitted" do + begin + r.lookup("int24") + rescue BinData::UnRegisteredTypeError => e + e.message.must_equal "int24, do you need to specify endian?" + end + end + it "does not lookup non byte based integers" do lambda { r.lookup("int3") diff -Nru ruby-bindata-2.3.5/test/stringz_test.rb ruby-bindata-2.4.8/test/stringz_test.rb --- ruby-bindata-2.3.5/test/stringz_test.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/test/stringz_test.rb 2020-09-27 14:31:03.000000000 +0000 @@ -106,12 +106,12 @@ end it "trims values greater than max_length" do - obj.assign("abcde") + obj.assign("abcdefg") obj.must_equal "abcd" end it "writes values greater than max_length" do - obj.assign("abcde") + obj.assign("abcdefg") obj.to_binary_s.must_equal_binary "abcd\0" end diff -Nru ruby-bindata-2.3.5/test/system_test.rb ruby-bindata-2.4.8/test/system_test.rb --- ruby-bindata-2.3.5/test/system_test.rb 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/test/system_test.rb 2020-09-27 14:31:03.000000000 +0000 @@ -338,3 +338,59 @@ end end +describe BinData::Record, "with boolean parameters" do + class BooleanParameterRecord < BinData::Record + default_parameter flag: true + + int8 :a, value: -> { flag ? 2 : 3 } + end + + it "uses default parameter" do + obj = BooleanParameterRecord.new + obj.a.must_equal 2 + end + + it "overrides parameter" do + obj = BooleanParameterRecord.new(flag: false) + obj.a.must_equal 3 + end + + it "overrides parameter with same value" do + obj = BooleanParameterRecord.new(flag: true) + obj.a.must_equal 2 + end +end + +describe BinData::Record, "encoding" do + class EncodingTestBufferRecord < BinData::Record + endian :big + default_parameter length: 5 + + uint16 :num + string :str, length: 10 + end + + it "returns binary encoded data" do + obj = EncodingTestBufferRecord.new(num: 3) + obj.to_binary_s.encoding.must_equal Encoding::ASCII_8BIT + end + + it "returns binary encoded data with utf-8 string" do + obj = EncodingTestBufferRecord.new(num: 3, str: "日本語") + obj.to_binary_s.encoding.must_equal Encoding::ASCII_8BIT + end + + it "returns binary encoded data despite Encoding.default_internal" do + w, $-w = $-w, false + before_enc = Encoding.default_internal + + begin + Encoding.default_internal = Encoding::UTF_8 + obj = EncodingTestBufferRecord.new(num: 3, str: "日本語") + obj.to_binary_s.encoding.must_equal Encoding::ASCII_8BIT + ensure + Encoding.default_internal = before_enc + $-w = w + end + end +end diff -Nru ruby-bindata-2.3.5/test/uint8_array_test.rb ruby-bindata-2.4.8/test/uint8_array_test.rb --- ruby-bindata-2.3.5/test/uint8_array_test.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-bindata-2.4.8/test/uint8_array_test.rb 2020-09-27 14:31:03.000000000 +0000 @@ -0,0 +1,44 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.join(File.dirname(__FILE__), "test_helper")) + +describe BinData::Uint8Array, "when initialising" do + it "with mutually exclusive parameters :initial_length and :read_until" do + params = {initial_length: 5, read_until: :eof} + lambda { BinData::Uint8Array.new(params) }.must_raise ArgumentError + end + + it "with :read_until" do + params = {read_until: :not_eof} + lambda { BinData::Uint8Array.new(params) }.must_raise ArgumentError + end + + it "with no parameters" do + arr = BinData::Uint8Array.new + arr.num_bytes.must_equal 0 + end +end + +describe BinData::Uint8Array, "with :read_until" do + it "reads until :eof" do + arr = BinData::Uint8Array.new(read_until: :eof) + arr.read("\xff\xfe\xfd\xfc") + arr.must_equal([255, 254, 253, 252]) + end +end + +describe BinData::Uint8Array, "with :initial_length" do + it "reads" do + arr = BinData::Uint8Array.new(initial_length: 3) + arr.read("\xff\xfe\xfd\xfc") + arr.must_equal([255, 254, 253]) + end +end + +describe BinData::Uint8Array, "when assigning" do + it "copies data" do + arr = BinData::Uint8Array.new + arr.assign([1, 2, 3]) + arr.must_equal([1, 2, 3]) + end +end diff -Nru ruby-bindata-2.3.5/.travis.yml ruby-bindata-2.4.8/.travis.yml --- ruby-bindata-2.3.5/.travis.yml 2017-01-26 23:17:11.000000000 +0000 +++ ruby-bindata-2.4.8/.travis.yml 2020-09-27 14:31:03.000000000 +0000 @@ -1,9 +1,11 @@ language: ruby rvm: - - 2.0 - - 2.1.10 - 2.2 - 2.3 + - 2.4 + - 2.5 + - 2.6 + - 2.7 - jruby - ruby-head