Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
jeroeningen committed Aug 11, 2012
2 parents d49f4a7 + a513cc1 commit e1e5f06
Show file tree
Hide file tree
Showing 41 changed files with 715 additions and 239 deletions.
16 changes: 16 additions & 0 deletions actionmailer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@

* Asynchronously send messages via the Rails Queue *Brian Cardarella*


## Rails 3.2.8 (Aug 9, 2012) ##

* No changes.


## Rails 3.2.7 (Jul 26, 2012) ##

* No changes.


## Rails 3.2.6 (Jun 12, 2012) ##

* No changes.


## Rails 3.2.5 (Jun 1, 2012) ##

* No changes.
Expand Down
126 changes: 96 additions & 30 deletions actionpack/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## Rails 4.0.0 (unreleased) ##

* Raises an ArgumentError when the first argument in `form_for` contain `nil`
or is empty.

*Richard Schneeman*

* Add 'X-Frame-Options' => 'SAMEORIGIN' and
'X-XSS-Protection' => '1; mode=block'
as default headers.
Expand All @@ -12,19 +17,19 @@

We recommend the use of Unobtrusive JavaScript instead. For example:

link_to "Greeting", "#", :class => "nav_link"
link_to "Greeting", "#", :class => "nav_link"

$(function() {
$('.nav_link').click(function() {
// Some complex code
$(function() {
$('.nav_link').click(function() {
// Some complex code

return false;
return false;
});
});
});

or

link_to "Greeting", '#', onclick: "alert('Hello world!'); return false", class: "nav_link"
link_to "Greeting", '#', onclick: "alert('Hello world!'); return false", class: "nav_link"

for simple cases.

Expand All @@ -41,18 +46,18 @@
* Added ActionController::Live. Mix it in to your controller and you can
stream data to the client live. For example:

class FooController < ActionController::Base
include ActionController::Live
class FooController < ActionController::Base
include ActionController::Live

def index
100.times {
# Client will see this as it's written
response.stream.write "hello world\n"
sleep 1
}
response.stream.close
def index
100.times {
# Client will see this as it's written
response.stream.write "hello world\n"
sleep 1
}
response.stream.close
end
end
end

* Remove ActionDispatch::Head middleware in favor of Rack::Head. *Santiago Pastorino*

Expand Down Expand Up @@ -261,13 +266,13 @@
* Add `collection_check_boxes` form helper, similar to `collection_select`:
Example:

collection_check_boxes :post, :author_ids, Author.all, :id, :name
# Outputs something like:
<input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" />
<label for="post_author_ids_1">D. Heinemeier Hansson</label>
<input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
<label for="post_author_ids_2">D. Thomas</label>
<input name="post[author_ids][]" type="hidden" value="" />
collection_check_boxes :post, :author_ids, Author.all, :id, :name
# Outputs something like:
<input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" />
<label for="post_author_ids_1">D. Heinemeier Hansson</label>
<input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
<label for="post_author_ids_2">D. Thomas</label>
<input name="post[author_ids][]" type="hidden" value="" />

The label/check_box pairs can be customized with a block.

Expand All @@ -276,12 +281,12 @@
* Add `collection_radio_buttons` form helper, similar to `collection_select`:
Example:

collection_radio_buttons :post, :author_id, Author.all, :id, :name
# Outputs something like:
<input id="post_author_id_1" name="post[author_id]" type="radio" value="1" />
<label for="post_author_id_1">D. Heinemeier Hansson</label>
<input id="post_author_id_2" name="post[author_id]" type="radio" value="2" />
<label for="post_author_id_2">D. Thomas</label>
collection_radio_buttons :post, :author_id, Author.all, :id, :name
# Outputs something like:
<input id="post_author_id_1" name="post[author_id]" type="radio" value="1" />
<label for="post_author_id_1">D. Heinemeier Hansson</label>
<input id="post_author_id_2" name="post[author_id]" type="radio" value="2" />
<label for="post_author_id_2">D. Thomas</label>

The label/radio_button pairs can be customized with a block.

Expand Down Expand Up @@ -325,6 +330,67 @@
HTML5 `mark` element. *Brian Cardarella*


## Rails 3.2.8 (Aug 9, 2012) ##

* There is an XSS vulnerability in the strip_tags helper in Ruby on Rails, the
helper doesn't correctly handle malformed html. As a result an attacker can
execute arbitrary javascript through the use of specially crafted malformed
html.

*Marek from Nethemba (www.nethemba.com) & Santiago Pastorino*

* When a "prompt" value is supplied to the `select_tag` helper, the "prompt" value is not escaped.
If untrusted data is not escaped, and is supplied as the prompt value, there is a potential for XSS attacks.
Vulnerable code will look something like this:
select_tag("name", options, :prompt => UNTRUSTED_INPUT)

*Santiago Pastorino*

* Reverted the deprecation of `:confirm`. *Rafael Mendonça França*

* Reverted the deprecation of `:disable_with`. *Rafael Mendonça França*

* Reverted the deprecation of `:mouseover` option to `image_tag`. *Rafael Mendonça França*

* Reverted the deprecation of `button_to_function` and `link_to_function` helpers.

*Rafael Mendonça França*


## Rails 3.2.7 (Jul 26, 2012) ##

* Do not convert digest auth strings to symbols. CVE-2012-3424

* Bump Journey requirements to 1.0.4

* Add support for optional root segments containing slashes

* Fixed bug creating invalid HTML in select options

* Show in log correct wrapped keys

* Fix NumberHelper options wrapping to prevent verbatim blocks being rendered instead of line continuations.

* ActionController::Metal doesn't have logger method, check it and then delegate

* ActionController::Caching depends on RackDelegation and AbstractController::Callbacks


## Rails 3.2.6 (Jun 12, 2012) ##

* nil is removed from array parameter values

CVE-2012-2694

* Deprecate `:confirm` in favor of `':data => { :confirm => "Text" }'` option for `button_to`, `button_tag`, `image_submit_tag`, `link_to` and `submit_tag` helpers.

*Carlos Galdino*

* Allow to use mounted_helpers (helpers for accessing mounted engines) in ActionView::TestCase. *Piotr Sarnacki*

* Include mounted_helpers (helpers for accessing mounted engines) in ActionDispatch::IntegrationTest by default. *Piotr Sarnacki*


## Rails 3.2.5 (Jun 1, 2012) ##

* No changes.
Expand Down
10 changes: 8 additions & 2 deletions actionpack/lib/action_controller/metal/url_for.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,15 @@ def url_options
:_recall => request.symbolized_path_parameters
).freeze

if _routes.equal?(env["action_dispatch.routes"])
if (same_origin = _routes.equal?(env["action_dispatch.routes"])) ||
(script_name = env["ROUTES_#{_routes.object_id}_SCRIPT_NAME"]) ||
(original_script_name = env['SCRIPT_NAME'])
@_url_options.dup.tap do |options|
options[:script_name] = request.script_name.dup
if original_script_name
options[:original_script_name] = original_script_name
else
options[:script_name] = same_origin ? request.script_name.dup : script_name
end
options.freeze
end
else
Expand Down
5 changes: 5 additions & 0 deletions actionpack/lib/action_dispatch/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ class Railtie < Rails::Railtie
:verbose => false
}

config.action_dispatch.default_headers = {
'X-Frame-Options' => 'SAMEORIGIN',
'X-XSS-Protection' => '1; mode=block'
}

initializer "action_dispatch.configure" do |app|
ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
ActionDispatch::Request.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
Expand Down
25 changes: 15 additions & 10 deletions actionpack/lib/action_dispatch/routing/route_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ def length
private

def define_named_route_methods(name, route)
define_url_helper route, :"#{name}_path",
define_url_helper route, :"#{name}_path",
route.defaults.merge(:use_route => name, :only_path => true)
define_url_helper route, :"#{name}_url",
define_url_helper route, :"#{name}_url",
route.defaults.merge(:use_route => name, :only_path => false)
end

Expand Down Expand Up @@ -409,21 +409,19 @@ def build_path(path, requirements, separators, anchor)
def build_conditions(current_conditions, path_values)
conditions = current_conditions.dup

verbs = conditions[:request_method] || []

# Rack-Mount requires that :request_method be a regular expression.
# :request_method represents the HTTP verb that matches this route.
#
# Here we munge values before they get sent on to rack-mount.
verbs = conditions[:request_method] || []
unless verbs.empty?
conditions[:request_method] = %r[^#{verbs.join('|')}$]
end
conditions.keep_if do |k,v|

conditions.keep_if do |k, _|
k == :action || k == :controller ||
@request_class.public_method_defined?(k) || path_values.include?(k)
end

conditions
end
private :build_conditions

Expand Down Expand Up @@ -465,7 +463,7 @@ def current_controller
def use_recall_for(key)
if @recall[key] && (!@options.key?(key) || @options[key] == @recall[key])
if !named_route_exists? || segment_keys.include?(key)
@options[key] = @recall.delete(key)
@options[key] = @recall.delete(key)
end
end
end
Expand Down Expand Up @@ -574,7 +572,8 @@ def generate(options, recall = {}, extras = false)
end

RESERVED_OPTIONS = [:host, :protocol, :port, :subdomain, :domain, :tld_length,
:trailing_slash, :anchor, :params, :only_path, :script_name]
:trailing_slash, :anchor, :params, :only_path, :script_name,
:original_script_name]

def mounted?
false
Expand All @@ -594,7 +593,13 @@ def url_for(options)

user, password = extract_authentication(options)
recall = options.delete(:_recall)
script_name = options.delete(:script_name).presence || _generate_prefix(options)

original_script_name = options.delete(:original_script_name).presence
script_name = options.delete(:script_name).presence || _generate_prefix(options)

if script_name && original_script_name
script_name = original_script_name + script_name
end

path_options = options.except(*RESERVED_OPTIONS)
path_options = yield(path_options) if block_given?
Expand Down
1 change: 1 addition & 0 deletions actionpack/lib/action_view/helpers/form_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ def form_for(record, options = {}, &proc)
object = nil
else
object = record.is_a?(Array) ? record.last : record
raise ArgumentError, "First argument in form cannot contain nil or be empty" if object.blank?
object_name = options[:as] || model_name_from_record_or_class(object).param_key
apply_form_for_options!(record, object, options)
end
Expand Down
8 changes: 5 additions & 3 deletions actionpack/lib/action_view/helpers/form_options_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -708,9 +708,11 @@ def collection_check_boxes(object, method, collection, value_method, text_method

private
def option_html_attributes(element)
return {} unless Array === element

Hash[element.select { |e| Hash === e }.reduce({}, :merge).map { |k, v| [k, v] }]
if Array === element
element.select { |e| Hash === e }.reduce({}, :merge!)
else
{}
end
end

def option_text_and_value(option)
Expand Down
18 changes: 0 additions & 18 deletions actionpack/test/dispatch/prefix_generation_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -166,18 +166,6 @@ def setup
assert_equal "/generate", last_response.body
end

test "[ENGINE] generating application's url includes default_url_options[:script_name]" do
RailsApplication.routes.default_url_options = {:script_name => "/something"}
get "/pure-awesomeness/blog/url_to_application"
assert_equal "/something/generate", last_response.body
end

test "[ENGINE] generating application's url should give higher priority to default_url_options[:script_name]" do
RailsApplication.routes.default_url_options = {:script_name => "/something"}
get "/pure-awesomeness/blog/url_to_application", {}, 'SCRIPT_NAME' => '/foo'
assert_equal "/something/generate", last_response.body
end

test "[ENGINE] generating engine's url with polymorphic path" do
get "/pure-awesomeness/blog/polymorphic_path_for_engine"
assert_equal "/pure-awesomeness/blog/posts/1", last_response.body
Expand All @@ -200,12 +188,6 @@ def setup
assert_equal "/something/awesome/blog/posts/1", last_response.body
end

test "[APP] generating engine's route should give higher priority to default_url_options[:script_name]" do
RailsApplication.routes.default_url_options = {:script_name => "/something"}
get "/generate", {}, 'SCRIPT_NAME' => "/foo"
assert_equal "/something/awesome/blog/posts/1", last_response.body
end

test "[APP] generating engine's url with polymorphic path" do
get "/polymorphic_path_for_engine"
assert_equal "/awesome/blog/posts/1", last_response.body
Expand Down
14 changes: 14 additions & 0 deletions actionpack/test/template/form_helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1045,6 +1045,20 @@ def test_form_for_requires_block
end
end

def test_form_for_requires_arguments
error = assert_raises(ArgumentError) do
form_for(nil, :html => { :id => 'create-post' }) do
end
end
assert_equal "First argument in form cannot contain nil or be empty", error.message

error = assert_raises(ArgumentError) do
form_for([nil, nil], :html => { :id => 'create-post' }) do
end
end
assert_equal "First argument in form cannot contain nil or be empty", error.message
end

def test_form_for
form_for(@post, :html => { :id => 'create-post' }) do |f|
concat f.label(:title) { "The Title" }
Expand Down
Loading

0 comments on commit e1e5f06

Please sign in to comment.