Rails 2.1.1

Among other things, a security fix.
This commit is contained in:
Jacques Distler 2008-09-07 00:54:05 -05:00
parent d2c4c8737c
commit d4f97345db
354 changed files with 21027 additions and 3072 deletions

View file

@ -178,10 +178,13 @@ module ActionView #:nodoc:
# that alert()s the caught exception (and then re-raises it).
@@debug_rjs = false
cattr_accessor :debug_rjs
@@erb_variable = '_erbout'
cattr_accessor :erb_variable
class << self
deprecate :erb_variable= => 'The erb variable will no longer be configurable. Use the concat helper method instead of appending to it directly.'
end
attr_internal :request
delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers,
@ -253,6 +256,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
elsif options == :update
update_page(&block)
elsif options.is_a?(Hash)
use_full_path = options[:use_full_path]
options = options.reverse_merge(:locals => {}, :use_full_path => true)
if partial_layout = options.delete(:layout)
@ -266,7 +270,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
end
end
elsif options[:file]
render_file(options[:file], options[:use_full_path], options[:locals])
render_file(options[:file], use_full_path || false, options[:locals])
elsif options[:partial] && options[:collection]
render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals])
elsif options[:partial]

View file

@ -485,21 +485,24 @@ module ActionView
source = "#{@controller.request.relative_url_root}#{source}"
end
end
source = rewrite_asset_path(source)
if include_host
host = compute_asset_host(source)
if has_request && !host.blank? && host !~ %r{^[-a-z]+://}
host = "#{@controller.request.protocol}#{host}"
end
"#{host}#{source}"
else
source
end
rewrite_asset_path(source)
end
end
source = ActionView::Base.computed_public_paths[cache_key]
if include_host && source !~ %r{^[-a-z]+://}
host = compute_asset_host(source)
if has_request && !host.blank? && host !~ %r{^[-a-z]+://}
host = "#{@controller.request.protocol}#{host}"
end
"#{host}#{source}"
else
source
end
end
# Pick an asset host for this source. Returns +nil+ if no host is set,

View file

@ -696,15 +696,15 @@ module ActionView
class FormBuilder
def date_select(method, options = {}, html_options = {})
@template.date_select(@object_name, method, options.merge(:object => @object))
@template.date_select(@object_name, method, options.merge(:object => @object), html_options)
end
def time_select(method, options = {}, html_options = {})
@template.time_select(@object_name, method, options.merge(:object => @object))
@template.time_select(@object_name, method, options.merge(:object => @object), html_options)
end
def datetime_select(method, options = {}, html_options = {})
@template.datetime_select(@object_name, method, options.merge(:object => @object))
@template.datetime_select(@object_name, method, options.merge(:object => @object), html_options)
end
end
end

View file

@ -601,7 +601,11 @@ module ActionView
end
def object
@object || (@template_object.instance_variable_get("@#{@object_name}") rescue nil)
@object || @template_object.instance_variable_get("@#{@object_name}")
rescue NameError
# As @object_name may contain the nested syntax (item[subobject]) we
# need to fallback to nil.
nil
end
def value(object)

View file

@ -304,7 +304,7 @@ module ActionView
#
# NOTE: Only the option tags are returned, you have to wrap this call in
# a regular HTML select tag.
def time_zone_options_for_select(selected = nil, priority_zones = nil, model = TimeZone)
def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone)
zone_options = ""
zones = model.all
@ -417,7 +417,7 @@ module ActionView
value = value(object)
content_tag("select",
add_options(
time_zone_options_for_select(value || options[:default], priority_zones, options[:model] || TimeZone),
time_zone_options_for_select(value || options[:default], priority_zones, options[:model] || ActiveSupport::TimeZone),
options, value
), html_options
)

View file

@ -129,7 +129,7 @@ module ActionView
# label_tag 'name', nil, :class => 'small_label'
# # => <label for="name" class="small_label">Name</label>
def label_tag(name, text = nil, options = {})
content_tag :label, text || name.humanize, { "for" => name }.update(options.stringify_keys)
content_tag :label, text || name.to_s.humanize, { "for" => name }.update(options.stringify_keys)
end
# Creates a hidden form input field used to transmit data that would be lost due to HTTP's statelessness or
@ -348,11 +348,13 @@ module ActionView
options.stringify_keys!
if disable_with = options.delete("disable_with")
disable_with = "this.value='#{disable_with}'"
disable_with << ";#{options.delete('onclick')}" if options['onclick']
options["onclick"] = [
"this.setAttribute('originalValue', this.value)",
"this.disabled=true",
"this.value='#{disable_with}'",
"#{options["onclick"]}",
disable_with,
"result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit())",
"if (result == false) { this.value = this.getAttribute('originalValue'); this.disabled = false }",
"return result;",

View file

@ -80,10 +80,9 @@ module ActionView
# return false;">Show me more</a>
#
def link_to_function(name, *args, &block)
html_options = args.extract_options!
html_options = args.extract_options!.symbolize_keys
function = args[0] || ''
html_options.symbolize_keys!
function = update_page(&block) if block_given?
content_tag(
"a", name,
@ -111,10 +110,9 @@ module ActionView
# page[:details].visual_effect :toggle_slide
# end
def button_to_function(name, *args, &block)
html_options = args.extract_options!
html_options = args.extract_options!.symbolize_keys
function = args[0] || ''
html_options.symbolize_keys!
function = update_page(&block) if block_given?
tag(:input, html_options.merge({
:type => "button", :value => name,
@ -147,6 +145,8 @@ module ActionView
javascript << '</script>'
end
deprecate :define_javascript_functions=>"use javascript_include_tag instead"
# Escape carrier returns and single and double quotes for JavaScript segments.
def escape_javascript(javascript)
(javascript || '').gsub('\\','\0\0').gsub('</','<\/').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }

View file

@ -111,7 +111,7 @@ module ActionView
(100..599).to_a)
AJAX_OPTIONS = Set.new([ :before, :after, :condition, :url,
:asynchronous, :method, :insertion, :position,
:form, :with, :update, :script ]).merge(CALLBACKS)
:form, :with, :update, :script, :type ]).merge(CALLBACKS)
end
# Returns a link to a remote action defined by <tt>options[:url]</tt>
@ -603,7 +603,7 @@ module ActionView
# Example:
#
# # Generates:
# # new Insertion.Bottom("list", "<li>Some item</li>");
# # new Element.insert("list", { bottom: <li>Some item</li>" });
# # new Effect.Highlight("list");
# # ["status-indicator", "cancel-link"].each(Element.hide);
# update_page do |page|
@ -736,16 +736,16 @@ module ActionView
#
# # Insert the rendered 'navigation' partial just before the DOM
# # element with ID 'content'.
# # Generates: new Insertion.Before("content", "-- Contents of 'navigation' partial --");
# # Generates: Element.insert("content", { before: "-- Contents of 'navigation' partial --" });
# page.insert_html :before, 'content', :partial => 'navigation'
#
# # Add a list item to the bottom of the <ul> with ID 'list'.
# # Generates: new Insertion.Bottom("list", "<li>Last item</li>");
# # Generates: Element.insert("list", { bottom: "<li>Last item</li>" });
# page.insert_html :bottom, 'list', '<li>Last item</li>'
#
def insert_html(position, id, *options_for_render)
insertion = position.to_s.camelize
call "new Insertion.#{insertion}", id, render(*options_for_render)
content = javascript_object_for(render(*options_for_render))
record "Element.insert(\"#{id}\", { #{position.to_s.downcase}: #{content} });"
end
# Replaces the inner HTML of the DOM element with the given +id+.
@ -1039,7 +1039,7 @@ module ActionView
js_options['asynchronous'] = options[:type] != :synchronous
js_options['method'] = method_option_to_s(options[:method]) if options[:method]
js_options['insertion'] = "Insertion.#{options[:position].to_s.camelize}" if options[:position]
js_options['insertion'] = "'#{options[:position].to_s.downcase}'" if options[:position]
js_options['evalScripts'] = options[:script].nil? || options[:script]
if options[:form]

View file

@ -1,5 +1,6 @@
require 'cgi'
require 'erb'
require 'set'
module ActionView
module Helpers #:nodoc:
@ -8,7 +9,8 @@ module ActionView
module TagHelper
include ERB::Util
BOOLEAN_ATTRIBUTES = Set.new(%w(disabled readonly multiple))
BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple).to_set
BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map(&:to_sym))
# Returns an empty HTML tag of type +name+ which by default is XHTML
# compliant. Set +open+ to true to create an open tag compatible
@ -37,7 +39,7 @@ module ActionView
# tag("img", { :src => "open &amp; shut.png" }, false, false)
# # => <img src="open &amp; shut.png" />
def tag(name, options = nil, open = false, escape = true)
"<#{name}#{tag_options(options, escape) if options}" + (open ? ">" : " />")
"<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}"
end
# Returns an HTML block tag of type +name+ surrounding the +content+. Add
@ -114,7 +116,6 @@ module ActionView
if escape
options.each do |key, value|
next unless value
key = key.to_s
value = BOOLEAN_ATTRIBUTES.include?(key) ? key : escape_once(value)
attrs << %(#{key}="#{value}")
end

View file

@ -464,7 +464,7 @@ module ActionView
[-\w]+ # subdomain or domain
(?:\.[-\w]+)* # remaining subdomains or domain
(?::\d+)? # port
(?:/(?:(?:[~\w\+@%=\(\)-]|(?:[,.;:][^\s$]))+)?)* # path
(?:/(?:(?:[~\w\+@%=\(\)-]|(?:[,.;:'][^\s$]))+)?)* # path
(?:\?[\w\+@%&=.;-]+)? # query string
(?:\#[\w\-]*)? # trailing anchor
)

View file

@ -63,17 +63,15 @@ module ActionView
# # calls @workshop.to_s
# # => /workshops/5
def url_for(options = {})
options ||= {}
case options
when Hash
show_path = options[:host].nil? ? true : false
options = { :only_path => show_path }.update(options.symbolize_keys)
options = { :only_path => options[:host].nil? }.update(options.symbolize_keys)
escape = options.key?(:escape) ? options.delete(:escape) : true
url = @controller.send(:url_for, options)
when String
escape = true
url = options
when NilClass
url = @controller.send(:url_for, nil)
else
escape = false
url = polymorphic_path(options)
@ -444,7 +442,7 @@ module ActionView
email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.has_key?("replace_dot")
if encode == "javascript"
"document.write('#{content_tag("a", name || email_address, html_options.merge({ "href" => "mailto:"+email_address+extras }))}');".each_byte do |c|
"document.write('#{content_tag("a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:"+email_address+extras }))}');".each_byte do |c|
string << sprintf("%%%x", c)
end
"<script type=\"#{Mime::JS}\">eval(unescape('#{string}'))</script>"

View file

@ -22,10 +22,10 @@ module ActionView #:nodoc:
end
def render_member(object)
@locals[@counter_name] += 1
@locals[:object] = @locals[@variable_name] = object
template = render_template
@locals[@counter_name] += 1
@locals.delete(@variable_name)
@locals.delete(:object)