Skip to content

Commit

Permalink
basic contextual autoescape wrapper for eruby + jruby
Browse files Browse the repository at this point in the history
  • Loading branch information
igrigorik committed Oct 22, 2011
1 parent 6b1f371 commit 146da88
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 6 deletions.
Empty file added .rspec
Empty file.
10 changes: 10 additions & 0 deletions Rakefile
Original file line number Original file line Diff line number Diff line change
@@ -1 +1,11 @@
require 'bundler/gem_tasks' require 'bundler/gem_tasks'
require 'rspec/core/rake_task'

task :default => [:spec]
task :test => [:spec]

desc "run spec tests"
RSpec::Core::RakeTask.new('spec') do |t|
t.pattern = 'spec/**_spec.rb'
end

9 changes: 6 additions & 3 deletions contextual.gemspec
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ Gem::Specification.new do |s|
s.version = Contextual::VERSION s.version = Contextual::VERSION
s.authors = ["Ilya Grigorik"] s.authors = ["Ilya Grigorik"]
s.email = ["ilya@igvita.com"] s.email = ["ilya@igvita.com"]
s.homepage = "" s.homepage = "https://github.com/igrigorik/contextual"
s.summary = %q{TODO: Write a gem summary} s.summary = "Runtime contextual autoescaper"
s.description = %q{TODO: Write a gem description} s.description = s.summary


s.rubyforge_project = "contextual" s.rubyforge_project = "contextual"
s.platform = "java"

s.add_development_dependency "rspec"


s.files = `git ls-files`.split("\n") s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
Expand Down
Binary file added ext/autoesc.jar
Binary file not shown.
Binary file added ext/guava.jar
Binary file not shown.
4 changes: 1 addition & 3 deletions lib/contextual.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,3 @@
require "contextual/version" require "contextual/version"
require "contextual/contextual"


module Contextual
# Your code goes here...
end
82 changes: 82 additions & 0 deletions lib/contextual/contextual.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,82 @@
require "java"
require "ext/guava"
require "ext/autoesc"

java_import com.google.autoesc.HTMLEscapingWriter

require "rubygems"
require "erubis"

module Erubis
module ContextualEscapeEnhancer

def self.desc # :nodoc:
"switch '<%= %>' to escaped and '<%== %>' to unescaped"
end

def add_expr(src, code, indicator)
case indicator
when '='
@escape ? add_expr_literal(src, code) : add_expr_escaped(src, code)
when '=='
@escape ? add_expr_escaped(src, code) : add_expr_literal(src, code)
when '==='
add_expr_debug(src, code)
end
end

def add_text(src, text)
src << " #{@bufvar}.writeSafe '" << text << "';" unless text.empty?
end

def add_stmt(src, code)
src << code
src << ';' unless code[-1] == ?\n
end

def add_expr_literal(src, code)
src << " #{@bufvar}.writeSafe(" << code << ').to_s;'
end

def add_expr_escaped(src, code)
src << " #{@bufvar}.write((" << code << ').to_s);'
end
end

class ContextualBuffer
def initialize
@writer = java.io.StringWriter.new
@buf = HTMLEscapingWriter.new(@writer)
end

def writeSafe(code)
@buf.writeSafe(code)
end

def write(code)
@buf.write(code)
end

def to_s
@writer.to_s
end

def close
@writer.close
end
end

class ContextualEruby < Eruby
include ContextualEscapeEnhancer

def add_preamble(src)
src << "#{@bufvar} = Erubis::ContextualBuffer.new; "
end

def add_postamble(src)
src << "\n" unless src[-1] == ?\n
src << "#{@bufvar}.close\n"
src << "#{@bufvar}.to_s\n"
end
end
end
35 changes: 35 additions & 0 deletions spec/contextual_spec.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,35 @@
require "contextual"

describe Contextual do

it "should escape unsafe content" do
t = Erubis::ContextualEruby.new(" \
<% elements.each do |e| %> \
<%= e %> \
<% end %> \
")

elements = ['<script>', '&bar', 'style="test"']
res = t.result(binding())

res.should match('&lt;script&gt;')
res.should match('&amp;bar')
res.should match('style=&#34;test&#34;')
end

it "should preserve safe content" do
t = Erubis::ContextualEruby.new("<ul><%= '<script>' %></ul>")
t.result.should match('<ul>&lt;script&gt;</ul>')
end

it "should allow explicit safe content" do
t = Erubis::ContextualEruby.new("<ul><%== '<script>' %></ul>")
t.result.should match('<ul><script></ul>')
end

it "should skip comments" do
t = Erubis::ContextualEruby.new("<%# some comment %>")
t.result.should be_empty
end

end

0 comments on commit 146da88

Please sign in to comment.