From 25158fabc2c83862de90f319b7dffc9e60904dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ondruch?= Date: Tue, 30 Aug 2022 09:07:15 +0200 Subject: [PATCH 1/4] Permit `Time` class loading from YAML. Since Psych 4.0, the `safe_load` is used as default loading mechanism. There are just a few permitted classes and `Time` is not one of them [[1]]. This results it test failure: ~~~ Error: test_converting_to_yaml(DocumentTest::TestSimpleConventionallyNamedDocument): Psych::DisallowedClass: Tried to load unspecified class: Time ~~~ Please also note that in YAML specs 1.2, the `timestamp` is not listed as supported tag anymore [[2]]. Given that: 1) ronn-ng does not provide any supported way of loading the serialized YAML. 2) The `to_yaml` does not appear to be used internally/externally anywhere. 3) If there were users of this functionality, it would have been already know, reported and fixed at this moment. The best course of action is fixing the test case by listing the `Time` as valid class for parsing. Fixes #80 [1]: https://docs.ruby-lang.org/en/master/Psych.html#method-c-safe_load [2]: https://github.com/yaml/yaml-spec/issues/268 --- test/test_ronn_document.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_ronn_document.rb b/test/test_ronn_document.rb index 75788dc..a86793f 100644 --- a/test/test_ronn_document.rb +++ b/test/test_ronn_document.rb @@ -146,7 +146,7 @@ def canonicalize(text) 'toc' => [['NAME', 'NAME']], 'organization' => nil, 'manual' => nil - }, YAML.load(@doc.to_yaml)) + }, YAML.load(@doc.to_yaml, permitted_classes: [Time])) end test 'converting to json' do From c8aaa0235ed0dd41ea7ea83e5133ae494cbf072a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ondruch?= Date: Tue, 30 Aug 2022 09:59:07 +0200 Subject: [PATCH 2/4] Check if `YAML.load` supports `permitted_classes` kwarg. This is due to Ruby 3.1 + Psych 4.0 changed changed `YAML.load` to use `safe_load` by default. --- test/test_ronn_document.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/test_ronn_document.rb b/test/test_ronn_document.rb index a86793f..c9c08c7 100644 --- a/test/test_ronn_document.rb +++ b/test/test_ronn_document.rb @@ -137,6 +137,15 @@ def canonicalize(text) test 'converting to yaml' do require 'yaml' + # Check if `permitted_classes` keyword argument is available. That means + # `safe_load` is the default loading mechanism, i.e. Ruby 3.1 + Psych 4.0 + # are used. + kwargs = !(YAML.method(:load).parameters & [[:key, :permitted_classes]]).empty? + loaded_yaml = if kwargs + YAML.load(@doc.to_yaml, permitted_classes: [Time]) + else + YAML.load(@doc.to_yaml) + end assert_equal({ 'section' => '1', 'name' => 'hello', @@ -146,7 +155,7 @@ def canonicalize(text) 'toc' => [['NAME', 'NAME']], 'organization' => nil, 'manual' => nil - }, YAML.load(@doc.to_yaml, permitted_classes: [Time])) + }, loaded_yaml) end test 'converting to json' do From d7bbcd7ef4461bd28eb3e9fc1880f7a5d5d46d88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ondruch?= Date: Tue, 30 Aug 2022 10:09:19 +0200 Subject: [PATCH 3/4] Extract the YAML loading logic into function This is to make the test case less poluted. Can be dropped once only Ruby 3.1+ is supported. --- test/test_ronn_document.rb | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/test/test_ronn_document.rb b/test/test_ronn_document.rb index c9c08c7..ae6f72a 100644 --- a/test/test_ronn_document.rb +++ b/test/test_ronn_document.rb @@ -12,6 +12,18 @@ def canonicalize(text) .tr('"', "'") end + def yaml_load(yaml) + # Check if `permitted_classes` keyword argument is available. That means + # `safe_load` is the default loading mechanism, i.e. Ruby 3.1 + Psych 4.0 + # are used. + kwargs = !(YAML.method(:load).parameters & [[:key, :permitted_classes]]).empty? + if kwargs + YAML.load(yaml, permitted_classes: [Time]) + else + YAML.load(yaml) + end + end + test 'new with path' do doc = Ronn::Document.new(SIMPLE_FILE) assert_equal File.read(SIMPLE_FILE), doc.data @@ -137,15 +149,6 @@ def canonicalize(text) test 'converting to yaml' do require 'yaml' - # Check if `permitted_classes` keyword argument is available. That means - # `safe_load` is the default loading mechanism, i.e. Ruby 3.1 + Psych 4.0 - # are used. - kwargs = !(YAML.method(:load).parameters & [[:key, :permitted_classes]]).empty? - loaded_yaml = if kwargs - YAML.load(@doc.to_yaml, permitted_classes: [Time]) - else - YAML.load(@doc.to_yaml) - end assert_equal({ 'section' => '1', 'name' => 'hello', @@ -155,7 +158,7 @@ def canonicalize(text) 'toc' => [['NAME', 'NAME']], 'organization' => nil, 'manual' => nil - }, loaded_yaml) + }, yaml_load(@doc.to_yaml)) end test 'converting to json' do From 7c49ae1926728987ca97e014931bb9148aa868b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ondruch?= Date: Tue, 30 Aug 2022 10:25:46 +0200 Subject: [PATCH 4/4] Use symbol array literal. This should make Rubocop happy. --- test/test_ronn_document.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_ronn_document.rb b/test/test_ronn_document.rb index ae6f72a..aa97a88 100644 --- a/test/test_ronn_document.rb +++ b/test/test_ronn_document.rb @@ -16,7 +16,7 @@ def yaml_load(yaml) # Check if `permitted_classes` keyword argument is available. That means # `safe_load` is the default loading mechanism, i.e. Ruby 3.1 + Psych 4.0 # are used. - kwargs = !(YAML.method(:load).parameters & [[:key, :permitted_classes]]).empty? + kwargs = !(YAML.method(:load).parameters & [%i[key permitted_classes]]).empty? if kwargs YAML.load(yaml, permitted_classes: [Time]) else