summary refs log tree commit
diff options
context:
space:
mode:
authorJames Tucker <jftucker@gmail.com>2014-07-13 14:42:20 -0700
committerJames Tucker <jftucker@gmail.com>2014-07-13 14:42:20 -0700
commitb3e7a7c3d7c6236efd0b38301bf7aeb43a4c19ee (patch)
treeb4973a0e0a327306a30fd1cc3daa6c222801260d
parent6f1a4a4873fbf2fd54f2582a9e388b96722e21de (diff)
downloadrack-b3e7a7c3d7c6236efd0b38301bf7aeb43a4c19ee.tar.gz
Gracefully handle cycles in parameters
Might close 632, pending more information.
-rw-r--r--lib/rack/utils.rb6
-rw-r--r--test/spec_utils.rb11
2 files changed, 16 insertions, 1 deletions
diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb
index 264b6b62..32868bdb 100644
--- a/lib/rack/utils.rb
+++ b/lib/rack/utils.rb
@@ -533,7 +533,11 @@ module Rack
         hash.keys.each do |key|
           value = hash[key]
           if value.kind_of?(self.class)
-            hash[key] = value.to_params_hash
+            if value.object_id == self.object_id
+              hash[key] = hash
+            else
+              hash[key] = value.to_params_hash
+            end
           elsif value.kind_of?(Array)
             value.map! {|x| x.kind_of?(self.class) ? x.to_params_hash : x}
           end
diff --git a/test/spec_utils.rb b/test/spec_utils.rb
index de12f83d..f6acb436 100644
--- a/test/spec_utils.rb
+++ b/test/spec_utils.rb
@@ -123,6 +123,17 @@ describe Rack::Utils do
     Rack::Utils.parse_query(",foo=bar;,", ";,").should.equal "foo" => "bar"
   end
 
+  should "not create infinite loops with cycle structures" do
+    ex = { "foo" => nil }
+    ex["foo"] = ex
+
+    params = Rack::Utils::KeySpaceConstrainedParams.new
+    params['foo'] = params
+    lambda {
+      params.to_params_hash.should.equal ex
+    }.should.not.raise
+  end
+
   should "parse nested query strings correctly" do
     Rack::Utils.parse_nested_query("foo").
       should.equal "foo" => nil