Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' into jruby

* master:
  Adding Rubinius as an Allowed Failure
  bump version
  Fix CVE-2014-9130
  Adding RVM listing for Rubinius
  fix minitest warnings
  * ext/psych/lib/psych/visitors/yaml_tree.rb: register nodes when   dumping objects with custom coders. [ruby-core:66215] [Bug #10496]
  * ext/psych/lib/psych/visitors/to_ruby.rb: fix support for regular   expressions with newlines. tenderlove/psych#222
  * ext/psych/lib/psych/visitors/to_ruby.rb: fix parsing hashes with   instance variables when it is referenced multiple times. * ext/psych/lib/psych.rb: bump version * ext/psych/psych.gemspec: bump version * test/psych/test_hash.rb: test for fix
  bump version
  Fix anchor
  Fix assertion regexps
  bump version
  Only dump ivars for subclasses of String, not for String. With cf0dd2b93f1552a3c452a0bfa0e996f441d5e27e, fixes #217.
  Only dump ivars for subclasses of Hash, not for Hash. Fixes #216. Fixes part of #217.
  Fix block chomping and add more tests
  Preset @line_width in YAMLTree#initialize for better performance
  Use appropriate style for serialized strings
  Remove unnnecessary 'str' variable in YAMLTree#visit_String
  • Loading branch information...
commit 22589e504eb32388b23dd9c22ed7e95cd11c845a 2 parents b2dab9e + 24ff785
Aaron Patterson authored
4 .travis.yml
View
@@ -4,8 +4,12 @@ rvm:
- 2.0.0
- 2.1.0
- ruby-head
+ - rbx-2
before_script:
- gem install hoe
- gem install rake-compiler
- gem install minitest -v '~> 4.0'
script: rake test
+matrix:
+ allow_failures:
+ - rvm: rbx-2
22 CHANGELOG.rdoc
View
@@ -1,3 +1,25 @@
+Fri Feb 6 17:47:05 2015 Aaron Patterson <aaron@tenderlovemaking.com>
+
+ * ext/psych/lib/psych/visitors/yaml_tree.rb: register nodes when
+ dumping objects with custom coders. [ruby-core:66215] [Bug #10496]
+
+ * test/psych/test_coder.rb: test for fix
+
+Fri Feb 6 16:58:31 2015 Aaron Patterson <aaron@tenderlovemaking.com>
+
+ * ext/psych/lib/psych/visitors/to_ruby.rb: fix support for regular
+ expressions with newlines. tenderlove/psych#222
+
+ * test/psych/test_yaml.rb: test for change.
+
+Thu Jan 29 02:34:27 2015 Aaron Patterson <aaron@tenderlovemaking.com>
+
+ * ext/psych/lib/psych/visitors/to_ruby.rb: fix parsing hashes with
+ instance variables when it is referenced multiple times.
+ * ext/psych/lib/psych.rb: bump version
+ * ext/psych/psych.gemspec: bump version
+ * test/psych/test_hash.rb: test for fix
+
Fri Jan 9 07:13:55 2015 Aaron Patterson <aaron@tenderlovemaking.com>
* ext/psych/lib/psych/visitors/to_ruby.rb: call `allocate` on hash
7 ext/psych/yaml/scanner.c
View
@@ -1106,13 +1106,6 @@ yaml_parser_save_simple_key(yaml_parser_t *parser)
&& parser->indent == (ptrdiff_t)parser->mark.column);
/*
- * A simple key is required only when it is the first token in the current
- * line. Therefore it is always allowed. But we add a check anyway.
- */
-
- assert(parser->simple_key_allowed || !required); /* Impossible. */
-
- /*
* If the current position may start a simple key, save it.
*/
2  lib/psych.rb
View
@@ -223,7 +223,7 @@
module Psych
# The version is Psych you're using
- VERSION = '2.0.9'
+ VERSION = '2.0.13'
# The version of libyaml Psych is using
LIBYAML_VERSION = Psych.libyaml_version.join '.'
5 lib/psych/visitors/to_ruby.rb
View
@@ -32,7 +32,7 @@ def accept target
return result if @domain_types.empty? || !target.tag
key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:')
- key = "tag:#{key}" unless key =~ /^(tag:|x-private)/
+ key = "tag:#{key}" unless key =~ /^(?:tag:|x-private)/
if @domain_types.key? key
value, block = @domain_types[key]
@@ -89,7 +89,7 @@ def deserialize o
Float(@ss.tokenize(o.value))
when "!ruby/regexp"
klass = class_loader.regexp
- o.value =~ /^\/(.*)\/([mixn]*)$/
+ o.value =~ /^\/(.*)\/([mixn]*)$/m
source = $1
options = 0
lang = nil
@@ -263,6 +263,7 @@ def visit_Psych_Nodes_Mapping o
when /^!ruby\/hash-with-ivars(?::(.*))?$/
hash = $1 ? resolve_class($1).allocate : {}
+ register o, hash
o.children.each_slice(2) do |key, value|
case key.value
when 'elements'
125 lib/psych/visitors/yaml_tree.rb
View
@@ -21,6 +21,7 @@ def initialize
end
def register target, node
+ return unless target.respond_to? :object_id
@targets << target
@obj_to_node[target.object_id] = node
end
@@ -62,13 +63,14 @@ def self.new emitter = nil, ss = nil, options = nil
def initialize emitter, ss, options
super()
- @started = false
- @finished = false
- @emitter = emitter
- @st = Registrar.new
- @ss = ss
- @options = options
- @coders = []
+ @started = false
+ @finished = false
+ @emitter = emitter
+ @st = Registrar.new
+ @ss = ss
+ @options = options
+ @line_width = options[:line_width]
+ @coders = []
@dispatch_cache = Hash.new do |h,klass|
method = "visit_#{(klass.name || '').split('::').join('_')}"
@@ -301,46 +303,46 @@ def visit_String o
quote = true
style = Nodes::Scalar::PLAIN
tag = nil
- str = o
if binary?(o)
- str = [o].pack('m').chomp
+ o = [o].pack('m').chomp
tag = '!binary' # FIXME: change to below when syck is removed
#tag = 'tag:yaml.org,2002:binary'
style = Nodes::Scalar::LITERAL
plain = false
quote = false
- elsif o =~ /\n/
+ elsif o =~ /\n(?!\Z)/ # match \n except blank line at the end of string
style = Nodes::Scalar::LITERAL
elsif o == '<<'
style = Nodes::Scalar::SINGLE_QUOTED
tag = 'tag:yaml.org,2002:str'
plain = false
quote = false
+ elsif @line_width && o.length > @line_width
+ style = Nodes::Scalar::FOLDED
elsif o =~ /^[^[:word:]][^"]*$/
style = Nodes::Scalar::DOUBLE_QUOTED
- else
- unless String === @ss.tokenize(o)
- style = Nodes::Scalar::SINGLE_QUOTED
- end
+ elsif not String === @ss.tokenize(o)
+ style = Nodes::Scalar::SINGLE_QUOTED
end
- ivars = find_ivars o
+ is_primitive = o.class == ::String
+ ivars = find_ivars o, is_primitive
if ivars.empty?
- unless o.class == ::String
+ unless is_primitive
tag = "!ruby/string:#{o.class}"
plain = false
quote = false
end
- @emitter.scalar str, nil, tag, plain, quote, style
+ @emitter.scalar o, nil, tag, plain, quote, style
else
maptag = '!ruby/string'
maptag << ":#{o.class}" unless o.class == ::String
register o, @emitter.start_mapping(nil, maptag, false, Nodes::Mapping::BLOCK)
@emitter.scalar 'str', nil, nil, true, false, Nodes::Scalar::ANY
- @emitter.scalar str, nil, tag, plain, quote, style
+ @emitter.scalar o, nil, tag, plain, quote, style
dump_ivars o
@@ -367,45 +369,15 @@ def visit_Range o
end
def visit_Hash o
- ivars = o.instance_variables
-
- if ivars.any?
- tag = "!ruby/hash-with-ivars"
- tag << ":#{o.class}" unless o.class == ::Hash
-
- register(o, @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK))
-
- @emitter.scalar 'elements', nil, nil, true, false, Nodes::Scalar::ANY
-
- @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
+ if o.class == ::Hash
+ register(o, @emitter.start_mapping(nil, nil, true, Psych::Nodes::Mapping::BLOCK))
o.each do |k,v|
accept k
accept v
end
@emitter.end_mapping
-
- @emitter.scalar 'ivars', nil, nil, true, false, Nodes::Scalar::ANY
-
- @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
- o.instance_variables.each do |ivar|
- accept ivar
- accept o.instance_variable_get ivar
- end
- @emitter.end_mapping
-
- @emitter.end_mapping
else
- tag = o.class == ::Hash ? nil : "!ruby/hash:#{o.class}"
- implicit = !tag
-
- register(o, @emitter.start_mapping(nil, tag, implicit, Psych::Nodes::Mapping::BLOCK))
-
- o.each do |k,v|
- accept k
- accept v
- end
-
- @emitter.end_mapping
+ visit_hash_subclass o
end
end
@@ -468,7 +440,8 @@ def binary? string
def visit_array_subclass o
tag = "!ruby/array:#{o.class}"
- if o.instance_variables.empty?
+ ivars = o.instance_variables
+ if ivars.empty?
node = @emitter.start_sequence(nil, tag, false, Nodes::Sequence::BLOCK)
register o, node
o.each { |c| accept c }
@@ -486,6 +459,35 @@ def visit_array_subclass o
# Dump the ivars
accept 'ivars'
@emitter.start_mapping(nil, nil, true, Nodes::Sequence::BLOCK)
+ ivars.each do |ivar|
+ accept ivar
+ accept o.instance_variable_get ivar
+ end
+ @emitter.end_mapping
+
+ @emitter.end_mapping
+ end
+ end
+
+ def visit_hash_subclass o
+ ivars = o.instance_variables
+ if ivars.any?
+ tag = "!ruby/hash-with-ivars:#{o.class}"
+ node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK)
+ register(o, node)
+
+ # Dump the elements
+ accept 'elements'
+ @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
+ o.each do |k,v|
+ accept k
+ accept v
+ end
+ @emitter.end_mapping
+
+ # Dump the ivars
+ accept 'ivars'
+ @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
o.instance_variables.each do |ivar|
accept ivar
accept o.instance_variable_get ivar
@@ -493,6 +495,15 @@ def visit_array_subclass o
@emitter.end_mapping
@emitter.end_mapping
+ else
+ tag = "!ruby/hash:#{o.class}"
+ node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK)
+ register(o, node)
+ o.each do |k,v|
+ accept k
+ accept v
+ end
+ @emitter.end_mapping
end
end
@@ -524,7 +535,7 @@ def format_time time
end
# FIXME: remove this method once "to_yaml_properties" is removed
- def find_ivars target
+ def find_ivars target, is_primitive=false
begin
loc = target.method(:to_yaml_properties).source_location.first
unless loc.start_with?(Psych::DEPRECATED) || loc.end_with?('rubytypes.rb')
@@ -538,7 +549,7 @@ def find_ivars target
# and it's OK to skip it since it's only to emit a warning.
end
- target.instance_variables
+ is_primitive ? [] : target.instance_variables
end
def register target, yaml_obj
@@ -556,10 +567,10 @@ def dump_coder o
c = Psych::Coder.new(tag)
o.encode_with(c)
- emit_coder c
+ emit_coder c, o
end
- def emit_coder c
+ def emit_coder c, o
case c.type
when :scalar
@emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, Nodes::Scalar::ANY
@@ -570,7 +581,7 @@ def emit_coder c
end
@emitter.end_sequence
when :map
- @emitter.start_mapping nil, c.tag, c.implicit, c.style
+ register o, @emitter.start_mapping(nil, c.tag, c.implicit, c.style)
c.map.each do |k,v|
accept k
accept v
8 test/psych/helper.rb
View
@@ -6,7 +6,13 @@
require 'psych'
module Psych
- class TestCase < MiniTest::Unit::TestCase
+ superclass = if defined?(Minitest::Test)
+ Minitest::Test
+ else
+ MiniTest::Unit::TestCase
+ end
+
+ class TestCase < superclass
def self.suppress_warning
verbose, $VERBOSE = $VERBOSE, nil
yield
22 test/psych/test_coder.rb
View
@@ -95,6 +95,28 @@ def encode_with coder
end
end
+ class Referential
+ attr_reader :a
+
+ def initialize
+ @a = self
+ end
+
+ def encode_with(c)
+ c['a'] = @a
+ end
+
+ def init_with(c)
+ @a = c['a']
+ end
+ end
+
+ def test_self_referential
+ x = Referential.new
+ copy = Psych.load Psych.dump x
+ assert_equal copy, copy.a
+ end
+
def test_represent_with_object
thing = Psych.load(Psych.dump(RepresentWithObject.new))
assert_equal 20, thing
13 test/psych/test_hash.rb
View
@@ -23,6 +23,13 @@ def setup
@hash = { :a => 'b' }
end
+ def test_referenced_hash_with_ivar
+ a = [1,2,3,4,5]
+ t1 = [HashWithCustomInit.new(a)]
+ t1 << t1.first
+ assert_cycle t1
+ end
+
def test_custom_initialized
a = [1,2,3,4,5]
t1 = HashWithCustomInit.new(a)
@@ -38,12 +45,6 @@ def test_custom_initialize_no_ivar
assert_cycle t1
end
- def test_hash_with_ivars
- @hash.instance_variable_set :@foo, 'bar'
- dup = Psych.load Psych.dump @hash
- assert_equal 'bar', dup.instance_variable_get(:@foo)
- end
-
def test_hash_subclass_with_ivars
x = X.new
x[:a] = 'b'
58 test/psych/test_string.rb
View
@@ -30,8 +30,62 @@ def test_no_quotes_when_start_with_non_ascii_character
end
def test_doublequotes_when_there_is_a_single
- yaml = Psych.dump "@123'abc"
- assert_match(/---\s*"/, yaml)
+ str = "@123'abc"
+ yaml = Psych.dump str
+ assert_match /---\s*"/, yaml
+ assert_equal str, Psych.load(yaml)
+ end
+
+ def test_plain_when_shorten_than_line_width_and_no_final_line_break
+ str = "Lorem ipsum"
+ yaml = Psych.dump str, line_width: 12
+ assert_match /---\s*[^>|]+\n/, yaml
+ assert_equal str, Psych.load(yaml)
+ end
+
+ def test_plain_when_shorten_than_line_width_and_with_final_line_break
+ str = "Lorem ipsum\n"
+ yaml = Psych.dump str, line_width: 12
+ assert_match /---\s*[^>|]+\n/, yaml
+ assert_equal str, Psych.load(yaml)
+ end
+
+ def test_folded_when_longer_than_line_width_and_with_final_line_break
+ str = "Lorem ipsum dolor sit\n"
+ yaml = Psych.dump str, line_width: 12
+ assert_match /---\s*>\n(.*\n){2}\Z/, yaml
+ assert_equal str, Psych.load(yaml)
+ end
+
+ # http://yaml.org/spec/1.2/2009-07-21/spec.html#id2593651
+ def test_folded_strip_when_longer_than_line_width_and_no_newlines
+ str = "Lorem ipsum dolor sit amet, consectetur"
+ yaml = Psych.dump str, line_width: 12
+ assert_match /---\s*>-\n(.*\n){3}\Z/, yaml
+ assert_equal str, Psych.load(yaml)
+ end
+
+ def test_literal_when_inner_and_final_line_break
+ [
+ "Lorem ipsum\ndolor\n",
+ "Lorem ipsum\nZolor\n",
+ ].each do |str|
+ yaml = Psych.dump str, line_width: 12
+ assert_match /---\s*\|\n(.*\n){2}\Z/, yaml
+ assert_equal str, Psych.load(yaml)
+ end
+ end
+
+ # http://yaml.org/spec/1.2/2009-07-21/spec.html#id2593651
+ def test_literal_strip_when_inner_line_break_and_no_final_line_break
+ [
+ "Lorem ipsum\ndolor",
+ "Lorem ipsum\nZolor",
+ ].each do |str|
+ yaml = Psych.dump str, line_width: 12
+ assert_match /---\s*\|-\n(.*\n){2}\Z/, yaml
+ assert_equal str, Psych.load(yaml)
+ end
end
def test_cycle_x
2  test/psych/test_to_yaml_properties.rb
View
@@ -1,7 +1,7 @@
require_relative 'helper'
module Psych
- class TestToYamlProperties < MiniTest::Unit::TestCase
+ class TestToYamlProperties < Psych::TestCase
class Foo
attr_accessor :a, :b, :c
def initialize
4 test/psych/test_yaml.rb
View
@@ -27,6 +27,10 @@ def test_syck_compat
assert_match "2010-10-10 00:00:00.000000000 Z", yaml
end
+ def test_multiline_regexp
+ assert_cycle(Regexp.new("foo\nbar"))
+ end
+
# [ruby-core:34969]
def test_regexp_with_n
assert_cycle(Regexp.new('',0,'n'))
Please sign in to comment.
Something went wrong with that request. Please try again.