Skip to content

Commit

Permalink
updating templates to allow for templates that do automatic html esca…
Browse files Browse the repository at this point in the history
…ping because of xss
  • Loading branch information
bleonard committed Sep 26, 2010
1 parent 1705850 commit bb46e65
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 17 deletions.
8 changes: 6 additions & 2 deletions lib/vanity/commands/report.rb
Expand Up @@ -22,12 +22,16 @@ def render(path, locals = {})
end

# Escape HTML.
def h(html)
def vanity_h(html)
CGI.escapeHTML(html)
end

def vanity_html_safe(text)
text
end

# Dumbed down from Rails' simple_format.
def simple_format(text, options={})
def vanity_simple_format(text, options={})
open = "<p #{options.map { |k,v| "#{k}=\"#{CGI.escapeHTML v}\"" }.join(" ")}>"
text = open + text.gsub(/\r\n?/, "\n"). # \r\n and \r -> \n
gsub(/\n\n+/, "</p>\n\n#{open}"). # 2+ newline -> paragraph
Expand Down
16 changes: 16 additions & 0 deletions lib/vanity/frameworks/rails.rb
Expand Up @@ -137,6 +137,22 @@ def ab_test(name, &block)
value
end
end

def vanity_h(text)
h(text)
end

def vanity_html_safe(text)
if text.respond_to?(:html_safe!)
text.html_safe!
else
text
end
end

def vanity_simple_format(text, html_options={})
vanity_html_safe(simple_format(text, html_options))
end
end


Expand Down
2 changes: 1 addition & 1 deletion lib/vanity/templates/_ab_test.erb
Expand Up @@ -5,7 +5,7 @@
<% score.alts.each do |alt| %>
<tr class="<%= "choice" if score.choice == alt %>">
<td class="option"><%= alt.name.gsub(/^o/, "O") %>:</td>
<td class="value"><code><%=h alt.value.to_s %></code></td>
<td class="value"><code><%=vanity_h alt.value.to_s %></code></td>
<td>
<%= "%.1f%%" % [alt.conversion_rate * 100] %>
<%= "(%d%% better than %s)" % [alt.difference, score.least.name] if alt.difference && alt.difference >= 1 %>
Expand Down
4 changes: 2 additions & 2 deletions lib/vanity/templates/_experiment.erb
@@ -1,5 +1,5 @@
<h3><%=h experiment.name %> <span class="type">(<%= experiment.class.friendly_name %>)</span></h3>
<%= experiment.description.to_s.split(/\n\s*\n/).map { |para| %{<p class="description">#{h para}</p>} }.join %>
<h3><%=vanity_h experiment.name %> <span class="type">(<%= experiment.class.friendly_name %>)</span></h3>
<%= experiment.description.to_s.split(/\n\s*\n/).map { |para| vanity_html_safe(%{<p class="description">#{vanity_h para}</p>}) }.join %>
<%= render Vanity.template(experiment.type), :experiment=>experiment %>
<p class="meta">Started <%= experiment.created_at.strftime("%a, %b %d") %>
<%= " | Completed #{experiment.completed_at.strftime("%a, %b %d")}" unless experiment.active? %></p>
2 changes: 1 addition & 1 deletion lib/vanity/templates/_experiments.erb
@@ -1,6 +1,6 @@
<ul class="experiments">
<% experiments.sort_by { |id, experiment| experiment.created_at }.reverse.each do |id, experiment| %>
<li class="experiment <%= experiment.type %>" id="experiment_<%=h id.to_s %>">
<li class="experiment <%= experiment.type %>" id="experiment_<%=vanity_h id.to_s %>">
<%= render Vanity.template("experiment"), :id=>id, :experiment=>experiment %>
</li>
<% end %>
Expand Down
12 changes: 6 additions & 6 deletions lib/vanity/templates/_metric.erb
@@ -1,14 +1,14 @@
<h3><%=h metric.name %></h3>
<%= simple_format h(Vanity::Metric.description(metric).to_s), :class=>"description" %>
<h3><%=vanity_h metric.name %></h3>
<%= vanity_simple_format vanity_h(Vanity::Metric.description(metric).to_s), :class=>"description" %>
<%=
begin
data = Vanity::Metric.data(metric)
min, max = data.map(&:last).minmax
js = data.map { |date,value| "['#{date.to_time.httpdate}',#{value}]" }.join(",")
%{<div class="chart"></div>
vanity_html_safe(%{<div class="chart"></div>
<script type="text/javascript">
$(function(){Vanity.metric("#{h id.to_s}").plot([{label:"#{h metric.name}", data: [#{js}]}])})
</script>}
$(function(){Vanity.metric("#{vanity_h id.to_s}").plot([{label:"#{vanity_h metric.name}", data: [#{js}]}])})
</script>})
rescue Exception=>ex
%{<div class="error">#{h ex.message}</div>}
%{<div class="error">#{vanity_h ex.message}</div>}
end %>
2 changes: 1 addition & 1 deletion lib/vanity/templates/_metrics.erb
Expand Up @@ -8,6 +8,6 @@
<form id="milestones">
<% experiments.each do |id, experiment| %>
<label><input type="checkbox" name="milestone" data-start="<%= experiment.created_at.httpdate %>"
data-end="<%= (experiment.completed_at || Time.now).httpdate %>"><%=h experiment.name %></label>
data-end="<%= (experiment.completed_at || Time.now).httpdate %>"><%=vanity_h experiment.name %></label>
<% end %>
</form>
8 changes: 4 additions & 4 deletions lib/vanity/templates/_report.erb
Expand Up @@ -4,11 +4,11 @@
<style>
.vanity { margin: 2em auto; width: 40em; font-family: "Helvetica Neue", "Helvetica", "Verdana", sans-serif }
.vanity h1 { margin: 1em 0; border-bottom: 3px solid #ccc }
<%= File.read(Vanity.template("vanity.css")) %>
<%= vanity_html_safe(File.read(Vanity.template("vanity.css"))) %>
</style>
<script type="text/javascript"><%= File.read(Vanity.template("jquery.min.js")) %></script>
<script type="text/javascript"><%= File.read(Vanity.template("flot.min.js")) %></script>
<script type="text/javascript"><%= File.read(Vanity.template("vanity.js")) %></script>
<script type="text/javascript"><%= vanity_html_safe(File.read(Vanity.template("jquery.min.js"))) %></script>
<script type="text/javascript"><%= vanity_html_safe(File.read(Vanity.template("flot.min.js"))) %></script>
<script type="text/javascript"><%= vanity_html_safe(File.read(Vanity.template("vanity.js"))) %></script>
<% if respond_to?(:form_authenticity_token) %><script type="text/javascript">document.auth_token = "<%= form_authenticity_token %>"</script><% end %>
</head>
<body>
Expand Down

0 comments on commit bb46e65

Please sign in to comment.