summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Tucker <jftucker@gmail.com>2013-02-06 15:31:53 -0800
committerJames Tucker <jftucker@gmail.com>2013-02-07 18:33:26 -0800
commit8748d492a4bc966de51f2ddf8edd498a3fa0e122 (patch)
tree9820cdac17ec246551d3075f52d324afd265267d
parent4d77cc9cfbdeb6b6e3a2323a3726273acb71a6e3 (diff)
downloadrack-8748d492a4bc966de51f2ddf8edd498a3fa0e122.tar.gz
Add secure_compare to Rack::Utils
Conflicts: test/spec_utils.rb
-rw-r--r--lib/rack/utils.rb12
-rw-r--r--test/spec_utils.rb5
2 files changed, 17 insertions, 0 deletions
diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb
index 3ffdb3a2..561e46e5 100644
--- a/lib/rack/utils.rb
+++ b/lib/rack/utils.rb
@@ -395,6 +395,18 @@ module Rack
end
module_function :byte_ranges
+ # Constant time string comparison.
+ def secure_compare(a, b)
+ return false unless bytesize(a) == bytesize(b)
+
+ l = a.unpack("C*")
+
+ r, i = 0, -1
+ b.each_byte { |v| r |= v ^ l[i+=1] }
+ r == 0
+ end
+ module_function :secure_compare
+
# Context allows the use of a compatible middleware at different points
# in a request handling stack. A compatible middleware must define
# #context which should take the arguments env and app. The first of which
diff --git a/test/spec_utils.rb b/test/spec_utils.rb
index de28a4f2..622b8ff5 100644
--- a/test/spec_utils.rb
+++ b/test/spec_utils.rb
@@ -354,6 +354,11 @@ describe Rack::Utils do
Rack::Utils.bytesize("FOO\xE2\x82\xAC").should.equal 6
end
+ should "should perform constant time string comparison" do
+ Rack::Utils.secure_compare('a', 'a').should.equal true
+ Rack::Utils.secure_compare('a', 'b').should.equal false
+ end
+
should "return status code for integer" do
Rack::Utils.status_code(200).should.equal 200
end