mirror of
https://github.com/github/rails.git
synced 2026-01-11 23:58:03 -05:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7403667b89 | ||
|
|
1a45ec57bf | ||
|
|
1e6e438f6e | ||
|
|
2b01f832a3 | ||
|
|
1e5fda763e | ||
|
|
7c3d4ec43c | ||
|
|
7343ed7b05 | ||
|
|
2a70c9691d | ||
|
|
a141d9de0d | ||
|
|
74492f43a8 | ||
|
|
c2894170bf | ||
|
|
057aed6e18 | ||
|
|
02fc012b42 | ||
|
|
4fdaf21b28 | ||
|
|
35b871fbcd | ||
|
|
a5697840d6 | ||
|
|
d0e554d231 | ||
|
|
d38b7664cc | ||
|
|
e4cd9caf02 | ||
|
|
89e4514704 | ||
|
|
0a0d975f51 | ||
|
|
62daf4cb6f | ||
|
|
24711e1e29 |
@@ -1 +1 @@
|
||||
2.3.14.github38
|
||||
2.3.14.github43
|
||||
|
||||
@@ -1320,7 +1320,14 @@ module ActionController #:nodoc:
|
||||
render
|
||||
end
|
||||
|
||||
CVE_2014_0310 = Class.new(StandardError)
|
||||
|
||||
def perform_action
|
||||
# CVE-2014-0130 protection
|
||||
if action_name.include? "/"
|
||||
raise CVE_2014_0310
|
||||
end
|
||||
|
||||
if action_methods.include?(action_name)
|
||||
send(action_name)
|
||||
default_render unless performed?
|
||||
|
||||
@@ -87,7 +87,6 @@ module ActionController #:nodoc:
|
||||
log_message << " [#{complete_request_uri rescue "unknown"}]"
|
||||
|
||||
logger.info(log_message)
|
||||
response.headers["X-Runtime"] = "%.0f" % ms
|
||||
else
|
||||
perform_action_without_benchmark
|
||||
end
|
||||
|
||||
@@ -37,7 +37,7 @@ module ActionController
|
||||
# Note that changing digest or secret invalidates all existing sessions!
|
||||
class CookieStore
|
||||
include AbstractStore::SessionUtils
|
||||
|
||||
|
||||
# Cookies can typically store 4096 bytes.
|
||||
MAX = 4096
|
||||
SECRET_MIN_LENGTH = 30 # characters
|
||||
@@ -95,14 +95,21 @@ module ActionController
|
||||
|
||||
def call(env)
|
||||
prepare!(env)
|
||||
|
||||
|
||||
status, headers, body = @app.call(env)
|
||||
|
||||
session_data = env[ENV_SESSION_KEY]
|
||||
options = env[ENV_SESSION_OPTIONS_KEY]
|
||||
request = ActionController::Request.new(env)
|
||||
|
||||
|
||||
if !(options[:secure] && !request.ssl?) && (!session_data.is_a?(AbstractStore::SessionHash) || session_data.loaded? || options[:expire_after])
|
||||
|
||||
# Backport standard Rack::Session::Cookie behavior
|
||||
# Skip writing session if env['rack.session.options'][:skip] is set
|
||||
if options[:skip]
|
||||
return [status, headers, body]
|
||||
end
|
||||
|
||||
session_data.send(:load!) if session_data.is_a?(AbstractStore::SessionHash) && !session_data.loaded?
|
||||
|
||||
persistent_session_id!(session_data)
|
||||
@@ -122,7 +129,7 @@ module ActionController
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
||||
def prepare!(env)
|
||||
env[ENV_SESSION_KEY] = AbstractStore::SessionHash.new(self, env)
|
||||
env[ENV_SESSION_OPTIONS_KEY] = AbstractStore::OptionsHash.new(self, env, @default_options)
|
||||
@@ -133,7 +140,7 @@ module ActionController
|
||||
data = persistent_session_id!(data)
|
||||
[data[:session_id], data]
|
||||
end
|
||||
|
||||
|
||||
def extract_session_id(env)
|
||||
if data = unpacked_cookie_data(env)
|
||||
persistent_session_id!(data) unless data.empty?
|
||||
|
||||
@@ -73,6 +73,8 @@ module ActionView
|
||||
def number_to_currency(number, options = {})
|
||||
options.symbolize_keys!
|
||||
|
||||
options[:format] = ERB::Util.html_escape(options[:format]) if options[:format]
|
||||
|
||||
defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
|
||||
currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :raise => true) rescue {}
|
||||
defaults = defaults.merge(currency)
|
||||
|
||||
@@ -3,6 +3,12 @@ require 'abstract_unit'
|
||||
class NumberHelperTest < ActionView::TestCase
|
||||
tests ActionView::Helpers::NumberHelper
|
||||
|
||||
def test_number_helpers_escape_delimiter_and_separator
|
||||
assert_equal "$1<script></script>01", number_to_currency(1.01, :separator => "<script></script>")
|
||||
assert_equal "$1<script></script>000.00", number_to_currency(1000, :delimiter => "<script></script>")
|
||||
assert_equal "<script>1,000.00$</script>", number_to_currency(1000, :format => "<script>%n%u</script>")
|
||||
end
|
||||
|
||||
def test_number_to_phone
|
||||
assert_equal("555-1234", number_to_phone(5551234))
|
||||
assert_equal("800-555-1212", number_to_phone(8005551212))
|
||||
|
||||
@@ -195,7 +195,9 @@ module ActiveRecord
|
||||
def log_info(sql, name, ms)
|
||||
if @logger && @logger.debug?
|
||||
name = '%s (%.1fms)' % [name || 'SQL', ms]
|
||||
sql.force_encoding 'binary' if sql.respond_to?(:force_encoding)
|
||||
if sql.respond_to?(:force_encoding)
|
||||
sql = sql.dup.force_encoding 'binary'
|
||||
end
|
||||
@logger.debug(format_log_entry(name, sql.squeeze(' ')))
|
||||
end
|
||||
end
|
||||
@@ -212,13 +214,7 @@ module ActiveRecord
|
||||
log_info(sql, name, 0)
|
||||
nil
|
||||
end
|
||||
rescue SystemExit, SignalException, NoMemoryError => e
|
||||
# Don't re-wrap these exceptions. They are probably not being caused by invalid
|
||||
# sql, but rather some external stimulus beyond the responsibilty of this code.
|
||||
# Additionaly, wrapping these exceptions with StatementInvalid would lead to
|
||||
# meaningful loss of data, such as losing SystemExit#status.
|
||||
raise e
|
||||
rescue Exception => e
|
||||
rescue => e
|
||||
# Log message and raise exception.
|
||||
# Set last_verification to 0, so that connection gets verified
|
||||
# upon reentering the request loop
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
require 'active_support/core_ext/kernel/daemonizing'
|
||||
require 'active_support/core_ext/kernel/reporting'
|
||||
require 'active_support/core_ext/kernel/agnostics'
|
||||
require 'active_support/core_ext/kernel/requires'
|
||||
require 'active_support/core_ext/kernel/debugger'
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
class Object
|
||||
# Makes backticks behave (somewhat more) similarly on all platforms.
|
||||
# On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the
|
||||
# spawned shell prints a message to stderr and sets $?. We emulate
|
||||
# Unix on the former but not the latter.
|
||||
def `(command) #:nodoc:
|
||||
super
|
||||
rescue Errno::ENOENT => e
|
||||
STDERR.puts "#$0: #{e}"
|
||||
end
|
||||
end
|
||||
@@ -1,3 +1,6 @@
|
||||
require 'active_support/core_ext/kernel/singleton_class'
|
||||
require 'active_support/core_ext/module/aliasing'
|
||||
|
||||
module ActiveSupport
|
||||
module Memoizable
|
||||
def self.memoized_ivar_for(symbol)
|
||||
@@ -41,10 +44,10 @@ module ActiveSupport
|
||||
end
|
||||
end
|
||||
|
||||
def flush_cache(*syms, &block)
|
||||
def flush_cache(*syms)
|
||||
syms.each do |sym|
|
||||
(methods + private_methods + protected_methods).each do |m|
|
||||
if m.to_s =~ /^_unmemoized_(#{sym})/
|
||||
if m.to_s =~ /^_unmemoized_(#{sym.to_s.gsub(/\?\Z/, '\?')})/
|
||||
ivar = ActiveSupport::Memoizable.memoized_ivar_for($1)
|
||||
instance_variable_get(ivar).clear if instance_variable_defined?(ivar)
|
||||
end
|
||||
@@ -69,7 +72,7 @@ module ActiveSupport
|
||||
if instance_method(:#{symbol}).arity == 0 # if instance_method(:mime_type).arity == 0
|
||||
def #{symbol}(reload = false) # def mime_type(reload = false)
|
||||
if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty? # if reload || !defined?(@_memoized_mime_type) || @_memoized_mime_type.empty?
|
||||
#{memoized_ivar} = [#{original_method}.freeze] # @_memoized_mime_type = [_unmemoized_mime_type.freeze]
|
||||
#{memoized_ivar} = [#{original_method}] # @_memoized_mime_type = [_unmemoized_mime_type]
|
||||
end # end
|
||||
#{memoized_ivar}[0] # @_memoized_mime_type[0]
|
||||
end # end
|
||||
@@ -82,7 +85,7 @@ module ActiveSupport
|
||||
if !reload && #{memoized_ivar}.has_key?(args) # if !reload && @_memoized_mime_type.has_key?(args)
|
||||
#{memoized_ivar}[args] # @_memoized_mime_type[args]
|
||||
elsif #{memoized_ivar} # elsif @_memoized_mime_type
|
||||
#{memoized_ivar}[args] = #{original_method}(*args).freeze # @_memoized_mime_type[args] = _unmemoized_mime_type(*args).freeze
|
||||
#{memoized_ivar}[args] = #{original_method}(*args) # @_memoized_mime_type[args] = _unmemoized_mime_type(*args)
|
||||
end # end
|
||||
else # else
|
||||
#{original_method}(*args) # _unmemoized_mime_type(*args)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
require 'abstract_unit'
|
||||
require 'active_support'
|
||||
require 'test/unit'
|
||||
|
||||
|
||||
@@ -4,12 +4,13 @@ class MemoizableTest < Test::Unit::TestCase
|
||||
class Person
|
||||
extend ActiveSupport::Memoizable
|
||||
|
||||
attr_reader :name_calls, :age_calls, :is_developer_calls
|
||||
attr_reader :name_calls, :age_calls, :is_developer_calls, :name_query_calls
|
||||
|
||||
def initialize
|
||||
@name_calls = 0
|
||||
@age_calls = 0
|
||||
@is_developer_calls = 0
|
||||
@name_query_calls = 0
|
||||
end
|
||||
|
||||
def name
|
||||
@@ -18,6 +19,7 @@ class MemoizableTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def name?
|
||||
@name_query_calls += 1
|
||||
true
|
||||
end
|
||||
memoize :name?
|
||||
@@ -123,6 +125,13 @@ class MemoizableTest < Test::Unit::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
def test_memoization_flush_with_punctuation
|
||||
assert_equal true, @person.name?
|
||||
@person.flush_cache(:name?)
|
||||
3.times { assert_equal true, @person.name? }
|
||||
assert_equal 2, @person.name_query_calls
|
||||
end
|
||||
|
||||
def test_memoization_with_nil_value
|
||||
assert_equal nil, @person.age
|
||||
assert_equal 1, @person.age_calls
|
||||
@@ -131,13 +140,7 @@ class MemoizableTest < Test::Unit::TestCase
|
||||
assert_equal 1, @person.age_calls
|
||||
end
|
||||
|
||||
def test_memorized_results_are_immutable
|
||||
assert_equal "Josh", @person.name
|
||||
assert_raise(ActiveSupport::FrozenObjectError) { @person.name.gsub!("Josh", "Gosh") }
|
||||
end
|
||||
|
||||
def test_reloadable
|
||||
counter = @calculator.counter
|
||||
assert_equal 1, @calculator.counter
|
||||
assert_equal 2, @calculator.counter(:reload)
|
||||
assert_equal 2, @calculator.counter
|
||||
|
||||
Reference in New Issue
Block a user