From 5279e18722f3c86d9bfd0e7910959be7c4fefe42 Mon Sep 17 00:00:00 2001 From: Adam Malcontenti-Wilson Date: Wed, 10 May 2023 16:50:33 +1000 Subject: [PATCH] Ensure strings that may be confused as YAML1.2 numbers are quoted --- lib/psych/visitors/yaml_tree.rb | 15 ++++++++++++++- test/psych/visitors/test_yaml_tree.rb | 10 ++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/psych/visitors/yaml_tree.rb b/lib/psych/visitors/yaml_tree.rb index 51491783..89220842 100644 --- a/lib/psych/visitors/yaml_tree.rb +++ b/lib/psych/visitors/yaml_tree.rb @@ -278,7 +278,7 @@ def visit_String o style = Nodes::Scalar::FOLDED elsif o =~ /^[^[:word:]][^"]*$/ style = Nodes::Scalar::DOUBLE_QUOTED - elsif not String === @ss.tokenize(o) or /\A0[0-7]*[89]/ =~ o + elsif not String === @ss.tokenize(o) or may_be_confused_as_yaml12?(o) style = Nodes::Scalar::SINGLE_QUOTED end @@ -392,6 +392,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.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 4c48670f..b1d3cbea 100644 --- a/test/psych/visitors/test_yaml_tree.rb +++ b/test/psych/visitors/test_yaml_tree.rb @@ -167,9 +167,19 @@ def test_float end def test_string + # YAML 1.1 int Base 8 assert_match(/'017'/, Psych.dump({'a' => '017'})) assert_match(/'019'/, Psych.dump({'a' => '019'})) assert_match(/'01818'/, Psych.dump({'a' => '01818'})) + + # YAML 1.2 int Base 8 + assert_match(/'0o17'/, Psych.dump({'a' => '0o17'})) + assert_match(/'0o111'/, Psych.dump({'a' => '0o111'})) + + # YAML 1.2 float Number + assert_match(/'12e03'/, Psych.dump({'a' => '12e03'})) + assert_match(/'1.2e3'/, Psych.dump({'a' => '1.2e3'})) + assert_match(/".2e3"/, Psych.dump({'a' => '.2e3'})) end # http://yaml.org/type/null.html