summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rubocop_todo.yml6
-rw-r--r--CHANGELOG.md1
-rw-r--r--README.md10
-rw-r--r--UPGRADING.md35
-rw-r--r--lib/hashie/extensions/parsers/yaml_erb_parser.rb12
-rw-r--r--lib/hashie/mash.rb2
-rw-r--r--lib/hashie/version.rb2
-rw-r--r--spec/fixtures/yaml_with_symbols.yml3
-rw-r--r--spec/hashie/mash_spec.rb46
9 files changed, 102 insertions, 15 deletions
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 944b8dc..4f87d3b 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
-# on 2018-09-30 14:46:03 -0500 using RuboCop version 0.52.1.
+# on 2019-03-22 11:21:24 -0400 using RuboCop version 0.52.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
@@ -19,7 +19,7 @@ Metrics/ClassLength:
Metrics/CyclomaticComplexity:
Max: 11
-# Offense count: 17
+# Offense count: 19
# Configuration parameters: CountComments.
Metrics/MethodLength:
Max: 28
@@ -28,6 +28,6 @@ Metrics/MethodLength:
Metrics/PerceivedComplexity:
Max: 10
-# Offense count: 37
+# Offense count: 39
Style/Documentation:
Enabled: false
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2d123ff..caf8080 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ scheme are considered to be bugs.
### Added
* [#323](https://github.com/intridea/hashie/pull/323): Added `Hashie::Extensions::Mash::DefineAccessors` - [@marshall-lee](https://github.com/marshall-lee).
+* [#474](https://github.com/intridea/hashie/pull/474): Expose `YAML#safe_load` options in `Mash#load` - [@riouruma](https://github.com/riouruma), [@dblock](https://github.com/dblock).
### Changed
diff --git a/README.md b/README.md
index 77456ac..c31a632 100644
--- a/README.md
+++ b/README.md
@@ -566,7 +566,7 @@ Twitter.extend mash.to_module # NOTE: if you want another name than settings, ca
Twitter.settings.api_key # => 'abcd'
```
-You can use another parser (by default: YamlErbParser):
+You can use another parser (by default: [YamlErbParser](lib/hashie/extensions/parsers/yaml_erb_parser.rb)):
```
#/etc/data/user.csv
@@ -582,6 +582,14 @@ mash = Mash.load('data/user.csv', parser: MyCustomCsvParser)
mash[1] #=> { name: 'John', lastname: 'Doe' }
```
+The `Mash#load` method calls `YAML.safe_load(path, [], [], true)`.
+
+Specify `whitelist_symbols`, `whitelist_classes` and `aliases` options as needed.
+
+```ruby
+Mash.load('data/user.csv', whitelist_classes: [Symbol], whitelist_symbols: [], aliases: false)
+```
+
### Mash Extension: KeepOriginalKeys
This extension can be mixed into a Mash to keep the form of any keys passed directly into the Mash. By default, Mash converts keys to strings to give indifferent access. This extension still allows indifferent access, but keeps the form of the keys to eliminate confusion when you're not expecting the keys to change.
diff --git a/UPGRADING.md b/UPGRADING.md
index 5a9f05a..6c8ac93 100644
--- a/UPGRADING.md
+++ b/UPGRADING.md
@@ -1,6 +1,41 @@
Upgrading Hashie
================
+### Upgrading to 3.7.0
+
+#### Mash#load takes options
+
+The `Hashie::Mash#load` method now accepts options, changing the interface of `Parser#initialize`. If you have a custom parser, you must update its `initialize` method.
+
+For example, `Hashie::Extensions::Parsers::YamlErbParser` now accepts `whitelist_classes`, `whitelist_symbols` and `aliases` options.
+
+Before:
+
+```ruby
+class Hashie::Extensions::Parsers::YamlErbParser
+ def initialize(file_path)
+ @file_path = file_path
+ end
+end
+```
+
+After:
+
+```ruby
+class Hashie::Extensions::Parsers::YamlErbParser
+ def initialize(file_path, options = {})
+ @file_path = file_path
+ @options = options
+ end
+end
+```
+
+Options can now be passed into `Mash#load`.
+
+```ruby
+Mash.load(filename, whitelist_classes: [])
+```
+
### Upgrading to 3.5.2
#### Disable logging in Mash subclasses
diff --git a/lib/hashie/extensions/parsers/yaml_erb_parser.rb b/lib/hashie/extensions/parsers/yaml_erb_parser.rb
index d3b5c80..05edc40 100644
--- a/lib/hashie/extensions/parsers/yaml_erb_parser.rb
+++ b/lib/hashie/extensions/parsers/yaml_erb_parser.rb
@@ -6,19 +6,23 @@ module Hashie
module Extensions
module Parsers
class YamlErbParser
- def initialize(file_path)
+ def initialize(file_path, options = {})
@content = File.read(file_path)
@file_path = file_path.is_a?(Pathname) ? file_path.to_s : file_path
+ @options = options
end
def perform
template = ERB.new(@content)
template.filename = @file_path
- YAML.safe_load template.result, [], [], true
+ whitelist_classes = @options.fetch(:whitelist_classes) { [] }
+ whitelist_symbols = @options.fetch(:whitelist_symbols) { [] }
+ aliases = @options.fetch(:aliases) { true }
+ YAML.safe_load template.result, whitelist_classes, whitelist_symbols, aliases
end
- def self.perform(file_path)
- new(file_path).perform
+ def self.perform(file_path, options = {})
+ new(file_path, options).perform
end
end
end
diff --git a/lib/hashie/mash.rb b/lib/hashie/mash.rb
index f41d745..650a269 100644
--- a/lib/hashie/mash.rb
+++ b/lib/hashie/mash.rb
@@ -107,7 +107,7 @@ module Hashie
raise ArgumentError, "The following file doesn't exist: #{path}" unless File.file?(path)
parser = options.fetch(:parser) { Hashie::Extensions::Parsers::YamlErbParser }
- @_mashes[path] = new(parser.perform(path)).freeze
+ @_mashes[path] = new(parser.perform(path, options.except(:parser))).freeze
end
def to_module(mash_method_name = :settings)
diff --git a/lib/hashie/version.rb b/lib/hashie/version.rb
index 1206e92..22480fb 100644
--- a/lib/hashie/version.rb
+++ b/lib/hashie/version.rb
@@ -1,3 +1,3 @@
module Hashie
- VERSION = '3.6.1'.freeze
+ VERSION = '3.7.0'.freeze
end
diff --git a/spec/fixtures/yaml_with_symbols.yml b/spec/fixtures/yaml_with_symbols.yml
new file mode 100644
index 0000000..c761e2b
--- /dev/null
+++ b/spec/fixtures/yaml_with_symbols.yml
@@ -0,0 +1,3 @@
+:user_icon:
+ :width: 200
+ :height: 200
diff --git a/spec/hashie/mash_spec.rb b/spec/hashie/mash_spec.rb
index be82281..59e3183 100644
--- a/spec/hashie/mash_spec.rb
+++ b/spec/hashie/mash_spec.rb
@@ -645,7 +645,7 @@ describe Hashie::Mash do
context 'if the file exists' do
before do
expect(File).to receive(:file?).with(path).and_return(true)
- expect(parser).to receive(:perform).with(path).and_return(config)
+ expect(parser).to receive(:perform).with(path, {}).and_return(config)
end
it { is_expected.to be_a(Hashie::Mash) }
@@ -677,7 +677,7 @@ describe Hashie::Mash do
before do
expect(File).to receive(:file?).with(path).and_return(true)
- expect(parser).to receive(:perform).with(path).and_return(config)
+ expect(parser).to receive(:perform).with(path, {}).and_return(config)
end
it 'return a Mash from a file' do
@@ -693,8 +693,8 @@ describe Hashie::Mash do
before do
expect(File).to receive(:file?).with(path).and_return(true)
expect(File).to receive(:file?).with("#{path}+1").and_return(true)
- expect(parser).to receive(:perform).once.with(path).and_return(config)
- expect(parser).to receive(:perform).once.with("#{path}+1").and_return(config)
+ expect(parser).to receive(:perform).once.with(path, {}).and_return(config)
+ expect(parser).to receive(:perform).once.with("#{path}+1", {}).and_return(config)
end
it 'cache the loaded yml file', :test_cache do
@@ -710,9 +710,45 @@ describe Hashie::Mash do
context 'when the file has aliases in it' do
it 'can use the aliases and does not raise an error' do
mash = Hashie::Mash.load('spec/fixtures/yaml_with_aliases.yml')
-
expect(mash.company_a.accounts.admin.password).to eq('secret')
end
+ it 'can override the value of aliases' do
+ expect do
+ Hashie::Mash.load('spec/fixtures/yaml_with_aliases.yml', aliases: false)
+ end.to raise_error Psych::BadAlias, /base_accounts/
+ end
+ end
+
+ context 'when the file has symbols' do
+ it 'can override the value of whitelist_classes' do
+ mash = Hashie::Mash.load('spec/fixtures/yaml_with_symbols.yml', whitelist_classes: [Symbol])
+ expect(mash.user_icon.width).to eq(200)
+ end
+ it 'uses defaults for whitelist_classes' do
+ expect do
+ Hashie::Mash.load('spec/fixtures/yaml_with_symbols.yml')
+ end.to raise_error Psych::DisallowedClass, /Symbol/
+ end
+ it 'can override the value of whitelist_symbols' do
+ mash = Hashie::Mash.load('spec/fixtures/yaml_with_symbols.yml',
+ whitelist_classes: [Symbol],
+ whitelist_symbols: %i[
+ user_icon
+ width
+ height
+ ])
+ expect(mash.user_icon.width).to eq(200)
+ end
+ it 'raises an error on insufficient whitelist_symbols' do
+ expect do
+ Hashie::Mash.load('spec/fixtures/yaml_with_symbols.yml',
+ whitelist_classes: [Symbol],
+ whitelist_symbols: %i[
+ user_icon
+ width
+ ])
+ end.to raise_error Psych::DisallowedClass, /Symbol/
+ end
end
end