diff --git a/lib/psych/visitors/yaml_tree.rb b/lib/psych/visitors/yaml_tree.rb index e27c9279..0b2357bb 100644 --- a/lib/psych/visitors/yaml_tree.rb +++ b/lib/psych/visitors/yaml_tree.rb @@ -274,7 +274,7 @@ def visit_String o style = Nodes::Scalar::FOLDED elsif o.match?(/^[^[:word:]][^"]*$/) style = Nodes::Scalar::DOUBLE_QUOTED - elsif not String === @ss.tokenize(o) or /\A0[0-7]*[89]/.match?(o) + elsif not String === @ss.tokenize(o) or may_be_confused_as_yaml12?(o) style = Nodes::Scalar::SINGLE_QUOTED end @@ -388,6 +388,19 @@ def binary? string string.encoding == Encoding::ASCII_8BIT && !string.ascii_only? end + def may_be_confused_as_yaml12? string + case string + when /\A0[0-7]*[89]\z/ # YAML 1.1 int (Base 8) + true + when /\A0o[0-7]+\z/ # YAML 1.2 int (Base 8) + true + when /\A[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?\z/ # YAML 1.1/1.2 float (Number) + true + else + false + end + end + def visit_array_subclass o tag = "!ruby/array:#{o.class}" ivars = o.instance_variables diff --git a/test/psych/visitors/test_yaml_tree.rb b/test/psych/visitors/test_yaml_tree.rb index 01e68513..271afa3c 100644 --- a/test/psych/visitors/test_yaml_tree.rb +++ b/test/psych/visitors/test_yaml_tree.rb @@ -167,9 +167,22 @@ def test_float end def test_string + # YAML 1.1 int Base 8 assert_include(Psych.dump({'a' => '017'}), "'017'") assert_include(Psych.dump({'a' => '019'}), "'019'") assert_include(Psych.dump({'a' => '01818'}), "'01818'") + + # YAML 1.1 float Number + assert_include(Psych.dump({'a' => '.2e3'}), '".2e3"') + + # YAML 1.2 int Base 8 + assert_include(Psych.dump({'a' => '0o17'}), "'0o17'") + assert_include(Psych.dump({'a' => '0o111'}), "'0o111'") + + # YAML 1.2 float Number + assert_include(Psych.dump({'a' => '12e03'}), "'12e03'") + assert_include(Psych.dump({'a' => '0e447890'}), "'0e447890'") + assert_include(Psych.dump({'a' => '1.2e3'}), "'1.2e3'") end # http://yaml.org/type/null.html