erector 0.8.2 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +0 -4
- data/VERSION.yml +1 -1
- data/lib/erector.rb +2 -4
- data/lib/erector/abstract_widget.rb +2 -1
- data/lib/erector/erect/erect.rb +17 -14
- data/lib/erector/erect/rhtml.treetop +18 -10
- data/lib/erector/externals.rb +7 -1
- data/lib/erector/html.rb +30 -39
- data/lib/erector/rails.rb +6 -26
- data/lib/erector/rails/form_builder.rb +36 -0
- data/lib/erector/rails/railtie.rb +11 -0
- data/lib/erector/rails/template_handler.rb +16 -0
- data/lib/erector/rails/widget_renderer.rb +6 -0
- data/lib/erector/rails2.rb +27 -0
- data/lib/erector/{rails → rails2}/extensions/action_controller.rb +1 -1
- data/lib/erector/{rails → rails2}/extensions/rails_helpers.rb +17 -4
- data/lib/erector/{rails → rails2}/extensions/rails_widget.rb +6 -3
- data/lib/erector/{rails → rails2}/rails_form_builder.rb +0 -0
- data/lib/erector/rails2/rails_version.rb +6 -0
- data/lib/erector/{rails → rails2}/template_handlers/ert_handler.rb +0 -0
- data/lib/erector/{rails → rails2}/template_handlers/rb_handler.rb +2 -2
- data/lib/erector/rails3.rb +208 -0
- data/lib/erector/raw_string.rb +4 -0
- data/lib/erector/widgets/external_renderer.rb +8 -0
- data/spec/erect/erect_rails_spec.rb +34 -49
- data/spec/erect/erected_spec.rb +11 -0
- data/spec/rails2/erect_rails_spec.rb +114 -0
- data/spec/rails2/rails_app/Gemfile +12 -0
- data/spec/rails2/rails_app/Gemfile.lock +89 -0
- data/spec/rails2/rails_app/README +243 -0
- data/spec/rails2/rails_app/Rakefile +19 -0
- data/spec/rails2/rails_app/app/controllers/application_controller.rb +10 -0
- data/spec/rails2/rails_app/app/helpers/application_helper.rb +3 -0
- data/spec/rails2/rails_app/app/views/test/_erb.erb +1 -0
- data/spec/rails2/rails_app/app/views/test/_erector.rb +5 -0
- data/spec/rails2/rails_app/app/views/test/_partial_with_locals.rb +7 -0
- data/spec/rails2/rails_app/app/views/test/bare.rb +5 -0
- data/spec/rails2/rails_app/app/views/test/erb_from_erector.html.rb +5 -0
- data/spec/rails2/rails_app/app/views/test/erector_from_erb.html.erb +1 -0
- data/spec/rails2/rails_app/app/views/test/erector_with_locals_from_erb.html.erb +6 -0
- data/spec/rails2/rails_app/app/views/test/implicit_assigns.html.rb +5 -0
- data/spec/rails2/rails_app/app/views/test/needs.html.rb +7 -0
- data/spec/rails2/rails_app/app/views/test/needs_subclass.html.rb +5 -0
- data/spec/rails2/rails_app/app/views/test/protected_instance_variable.html.rb +5 -0
- data/spec/rails2/rails_app/app/views/test/render_default.html.rb +5 -0
- data/spec/rails2/rails_app/app/views/test/render_partial.html.rb +5 -0
- data/spec/rails2/rails_app/config/boot.rb +114 -0
- data/spec/rails2/rails_app/config/database.yml +16 -0
- data/spec/rails2/rails_app/config/environment.rb +42 -0
- data/spec/rails2/rails_app/config/environments/development.rb +17 -0
- data/spec/rails2/rails_app/config/environments/production.rb +28 -0
- data/spec/rails2/rails_app/config/environments/test.rb +28 -0
- data/spec/rails2/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails2/rails_app/config/initializers/cookie_verification_secret.rb +7 -0
- data/spec/rails2/rails_app/config/initializers/inflections.rb +10 -0
- data/spec/rails2/rails_app/config/initializers/mime_types.rb +5 -0
- data/spec/rails2/rails_app/config/initializers/new_rails_defaults.rb +21 -0
- data/spec/rails2/rails_app/config/initializers/session_store.rb +15 -0
- data/spec/rails2/rails_app/config/locales/en.yml +5 -0
- data/spec/rails2/rails_app/config/routes.rb +43 -0
- data/spec/rails2/rails_app/db/development.sqlite3 +0 -0
- data/spec/rails2/rails_app/db/schema.rb +14 -0
- data/spec/rails2/rails_app/db/seeds.rb +7 -0
- data/spec/rails2/rails_app/doc/README_FOR_APP +2 -0
- data/spec/rails2/rails_app/log/development.log +76 -0
- data/spec/rails2/rails_app/log/production.log +0 -0
- data/spec/rails2/rails_app/log/server.log +0 -0
- data/spec/rails2/rails_app/log/test.log +4158 -0
- data/spec/rails2/rails_app/public/404.html +30 -0
- data/spec/rails2/rails_app/public/422.html +30 -0
- data/spec/rails2/rails_app/public/500.html +30 -0
- data/spec/rails2/rails_app/public/favicon.ico +0 -0
- data/spec/rails2/rails_app/public/images/rails.png +0 -0
- data/spec/rails2/rails_app/public/index.html +275 -0
- data/spec/rails2/rails_app/public/javascripts/application.js +2 -0
- data/spec/rails2/rails_app/public/javascripts/controls.js +963 -0
- data/spec/rails2/rails_app/public/javascripts/dragdrop.js +973 -0
- data/spec/rails2/rails_app/public/javascripts/effects.js +1128 -0
- data/spec/rails2/rails_app/public/javascripts/prototype.js +4320 -0
- data/spec/rails2/rails_app/public/robots.txt +5 -0
- data/spec/rails2/rails_app/script/about +4 -0
- data/spec/rails2/rails_app/script/console +3 -0
- data/spec/rails2/rails_app/script/dbconsole +3 -0
- data/spec/rails2/rails_app/script/destroy +3 -0
- data/spec/rails2/rails_app/script/generate +3 -0
- data/spec/rails2/rails_app/script/performance/benchmarker +3 -0
- data/spec/rails2/rails_app/script/performance/profiler +3 -0
- data/spec/rails2/rails_app/script/plugin +3 -0
- data/spec/rails2/rails_app/script/runner +3 -0
- data/spec/rails2/rails_app/script/server +3 -0
- data/spec/rails2/rails_app/spec/rails_helpers_spec.rb +255 -0
- data/spec/rails2/rails_app/spec/rails_spec_helper.rb +34 -0
- data/spec/rails2/rails_app/spec/rails_widget_spec.rb +83 -0
- data/spec/rails2/rails_app/spec/render_spec.rb +324 -0
- data/spec/rails2/rails_app/test/performance/browsing_test.rb +9 -0
- data/spec/rails2/rails_app/test/test_helper.rb +38 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/MIT-LICENSE +20 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/README.markdown +90 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/Rakefile +23 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/init.rb +7 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/lib/rails_xss.rb +3 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/lib/rails_xss/action_view.rb +87 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/lib/rails_xss/erubis.rb +33 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/lib/rails_xss/string_ext.rb +52 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/lib/tasks/rails_xss_tasks.rake +4 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/active_record_helper_test.rb +74 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/asset_tag_helper_test.rb +49 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/caching_test.rb +43 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/date_helper_test.rb +29 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/deprecated_output_safety_test.rb +112 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/erb_util_test.rb +36 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/form_helper_test.rb +1447 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/form_tag_helper_test.rb +354 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/output_safety_test.rb +115 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/rails_xss_test.rb +23 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/test_helper.rb +5 -0
- data/spec/rails2/rails_app/vendor/plugins/rails_xss/test/text_helper_test.rb +17 -0
- data/spec/spec_helper.rb +2 -6
- metadata +348 -23
- data/lib/erector/errors.rb +0 -12
- data/lib/erector/extensions/hash.rb +0 -21
- data/lib/erector/extensions/object.rb +0 -18
- data/lib/erector/rails/rails_version.rb +0 -6
- data/rails/init.rb +0 -4
@@ -0,0 +1,38 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
|
3
|
+
require 'test_help'
|
4
|
+
|
5
|
+
class ActiveSupport::TestCase
|
6
|
+
# Transactional fixtures accelerate your tests by wrapping each test method
|
7
|
+
# in a transaction that's rolled back on completion. This ensures that the
|
8
|
+
# test database remains unchanged so your fixtures don't have to be reloaded
|
9
|
+
# between every test method. Fewer database queries means faster tests.
|
10
|
+
#
|
11
|
+
# Read Mike Clark's excellent walkthrough at
|
12
|
+
# http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
|
13
|
+
#
|
14
|
+
# Every Active Record database supports transactions except MyISAM tables
|
15
|
+
# in MySQL. Turn off transactional fixtures in this case; however, if you
|
16
|
+
# don't care one way or the other, switching from MyISAM to InnoDB tables
|
17
|
+
# is recommended.
|
18
|
+
#
|
19
|
+
# The only drawback to using transactional fixtures is when you actually
|
20
|
+
# need to test transactions. Since your test is bracketed by a transaction,
|
21
|
+
# any transactions started in your code will be automatically rolled back.
|
22
|
+
self.use_transactional_fixtures = true
|
23
|
+
|
24
|
+
# Instantiated fixtures are slow, but give you @david where otherwise you
|
25
|
+
# would need people(:david). If you don't want to migrate your existing
|
26
|
+
# test cases which use the @david style and don't mind the speed hit (each
|
27
|
+
# instantiated fixtures translates to a database query per test method),
|
28
|
+
# then set this back to true.
|
29
|
+
self.use_instantiated_fixtures = false
|
30
|
+
|
31
|
+
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
|
32
|
+
#
|
33
|
+
# Note: You'll currently still have to declare fixtures explicitly in integration tests
|
34
|
+
# -- they do not yet inherit this setting
|
35
|
+
fixtures :all
|
36
|
+
|
37
|
+
# Add more helper methods to be used by all tests here...
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Koziarski Software Ltd.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,90 @@
|
|
1
|
+
RailsXss
|
2
|
+
========
|
3
|
+
|
4
|
+
This plugin replaces the default ERB template handlers with erubis, and switches the behaviour to escape by default rather than requiring you to escape. This is consistent with the behaviour in Rails 3.0.
|
5
|
+
|
6
|
+
Strings now have a notion of "html safe", which is false by default. Whenever rails copies a string into the response body it checks whether or not the string is safe, safe strings are copied verbatim into the response body, but unsafe strings are escaped first.
|
7
|
+
|
8
|
+
All the XSS-proof helpers like link_to and form_tag now return safe strings, and will continue to work unmodified. If you have your own helpers which return strings you *know* are safe, you will need to explicitly tell rails that they're safe. For an example, take the following helper.
|
9
|
+
|
10
|
+
|
11
|
+
def some_helper
|
12
|
+
(1..5).map do |i|
|
13
|
+
"<li>#{i}</li>"
|
14
|
+
end.join("\n")
|
15
|
+
end
|
16
|
+
|
17
|
+
With this plugin installed, the html will be escaped. So you will need to do one of the following:
|
18
|
+
|
19
|
+
1) Use the raw helper in your template. raw will ensure that your string is copied verbatim into the response body.
|
20
|
+
|
21
|
+
<%= raw some_helper %>
|
22
|
+
|
23
|
+
2) Mark the string as safe in the helper itself:
|
24
|
+
|
25
|
+
def some_helper
|
26
|
+
(1..5).map do |i|
|
27
|
+
"<li>#{i}</li>"
|
28
|
+
end.join("\n").html_safe
|
29
|
+
end
|
30
|
+
|
31
|
+
3) Use the safe_helper meta programming method:
|
32
|
+
|
33
|
+
module ApplicationHelper
|
34
|
+
def some_helper
|
35
|
+
#...
|
36
|
+
end
|
37
|
+
safe_helper :some_helper
|
38
|
+
end
|
39
|
+
|
40
|
+
Example
|
41
|
+
-------
|
42
|
+
|
43
|
+
BEFORE:
|
44
|
+
|
45
|
+
<%= params[:own_me] %> => XSS attack
|
46
|
+
<%=h params[:own_me] %> => No XSS
|
47
|
+
<%= @blog_post.content %> => Displays the HTML
|
48
|
+
|
49
|
+
AFTER:
|
50
|
+
|
51
|
+
<%= params[:own_me] %> => No XSS
|
52
|
+
<%=h params[:own_me] %> => No XSS (same result)
|
53
|
+
<%= @blog_post.content %> => *escapes* the HTML
|
54
|
+
<%= raw @blog_post.content %> => Displays the HTML
|
55
|
+
|
56
|
+
|
57
|
+
Gotchas
|
58
|
+
---
|
59
|
+
|
60
|
+
#### textilize and simple_format do *not* return safe strings
|
61
|
+
|
62
|
+
Both these methods support arbitrary HTML and are *not* safe to embed directly in your document. You'll need to do something like:
|
63
|
+
|
64
|
+
<%= sanitize(textilize(@blog_post.content_textile)) %>
|
65
|
+
|
66
|
+
#### Safe strings aren't magic.
|
67
|
+
|
68
|
+
Once a string has been marked as safe, the only operations which will maintain that HTML safety are String#<<, String#concat and String#+. All other operations are safety ignorant so it's still probably possible to break your app if you're doing something like
|
69
|
+
|
70
|
+
value = something_safe
|
71
|
+
value.gsub!(/a/, params[:own_me])
|
72
|
+
|
73
|
+
Don't do that.
|
74
|
+
|
75
|
+
#### String interpolation won't be safe, even when it 'should' be
|
76
|
+
|
77
|
+
value = "#{something_safe}#{something_else_safe}"
|
78
|
+
value.html_safe? # => false
|
79
|
+
|
80
|
+
This is intended functionality and can't be fixed.
|
81
|
+
|
82
|
+
Getting Started
|
83
|
+
===============
|
84
|
+
|
85
|
+
1. Install rails 2.3.8 or higher, or freeze rails from 2-3-stable.
|
86
|
+
2. Install erubis (gem install erubis)
|
87
|
+
3. Install this plugin (ruby script/plugin install git://github.com/rails/rails_xss.git)
|
88
|
+
4. Report anything that breaks.
|
89
|
+
|
90
|
+
Copyright (c) 2009 Koziarski Software Ltd, released under the MIT license. For full details see MIT-LICENSE included in this distribution.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the rails_xss plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.libs << 'test'
|
12
|
+
t.pattern = 'test/**/*_test.rb'
|
13
|
+
t.verbose = true
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Generate documentation for the rails_xss plugin.'
|
17
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
18
|
+
rdoc.rdoc_dir = 'rdoc'
|
19
|
+
rdoc.title = 'RailsXss'
|
20
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
21
|
+
rdoc.rdoc_files.include('README')
|
22
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module ActionView
|
2
|
+
class Base
|
3
|
+
def self.xss_safe?
|
4
|
+
true
|
5
|
+
end
|
6
|
+
|
7
|
+
module WithSafeOutputBuffer
|
8
|
+
# Rails version of with_output_buffer uses '' as the default buf
|
9
|
+
def with_output_buffer(buf = ActiveSupport::SafeBuffer.new) #:nodoc:
|
10
|
+
super buf
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
include WithSafeOutputBuffer
|
15
|
+
end
|
16
|
+
|
17
|
+
module Helpers
|
18
|
+
module TextHelper
|
19
|
+
def concat(string, unused_binding = nil)
|
20
|
+
if unused_binding
|
21
|
+
ActiveSupport::Deprecation.warn("The binding argument of #concat is no longer needed. Please remove it from your views and helpers.", caller)
|
22
|
+
end
|
23
|
+
|
24
|
+
output_buffer.concat(string)
|
25
|
+
end
|
26
|
+
|
27
|
+
def simple_format_with_escaping(text, html_options = {})
|
28
|
+
simple_format_without_escaping(ERB::Util.h(text), html_options)
|
29
|
+
end
|
30
|
+
alias_method_chain :simple_format, :escaping
|
31
|
+
end
|
32
|
+
|
33
|
+
module TagHelper
|
34
|
+
private
|
35
|
+
def content_tag_string_with_escaping(name, content, options, escape = true)
|
36
|
+
content_tag_string_without_escaping(name, ERB::Util.h(content), options, escape)
|
37
|
+
end
|
38
|
+
alias_method_chain :content_tag_string, :escaping
|
39
|
+
end
|
40
|
+
|
41
|
+
module UrlHelper
|
42
|
+
def link_to(*args, &block)
|
43
|
+
if block_given?
|
44
|
+
options = args.first || {}
|
45
|
+
html_options = args.second
|
46
|
+
concat(link_to(capture(&block), options, html_options))
|
47
|
+
else
|
48
|
+
name = args.first
|
49
|
+
options = args.second || {}
|
50
|
+
html_options = args.third
|
51
|
+
|
52
|
+
url = url_for(options)
|
53
|
+
|
54
|
+
if html_options
|
55
|
+
html_options = html_options.stringify_keys
|
56
|
+
href = html_options['href']
|
57
|
+
convert_options_to_javascript!(html_options, url)
|
58
|
+
tag_options = tag_options(html_options)
|
59
|
+
else
|
60
|
+
tag_options = nil
|
61
|
+
end
|
62
|
+
|
63
|
+
href_attr = "href=\"#{url}\"" unless href
|
64
|
+
"<a #{href_attr}#{tag_options}>#{ERB::Util.h(name || url)}</a>".html_safe
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
module RailsXss
|
72
|
+
module SafeHelpers
|
73
|
+
def safe_helper(*names)
|
74
|
+
names.each do |helper_method_name|
|
75
|
+
aliased_target, punctuation = helper_method_name.to_s.sub(/([?!=])$/, ''), $1
|
76
|
+
module_eval <<-END
|
77
|
+
def #{aliased_target}_with_xss_safety#{punctuation}(*args, &block)
|
78
|
+
raw(#{aliased_target}_without_xss_safety#{punctuation}(*args, &block))
|
79
|
+
end
|
80
|
+
END
|
81
|
+
alias_method_chain helper_method_name, :xss_safety
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
Module.class_eval { include RailsXss::SafeHelpers }
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'erubis/helpers/rails_helper'
|
2
|
+
|
3
|
+
module RailsXss
|
4
|
+
class Erubis < ::Erubis::Eruby
|
5
|
+
def add_preamble(src)
|
6
|
+
src << "@output_buffer = ActiveSupport::SafeBuffer.new;"
|
7
|
+
end
|
8
|
+
|
9
|
+
def add_text(src, text)
|
10
|
+
return if text.empty?
|
11
|
+
src << "@output_buffer.safe_concat('" << escape_text(text) << "');"
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_expr_literal(src, code)
|
15
|
+
if code =~ /\s*raw\s+(.*)/
|
16
|
+
src << "@output_buffer.safe_concat((" << $1 << ").to_s);"
|
17
|
+
else
|
18
|
+
src << '@output_buffer << ((' << code << ').to_s);'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_expr_escaped(src, code)
|
23
|
+
src << '@output_buffer << ' << escaped_expr(code) << ';'
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_postamble(src)
|
27
|
+
src << '@output_buffer.to_s'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Erubis::Helpers::RailsHelper.engine_class = RailsXss::Erubis
|
33
|
+
Erubis::Helpers::RailsHelper.show_src = false
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'active_support/deprecation'
|
2
|
+
|
3
|
+
ActiveSupport::SafeBuffer.class_eval do
|
4
|
+
def concat(value)
|
5
|
+
if value.html_safe?
|
6
|
+
super(value)
|
7
|
+
else
|
8
|
+
super(ERB::Util.h(value))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
alias << concat
|
12
|
+
end
|
13
|
+
|
14
|
+
class String
|
15
|
+
def html_safe?
|
16
|
+
defined?(@_rails_html_safe)
|
17
|
+
end
|
18
|
+
|
19
|
+
def html_safe!
|
20
|
+
ActiveSupport::Deprecation.warn("Use html_safe with your strings instead of html_safe! See http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/ for the full story.", caller)
|
21
|
+
@_rails_html_safe = true
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_with_safety(other)
|
26
|
+
result = add_without_safety(other)
|
27
|
+
if html_safe? && also_html_safe?(other)
|
28
|
+
result.html_safe!
|
29
|
+
else
|
30
|
+
result
|
31
|
+
end
|
32
|
+
end
|
33
|
+
alias_method :add_without_safety, :+
|
34
|
+
alias_method :+, :add_with_safety
|
35
|
+
|
36
|
+
def concat_with_safety(other_or_fixnum)
|
37
|
+
result = concat_without_safety(other_or_fixnum)
|
38
|
+
unless html_safe? && also_html_safe?(other_or_fixnum)
|
39
|
+
remove_instance_variable(:@_rails_html_safe) if defined?(@_rails_html_safe)
|
40
|
+
end
|
41
|
+
result
|
42
|
+
end
|
43
|
+
|
44
|
+
alias_method_chain :concat, :safety
|
45
|
+
undef_method :<<
|
46
|
+
alias_method :<<, :concat_with_safety
|
47
|
+
|
48
|
+
private
|
49
|
+
def also_html_safe?(other)
|
50
|
+
other.respond_to?(:html_safe?) && other.html_safe?
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ActiveRecordHelperTest < ActionView::TestCase
|
4
|
+
silence_warnings do
|
5
|
+
Post = Struct.new("Post", :title, :author_name, :body, :secret, :written_on)
|
6
|
+
Post.class_eval do
|
7
|
+
alias_method :title_before_type_cast, :title unless respond_to?(:title_before_type_cast)
|
8
|
+
alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
|
9
|
+
alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def setup_post
|
14
|
+
@post = Post.new
|
15
|
+
def @post.errors
|
16
|
+
Class.new {
|
17
|
+
def on(field)
|
18
|
+
case field.to_s
|
19
|
+
when "author_name"
|
20
|
+
"can't be empty"
|
21
|
+
when "body"
|
22
|
+
true
|
23
|
+
else
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
def empty?() false end
|
28
|
+
def count() 1 end
|
29
|
+
def full_messages() [ "Author name can't be empty" ] end
|
30
|
+
}.new
|
31
|
+
end
|
32
|
+
|
33
|
+
def @post.new_record?() true end
|
34
|
+
def @post.to_param() nil end
|
35
|
+
|
36
|
+
def @post.column_for_attribute(attr_name)
|
37
|
+
Post.content_columns.select { |column| column.name == attr_name }.first
|
38
|
+
end
|
39
|
+
|
40
|
+
silence_warnings do
|
41
|
+
def Post.content_columns() [ Column.new(:string, "title", "Title"), Column.new(:text, "body", "Body") ] end
|
42
|
+
end
|
43
|
+
|
44
|
+
@post.title = "Hello World"
|
45
|
+
@post.author_name = ""
|
46
|
+
@post.body = "Back to the hill and over it again!"
|
47
|
+
@post.secret = 1
|
48
|
+
@post.written_on = Date.new(2004, 6, 15)
|
49
|
+
end
|
50
|
+
|
51
|
+
def setup
|
52
|
+
setup_post
|
53
|
+
|
54
|
+
@response = ActionController::TestResponse.new
|
55
|
+
|
56
|
+
@controller = Object.new
|
57
|
+
def @controller.url_for(options)
|
58
|
+
options = options.symbolize_keys
|
59
|
+
|
60
|
+
[options[:action], options[:id].to_param].compact.join('/')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_text_field_with_errors_is_safe
|
65
|
+
assert text_field("post", "author_name").html_safe?
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_text_field_with_errors
|
69
|
+
assert_dom_equal(
|
70
|
+
%(<div class="fieldWithErrors"><input id="post_author_name" name="post[author_name]" size="30" type="text" value="" /></div>),
|
71
|
+
text_field("post", "author_name")
|
72
|
+
)
|
73
|
+
end
|
74
|
+
end
|