Skip to content
This repository has been archived by the owner on Mar 9, 2020. It is now read-only.

Commit

Permalink
accessing keys doesn't expose them anymore, only #expose
Browse files Browse the repository at this point in the history
  • Loading branch information
technoweenie committed Mar 9, 2012
1 parent b8b3838 commit f10dfcd
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 40 deletions.
18 changes: 4 additions & 14 deletions README.md
Expand Up @@ -15,26 +15,16 @@ tainted = TaintedHash.new hash

You can access keys manually to get the value and approve them:

Use `#expose` to expose keys.

```ruby
tainted.include?(:a) # false
tainted['a'] # Returns 2
tainted[:a] # Symbols are OK too.
tainted.include?(:a) # false, not exposed
tainted.expose :a
tainted.include?(:a) # true
tainted.keys # ['a']

tainted.fetch(:b) # Returns 2
tainted.include?(:b) # true
tainted.keys # ['a', 'b']

tainted.values_at(:b, :c) # Returns [2, 3]
tainted.include?(:c) # true
tainted.keys # ['a', 'b', 'c']
```

You can also explicitly expose keys:

```ruby
tainted.expose :a, :b
```

If using Rails 2.3, require `tainted_hash/rails` to setup the necessary hooks.
Expand Down
17 changes: 4 additions & 13 deletions lib/tainted_hash.rb
Expand Up @@ -84,11 +84,7 @@ def extra_keys
# Returns the value of the key, or the default.
def fetch(key, default = nil)
key_s = key.to_s
if @original_hash.key?(key_s)
self[key_s] = @original_hash[key_s]
else
default
end
@original_hash.fetch key_s, default
end

# Public: Gets the value for the key, and exposes the key for the Hash.
Expand All @@ -106,8 +102,6 @@ def [](key)
value = @original_hash[key_s] = self.class.new(value, @new_class)
else value
end
self[key_s] = value
value
end

# Public: Attempts to set the key of a frozen hash.
Expand Down Expand Up @@ -153,9 +147,7 @@ def include?(key)
#
# Returns an Array of the values (or nil if there is no value) for the keys.
def values_at(*keys)
str_keys = keys.map { |k| k.to_s }
expose *str_keys
super(*str_keys)
@original_hash.values_at *keys.map { |k| k.to_s }
end

# Public: Merges the given hash with the internal and a dup of the current
Expand All @@ -175,8 +167,7 @@ def merge(hash)
# Returns this TaintedHash.
def update(hash)
hash.each do |key, value|
key_s = key.to_s
@original_hash[key_s] = self[key_s] = value
@original_hash[key.to_s] = value
end
self
end
Expand Down Expand Up @@ -226,7 +217,7 @@ def slice(*keys)
str_keys = @original_hash.keys & keys.map { |k| k.to_s }
hash = self.class.new
str_keys.each do |key|
hash[key] = self[key]
hash[key] = @original_hash[key]
end
hash
end
Expand Down
30 changes: 17 additions & 13 deletions test/tainted_hash_test.rb
Expand Up @@ -26,8 +26,8 @@ def test_dup
@tainted[:c].expose :name
@tainted.expose :a
dup = @tainted.dup.expose :b
assert_equal %w(a c), @tainted.keys.sort
assert_equal %w(a b c), dup.keys.sort
assert_equal %w(a), @tainted.keys.sort
assert_equal %w(a b), dup.keys.sort
end

def test_expose_keys
Expand All @@ -43,14 +43,14 @@ def test_fetching_a_value
assert !@tainted.include?(:d)
assert_equal 1, @tainted.fetch(:a, :default)
assert_equal :default, @tainted.fetch(:d, :default)
assert @tainted.include?(:a)
assert !@tainted.include?(:a)
assert !@tainted.include?(:d)
end

def test_getting_a_value
assert !@tainted.include?(:a)
assert_equal 1, @tainted[:a]
assert @tainted.include?(:a)
assert !@tainted.include?(:a)
end

def test_setting_a_value
Expand All @@ -62,7 +62,7 @@ def test_setting_a_value

def test_deleting_a_value
assert_equal 1, @tainted[:a]
assert @tainted.include?(:a)
assert !@tainted.include?(:a)
assert_equal 1, @tainted.delete(:a)
assert !@tainted.include?(:a)
end
Expand All @@ -75,9 +75,13 @@ def test_slicing_a_hash
output = @tainted.slice(:a, :b)
assert_equal({'a' => 1, 'b' => 2}, output.to_hash)

assert @tainted.include?(:a)
assert @tainted.include?(:b)
assert !@tainted.include?(:a)
assert !@tainted.include?(:b)
assert !@tainted.include?(:c)

assert output.include?(:a)
assert output.include?(:b)
assert !output.include?(:c)
end

def test_yields_real_values
Expand All @@ -102,7 +106,7 @@ def test_slicing_nested_hashes
assert_equal 2, slice[:b]
assert_equal 'bob', slice[:c][:name]
assert_equal %w(b c), slice.keys.sort
assert_equal %w(name), slice[:c].keys
assert_equal [], slice[:c].keys
end

def test_slicing_and_building_hashes
Expand All @@ -126,8 +130,8 @@ def test_update_hash
assert !@tainted.include?(:a)
assert !@tainted.include?(:d)
@tainted.update :a => 2, :d => 1
assert @tainted.include?(:a)
assert @tainted.include?(:d)
assert !@tainted.include?(:a)
assert !@tainted.include?(:d)
assert_equal 2, @tainted[:a]
assert_equal 1, @tainted[:d]
end
Expand All @@ -140,13 +144,13 @@ def test_does_not_expose_missing_keys
assert !@tainted.include?(:d)
end

def test_values_at_exposes_keys
def test_values_at_doesnt_expose_keys
assert !@tainted.include?(:a)
assert !@tainted.include?(:b)
assert !@tainted.include?(:d)
assert_equal [1,2, nil], @tainted.values_at(:a, :b, :d)
assert @tainted.include?(:a)
assert @tainted.include?(:b)
assert !@tainted.include?(:a)
assert !@tainted.include?(:b)
assert !@tainted.include?(:d)
end

Expand Down

0 comments on commit f10dfcd

Please sign in to comment.