Skip to content

Commit

Permalink
fix: sanitize fields when rendering pact html
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Apr 1, 2019
1 parent 2a0fbc7 commit dca7650
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 10 deletions.
14 changes: 9 additions & 5 deletions lib/pact/doc/markdown/consumer_contract_renderer.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'pact/doc/markdown/interaction_renderer'
require 'pact/doc/sort_interactions'
require 'rack/utils'

module Pact
module Doc
Expand All @@ -15,7 +16,7 @@ def self.call consumer_contract
end

def call
title + summaries_title + summaries.join + interactions_title + full_interactions.join
title + summaries_title + summaries + interactions_title + full_interactions
end

private
Expand All @@ -39,29 +40,32 @@ def interactions_title
end

def summaries
interaction_renderers.collect(&:render_summary)
interaction_renderers.collect(&:render_summary).join
end

def full_interactions
interaction_renderers.collect(&:render_full_interaction)
interaction_renderers.collect(&:render_full_interaction).join
end

def sorted_interactions
SortInteractions.call(consumer_contract.interactions)
end

def consumer_name
markdown_escape consumer_contract.consumer.name
h(markdown_escape consumer_contract.consumer.name)
end

def provider_name
markdown_escape consumer_contract.provider.name
h(markdown_escape consumer_contract.provider.name)
end

def markdown_escape string
string.gsub('*','\*').gsub('_','\_')
end

def h(text)
Rack::Utils.escape_html(text)
end
end
end
end
Expand Down
6 changes: 3 additions & 3 deletions lib/pact/doc/markdown/interaction.erb
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<a name="<%= interaction.id %>"></a>
<%= if interaction.has_provider_state?
"Given **#{interaction.provider_state}**, upon receiving"
"Given **#{h(interaction.provider_state)}**, upon receiving"
else
"Upon receiving"
end
%> **<%= interaction.description %>** from <%= interaction.consumer_name %>, with
%> **<%= h(interaction.description) %>** from <%= h(interaction.consumer_name) %>, with
```json
<%= interaction.request %>
```
<%= interaction.provider_name %> will respond with:
<%= h(interaction.provider_name) %> will respond with:
```json
<%= interaction.response %>
```
8 changes: 6 additions & 2 deletions lib/pact/doc/markdown/interaction_renderer.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'erb'
require 'pact/doc/interaction_view_model'
require 'rack/utils'

module Pact
module Doc
Expand All @@ -12,8 +13,8 @@ def initialize interaction, pact
end

def render_summary
suffix = interaction.has_provider_state? ? " given #{interaction.provider_state}" : ""
"* [#{interaction.description(true)}](##{interaction.id})#{suffix}\n\n"
suffix = interaction.has_provider_state? ? " given #{h(interaction.provider_state)}" : ""
"* [#{h(interaction.description(true))}](##{interaction.id})#{suffix}\n\n"
end

def render_full_interaction
Expand All @@ -36,6 +37,9 @@ def template_contents(template_file)
File.dirname(__FILE__) + template_file
end

def h(text)
Rack::Utils.escape_html(text)
end
end
end
end
Expand Down
16 changes: 16 additions & 0 deletions spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ module Markdown
it "renders the interactions" do
expect(subject.call).to eq(expected_output)
end

context "when the pact fields have html embedded in them" do
let(:consumer_contract) { Pact::ConsumerContract.from_uri './spec/support/markdown_pact_with_html.json' }

its(:title) { is_expected.to include "&lt;h1&gt;Consumer&lt;&#x2F;h1&gt;" }
its(:title) { is_expected.to include "&lt;h1&gt;Provider&lt;&#x2F;h1&gt;" }

its(:summaries_title) { is_expected.to include "&lt;h1&gt;Consumer&lt;&#x2F;h1&gt;" }
its(:summaries_title) { is_expected.to include "&lt;h1&gt;Provider&lt;&#x2F;h1&gt;" }

its(:summaries) { is_expected.to include "&lt;h1&gt;alligators&lt;/h1&gt;" }
its(:summaries) { is_expected.to_not include "<h1>alligators</h1>" }

its(:full_interactions) { is_expected.to include "&lt;h1&gt;alligators&lt;/h1&gt;" }
its(:full_interactions) { is_expected.to_not include "<h1>alligators</h1>" }
end
end

end
Expand Down
27 changes: 27 additions & 0 deletions spec/support/markdown_pact_with_html.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"provider": {
"name": "Some <h1>Provider</h1>"
},
"consumer": {
"name": "Some <h1>Consumer</h1>"
},
"interactions": [
{
"description": "a request for <h1>alligators</h1> in France",
"provider_state": "<h1>alligators</h1> exist",
"request": {
"method": "get",
"path": "/alligators"
},
"response": {
"headers" : {"Content-Type": "application/json"},
"status" : 200,
"body" : {
"alligators": [{
"name": "Bob"
}]
}
}
}
]
}

0 comments on commit dca7650

Please sign in to comment.