Skip to content

Commit

Permalink
Merge pull request #1414 from tvdeyen/4.0/fix-yaml-safe-load
Browse files Browse the repository at this point in the history
4.0: Fix yaml safe_load
  • Loading branch information
tvdeyen authored Apr 23, 2018
2 parents 0cb6cc4 + 55b6b60 commit 3d1087d
Showing 8 changed files with 38 additions and 16 deletions.
2 changes: 1 addition & 1 deletion app/models/alchemy/cell.rb
Original file line number Diff line number Diff line change
@@ -58,7 +58,7 @@ def translated_label_for(cell_name)
private

def read_yml_file
::YAML.safe_load(ERB.new(File.read(yml_file_path)).result, [], [], true) || []
::YAML.safe_load(ERB.new(File.read(yml_file_path)).result, YAML_WHITELIST_CLASSES, [], true) || []
end

def yml_file_path
2 changes: 1 addition & 1 deletion app/models/alchemy/element/definitions.rb
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ def definition_by_name(name)
#
def read_definitions_file
if ::File.exist?(definitions_file_path)
::YAML.safe_load(ERB.new(File.read(definitions_file_path)).result, [Date, Regexp, Symbol], [], true) || []
::YAML.safe_load(ERB.new(File.read(definitions_file_path)).result, YAML_WHITELIST_CLASSES, [], true) || []
else
raise LoadError, "Could not find elements.yml file! Please run `rails generate alchemy:scaffold`"
end
3 changes: 2 additions & 1 deletion lib/alchemy/config.rb
Original file line number Diff line number Diff line change
@@ -48,7 +48,8 @@ def env_specific_config
# If it does not exist, or its empty, it returns an empty Hash.
#
def read_file(file)
return YAML.load_file(file) || {} if File.exist?(file) # YAML.load_file returns false if file is empty.
YAML.safe_load(ERB.new(File.read(file)).result, YAML_WHITELIST_CLASSES, [], true) || {}
rescue Errno::ENOENT
{}
end

2 changes: 1 addition & 1 deletion lib/alchemy/page_layout.rb
Original file line number Diff line number Diff line change
@@ -159,7 +159,7 @@ def available_on_site?(layout)
#
def read_definitions_file
if File.exist?(layouts_file_path)
YAML.safe_load(ERB.new(File.read(layouts_file_path)).result, [Date, Symbol], [], true) || []
YAML.safe_load(ERB.new(File.read(layouts_file_path)).result, YAML_WHITELIST_CLASSES, [], true) || []
else
raise LoadError, "Could not find page_layouts.yml file! Please run `rails generate alchemy:scaffold`"
end
1 change: 1 addition & 0 deletions lib/alchemy_cms.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Instantiate the global Alchemy namespace
module Alchemy
Alchemy::YAML_WHITELIST_CLASSES = %w(Symbol Date Regexp)
end

# Require globally used external libraries
4 changes: 2 additions & 2 deletions lib/rails/generators/alchemy/base.rb
Original file line number Diff line number Diff line change
@@ -32,9 +32,9 @@ def template_engine
end

def load_alchemy_yaml(name)
YAML.safe_load(ERB.new(File.read("#{Rails.root}/config/alchemy/#{name}")).result, [Regexp], [], true)
YAML.safe_load(ERB.new(File.read("#{Rails.root}/config/alchemy/#{name}")).result, YAML_WHITELIST_CLASSES, [], true)
rescue Errno::ENOENT
puts "\nERROR: Could not read config/alchemy/#{name} file. Please run: rails generate alchemy:scaffold"
puts "\nERROR: Could not read config/alchemy/#{name} file. Please run: `rails generate alchemy:install`"
end
end
end
13 changes: 3 additions & 10 deletions spec/libraries/config_spec.rb
Original file line number Diff line number Diff line change
@@ -54,17 +54,10 @@ module Alchemy

describe '.read_file' do
context 'when given path to yml file exists' do
before { allow(File).to receive(:exist?).and_return(true) }

it 'should call YAML.load_file with the given config path' do
expect(YAML).to receive(:load_file).once.with('path/to/config.yml').and_return({})
Config.send(:read_file, 'path/to/config.yml')
end

context 'but its empty' do
context 'and file is empty' do
before do
allow(File).to receive(:exist?).with('empty_file.yml').and_return(true)
allow(YAML).to receive(:load_file).and_return(false) # YAML.load_file returns false if file is empty.
# YAML.safe_load returns nil if file is empty.
allow(YAML).to receive(:safe_load) { nil }
end

it "should return an empty Hash" do
27 changes: 27 additions & 0 deletions spec/models/alchemy/element_spec.rb
Original file line number Diff line number Diff line change
@@ -119,6 +119,33 @@ module Alchemy

context "with a YAML file including a symbol" do
let(:yaml) { '- name: :symbol' }

before do
expect(File).to receive(:exist?).and_return(true)
expect(File).to receive(:read).and_return(yaml)
end

it "returns the definition without error" do
expect { Element.definitions }.to_not raise_error
end
end

context "with a YAML file including a Date" do
let(:yaml) { '- default: 2017-12-24' }

before do
expect(File).to receive(:exist?).and_return(true)
expect(File).to receive(:read).and_return(yaml)
end

it "returns the definition without error" do
expect { Element.definitions }.to_not raise_error
end
end

context "with a YAML file including a Regex" do
let(:yaml) { "- format: !ruby/regexp '/\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/'" }

before do
expect(File).to receive(:exist?).and_return(true)
expect(File).to receive(:read).and_return(yaml)

0 comments on commit 3d1087d

Please sign in to comment.