Skip to content

Commit

Permalink
Fixed: Vault warns when valid JSON contains special character sequences
Browse files Browse the repository at this point in the history
This partially reverts commit 2e0ee1b

Fixes #415

Signed-off-by: Joseph Larionov <[email protected]>
  • Loading branch information
decoyjoe committed Nov 26, 2024
1 parent 11d5fc5 commit e959039
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 50 deletions.
38 changes: 0 additions & 38 deletions lib/chef/knife/mixin/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,48 +39,10 @@ def values_from_file(file)
end

def values_from_json(json)
validate_json(json)
JSON.parse(json)
rescue JSON::ParserError
raise JSON::ParserError, "#{json} is not valid JSON!"
end

# I/P: json string
# Raises `InvalidValue` if any of the json's values contain non-printable characters.
def validate_json(json)
begin
parsed_json = JSON.parse(json)
rescue JSON::ParserError
raise ChefVault::Exceptions::InvalidValue, "#{json} is not valid JSON!"
end

check_value(parsed_json) # Start checking from the root of the parsed JSON
end

def check_value(value, parent_key = nil)
if value.is_a?(Array)
value.each { |item| check_value(item, parent_key) }
elsif value.is_a?(Hash)
value.each do |key, nested_value|
next if key == "password" # Skip the password key

check_value(nested_value, key)
end
else
unless printable?(value.to_s)
msg = "Value '#{value}' of key '#{parent_key}' contains non-printable characters."
ChefVault::Log.warn(msg)
end
end
end

# I/P: String
# O/P: true/false
# returns true if string is free of non-printable characters (escape sequences)
# this returns false for whitespace escape sequences as well, e.g. \n\t
def printable?(string)
!/[[:^print:]]/.match?(string) # Returns true if the string is printable
end
end
end
end
34 changes: 22 additions & 12 deletions spec/chef/helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,34 @@
RSpec.describe ChefVault::Mixin::Helper do
include ChefVault::Mixin::Helper

let(:json) { { "username": "root" } }
let(:json_data) { '{"username": "root", "password": "abcabc"}' }
let(:buggy_json_data) { '{"username": "root", "password": "abc\abc"' }
before do
allow(ChefVault::Log).to receive(:warn)
end

let(:json_base) { { "username": "root" } }
let(:valid_json) { '{"username": "root", "password": "abcabc"}' }
let(:malformed_json) { '{"username": ' }
let(:valid_json_with_special_character) { { "Data": "Null->\u0000<-Byte" } }

describe "#validate_json" do
it "Raises InvalidValue Exception when invalid data provided" do
expect { validate_json(buggy_json_data) }.to raise_error(ChefVault::Exceptions::InvalidValue)
describe "#values_from_json" do
it "should raise error when invalid JSON provided" do
expect { values_from_json(malformed_json) }.to raise_error(JSON::ParserError)
end

it "Not to raise error if valid data provided" do
expect { validate_json(json_data) }.to_not raise_error
it "should not raise error when valid JSON provided" do
expect { values_from_json(valid_json) }.to_not raise_error
end

it "not to raise error if data consist of tab/new line OR space" do
%w{abc\tabc abc\nabc}.each do |pass|
json_data_with_slash = json.merge("password": pass)
expect { validate_json(json_data_with_slash.to_json) }.to_not raise_error
it "should not raise error if JSON contains tab, newline, or space characters" do
["abc\tabc", "abc\nabc", "abc abc"].each do |pass|
json_data_with_slash = json_base.merge("password": pass)
expect { values_from_json(json_data_with_slash.to_json) }.to_not raise_error
end
end

it 'should not warn or error when JSON contains special character sequences' do
expect(ChefVault::Log).to_not receive(:warn)
expect { values_from_json(valid_json_with_special_character.to_json) }.to_not raise_error
end
end
end

0 comments on commit e959039

Please sign in to comment.