From c0ab42fecc504cbe94ecbd3d6bdbda74e4fe54fb Mon Sep 17 00:00:00 2001
From: Benjamin Neff <benjamin@coding4coffee.ch>
Date: Mon, 27 Jun 2016 04:00:59 +0200
Subject: [PATCH] check if `links` is an array in the JRD

---
 lib/connection_tester.rb           | 8 ++++++--
 spec/lib/connection_tester_spec.rb | 7 +++++++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/lib/connection_tester.rb b/lib/connection_tester.rb
index c75fdedc20..6619250e50 100644
--- a/lib/connection_tester.rb
+++ b/lib/connection_tester.rb
@@ -129,6 +129,8 @@ class ConnectionTester
       nd_resp = http.get(find_nodeinfo_url(ni_resp.body))
       find_software_version(nd_resp.body)
     end
+  rescue NodeInfoFailure => e
+    raise e
   rescue JSON::Schema::ValidationError, JSON::Schema::SchemaError => e
     raise NodeInfoFailure, "#{e.class}: #{e.message}"
   rescue Faraday::ResourceNotFound, JSON::JSONError => e
@@ -183,8 +185,10 @@ class ConnectionTester
 
   # walk the JSON document, get the actual document location
   def find_nodeinfo_url(body)
-    links = JSON.parse(body)
-    links.fetch("links").find { |entry|
+    jrd = JSON.parse(body)
+    links = jrd.fetch("links")
+    raise NodeInfoFailure, "invalid JRD: '#/links' is not an array!" unless links.is_a?(Array)
+    links.find { |entry|
       entry.fetch("rel") == NODEINFO_SCHEMA
     }.fetch("href")
   end
diff --git a/spec/lib/connection_tester_spec.rb b/spec/lib/connection_tester_spec.rb
index e3a0b92a03..22fc906bd9 100644
--- a/spec/lib/connection_tester_spec.rb
+++ b/spec/lib/connection_tester_spec.rb
@@ -145,6 +145,13 @@ describe ConnectionTester do
       expect { tester.nodeinfo }.to raise_error(ConnectionTester::NodeInfoFailure)
     end
 
+    it "handles a invalid jrd document gracefully" do
+      invalid_wellknown = {links: {rel: ConnectionTester::NODEINFO_SCHEMA, href: "/nodeinfo"}}
+      stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}")
+        .to_return(status: 200, body: JSON.generate(invalid_wellknown))
+      expect { tester.nodeinfo }.to raise_error(ConnectionTester::NodeInfoFailure)
+    end
+
     it "handles a invalid nodeinfo document gracefully" do
       stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}")
         .to_return(status: 200, body: JSON.generate(ni_wellknown))
-- 
GitLab