Compare commits

..

25 Commits

Author SHA1 Message Date
Charlie Somerville
dbe129af02 compile helpers without trace instruction 2013-10-16 19:54:42 -04:00
Charlie Somerville
bf71aa30d2 fast 2013-10-15 15:07:23 -04:00
Charlie Somerville
0928c2bf4f automatically infer file/line of module eval from caller 2013-10-15 15:05:32 -04:00
Charlie Somerville
c96caaae9a Merge pull request #19 from github/delete-formatted-route-helper
Delete deprecated formatted_ URL helper
2013-10-01 21:56:02 -07:00
Charlie Somerville
050be61caf delete test for formatted_ 2013-10-02 14:29:50 +10:00
Charlie Somerville
4baefa4de9 delete formatted_ url helper 2013-10-02 14:25:57 +10:00
Charlie Somerville
26fce88209 add readme with note that this fork is unsupported 2013-09-18 00:37:48 +10:00
Charlie Somerville
cb507570a1 Merge pull request #18 from github/remove-use-of-method-private
Remove use of Method#private?
2013-09-16 22:59:19 -07:00
Charlie Somerville
9a2d6cad23 backport rails 4 assign attributes 2013-09-17 15:50:09 +10:00
Charlie Somerville
bf96f35248 we can used defined?() to check if a method is public or protected 2013-09-17 15:45:25 +10:00
Charlie Somerville
21bae614ee Merge pull request #17 from github/remove-warnings-from-tests
Don't use -w in tests
2013-09-16 22:43:27 -07:00
Charlie Somerville
1d6053f5bf remove -w from tests 2013-09-17 15:40:41 +10:00
Charlie Somerville
f90bfeb930 Merge pull request #16 from github/build-on-ruby-1.9.3-and-2.0.0
Build on Ruby 1.9.3 and 2.0.0
2013-09-16 22:35:48 -07:00
Charlie Somerville
bca938dae2 skip over memcached tests 2013-09-17 12:08:57 +10:00
Charlie Somerville
4579aa2767 run rails tests on both ruby 1.9.3 and 2.0.0 2013-09-17 11:47:15 +10:00
Charlie Somerville
0a522af512 Merge pull request #15 from github/add-gemspecs
Add gemspecs
2013-09-16 18:29:30 -07:00
Charlie Somerville
ca6a64758b bump rack dependency to 1.4 to match what we currently have 2013-09-17 11:24:19 +10:00
Charlie Somerville
8573f7f86b pull in gemspecs from upstream 2013-09-17 11:17:06 +10:00
Charlie Somerville
685cb901fc Merge pull request #13 from github/backport-message_verifier
Backport ActiveSupport::MessageVerifier from Rails 3
2013-08-27 03:55:52 -07:00
Charlie Somerville
e9f9d05a94 pass digest as a key in an options hash 2013-08-27 20:51:18 +10:00
Charlie Somerville
7b6670cc08 fix test 2013-08-27 20:51:14 +10:00
Charlie Somerville
ed2d852bdc backport ActiveSupport::MessageVerifier from Rails 3 2013-08-27 20:27:31 +10:00
Greg Ose
726ab5316d Merge pull request #12 from github/authenticity_token_tests
Authenticity token tests
2013-08-13 11:37:09 -07:00
Greg Ose
ecd6fb250a Test for form_for authenticity_token backport 2013-08-12 13:21:03 -05:00
Greg Ose
9f8ee9dd97 Merge tag 'github24' into authenticity_token_tests
github24
2013-08-12 12:54:23 -05:00
25 changed files with 301 additions and 132 deletions

6
README.md Normal file
View File

@@ -0,0 +1,6 @@
# GitHub Rails
This is GitHub's fork of Rails 2.3.
Please note that this fork is **unsupported**. It is not guaranteed to receive security patches or remain stable. **Use at your own risk.**

View File

@@ -23,8 +23,6 @@ task :default => [ :test ]
Rake::TestTask.new { |t|
t.libs << "test"
t.pattern = 'test/*_test.rb'
t.verbose = true
t.warning = false
}

View File

@@ -0,0 +1,14 @@
Gem::Specification.new do |s|
s.name = 'actionmailer'
s.version = '2.3.18'
s.summary = 'Service layer for easy email delivery and testing.'
s.description = 'Makes it trivial to test and deliver emails sent from a single service layer.'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.add_dependency 'actionpack', '= 2.3.18'
end

View File

@@ -30,16 +30,12 @@ Rake::TestTask.new(:test_action_pack) do |t|
# make sure we include the tests in alphabetical order as on some systems
# this will not happen automatically and the tests (as a whole) will error
t.test_files = Dir.glob( "test/[cftv]*/**/*_test.rb" ).sort
t.verbose = true
#t.warning = true
end
desc 'ActiveRecord Integration Tests'
Rake::TestTask.new(:test_active_record_integration) do |t|
t.libs << "test"
t.test_files = Dir.glob("test/activerecord/*_test.rb")
t.verbose = true
end

View File

@@ -0,0 +1,15 @@
Gem::Specification.new do |s|
s.name = 'actionpack'
s.version = '2.3.18'
s.summary = 'Web-flow and rendering framework putting the VC in MVC.'
s.description = 'Eases web-request routing, handling, and response as a half-way front, half-way page controller. Implemented with specific emphasis on enabling easy unit/integration testing that doesn\'t require a browser.'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.add_dependency 'activesupport', '= 2.3.18'
s.add_dependency 'rack', '~> 1.4'
end

View File

@@ -1332,10 +1332,7 @@ module ActionController #:nodoc:
if action_methods.include?(action_name)
send(action_name)
default_render unless performed?
elsif RUBY_VERSION == "1.9.3" && respond_to?(:method_missing)
method_missing action_name.intern
default_render unless performed?
elsif RUBY_VERSION >= "2.0.0" && respond_to?(:method_missing, true) && !method(:method_missing).private?
elsif defined?(self.method_missing) # returns "method" if method_missing is public or protected, but not if it's private
method_missing action_name.intern
default_render unless performed?
else

View File

@@ -138,8 +138,13 @@ module ActionController
end
end
def named_helper_module_eval(code, *args)
@module.module_eval(code, *args)
def named_helper_module_eval(code)
file, line = caller.first.split(":")
compile_option = RubyVM::InstructionSequence.compile_option
RubyVM::InstructionSequence.compile_option = compile_option.merge(:trace_instruction => false)
@module.module_eval(code, file, line.to_i + 1)
ensure
RubyVM::InstructionSequence.compile_option = compile_option
end
def define_hash_access(route, name, kind, options)
@@ -192,17 +197,44 @@ module ActionController
url_for(#{hash_access_method}(opts)) # url_for(hash_for_users_url(opts))
#
end # end
#Add an alias to support the now deprecated formatted_* URL. # #Add an alias to support the now deprecated formatted_* URL.
def formatted_#{selector}(*args) # def formatted_users_url(*args)
ActiveSupport::Deprecation.warn( # ActiveSupport::Deprecation.warn(
"formatted_#{selector}() has been deprecated. " + # "formatted_users_url() has been deprecated. " +
"Please pass format to the standard " + # "Please pass format to the standard " +
"#{selector} method instead.", caller) # "users_url method instead.", caller)
#{selector}(*args) # users_url(*args)
end # end
protected :#{selector} # protected :users_url
end_eval
helpers << selector
if kind == :path
define_fast_url_helper(selector, route, name)
end
end
def define_fast_url_helper(selector, route, name)
dynamic_segments = route.segments.grep(DynamicSegment)
return if dynamic_segments.any?(&:optional?) # TODO - maybe exclude optional format
helper_arguments = dynamic_segments.map { |route_argument|
"arg_#{route_argument.key}"
}
route_segments = route.segments.dup
if route_segments.size > 1 && route_segments.last.is_a?(DividerSegment) && route_segments.last.optional?
route_segments.pop
end
string_segments = route_segments.map { |segment|
if segment.is_a?(StaticSegment)
segment.value.inspect
else
'"#{URI::DEFAULT_PARSER.escape(arg_%s.to_s, ActionController::Routing::Segment::UNSAFE_PCHAR)}"' % segment.key
end
}
named_helper_module_eval <<-"RUBY"
def fast_#{selector}(#{helper_arguments.join(", ")})
#{string_segments.join(" ")}
end
RUBY
end
end

View File

@@ -209,7 +209,7 @@ module ActionController
def verifier_for(secret, digest)
key = secret.respond_to?(:call) ? secret.call : secret
ActiveSupport::MessageVerifier.new(key, digest)
ActiveSupport::MessageVerifier.new(key, digest: digest)
end
def generate_sid

View File

@@ -19,6 +19,14 @@ module RequestForgeryProtectionActions
render :inline => "<% form_remote_tag(:url => '/') {} %>"
end
def external_form_for
render :inline => "<%= form_for(:some_resource, :authenticity_token => 'external_token') {} %>"
end
def form_for_without_token
render :inline => "<%= form_for(:some_resource, :authenticity_token => false ) {} %>"
end
def unsafe
render :text => 'pwn'
end
@@ -156,6 +164,20 @@ module RequestForgeryProtectionTests
assert_nothing_raised { yield }
assert_response :success
end
def test_should_render_form_with_token_tag_with_authenticity_token_requested
assert_not_blocked do
get :external_form_for
end
assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', 'external_token'
end
def test_should_render_form_without_token_tag_with_authenticity_token_set_to_false
assert_not_blocked do
get :form_for_without_token
end
assert_select 'form>div>input[name=?]', 'authenticity_token', false
end
end
# OK let's get our test on

View File

@@ -7,7 +7,7 @@ class CookieStoreTest < ActionController::IntegrationTest
DispatcherApp = ActionController::Dispatcher.new
Verifier = ActiveSupport::MessageVerifier.new(SessionSecret, 'SHA1')
Verifier = ActiveSupport::MessageVerifier.new(SessionSecret, digest: 'SHA1')
SignedBar = "BAh7BjoIZm9vIghiYXI%3D--fef868465920f415f2c0652d6910d3af288a0367"

View File

@@ -357,24 +357,6 @@ class UrlWriterTests < ActionController::TestCase
ActionController::Routing::Routes.load!
end
def test_formatted_url_methods_are_deprecated
ActionController::Routing::Routes.draw do |map|
map.resources :posts
end
# We need to create a new class in order to install the new named route.
kls = Class.new { include ActionController::UrlWriter }
controller = kls.new
params = {:id => 1, :format => :xml}
assert_deprecated do
assert_equal("/posts/1.xml", controller.send(:formatted_post_path, params))
end
assert_deprecated do
assert_equal("/posts/1.xml", controller.send(:formatted_post_path, 1, :xml))
end
ensure
ActionController::Routing::Routes.load!
end
def test_multiple_includes_maintain_distinct_options
first_class = Class.new { include ActionController::UrlWriter }
second_class = Class.new { include ActionController::UrlWriter }

View File

@@ -64,7 +64,6 @@ for adapter in %w( mysql postgresql sqlite sqlite3 firebird db2 oracle sybase op
end
adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z]+/]
t.test_files=Dir.glob( "test/cases/**/*_test{,_#{adapter_short}}.rb" ).sort
t.verbose = true
}
namespace adapter do

View File

@@ -0,0 +1,17 @@
Gem::Specification.new do |s|
s.name = 'activerecord'
s.version = '2.3.18'
s.summary = 'Implements the ActiveRecord pattern for ORM.'
s.description = 'Implements the ActiveRecord pattern (Fowler, PoEAA) for ORM. It ties database tables and classes together for business objects, like Customer or Subscription, that can find, save, and destroy themselves without resorting to manual SQL.'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.files = ['README']
s.rdoc_options = ['--main', 'README']
s.extra_rdoc_files = ['README']
s.add_dependency 'activesupport', '= 2.3.18'
end

View File

@@ -2920,15 +2920,23 @@ module ActiveRecord #:nodoc:
attributes.each do |k, v|
if k.to_s.include?("(")
multiparameter_attributes << [ k, v ]
elsif RUBY_VERSION == "1.9.3"
respond_to?(:"#{k}=") ? send(:"#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}")
else
(respond_to?(:"#{k}=", true) && !method(:"#{k}=").private?) ? send(:"#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}")
_assign_attribute(k, v)
end
end
assign_multiparameter_attributes(multiparameter_attributes) unless multiparameter_attributes.empty?
end
def _assign_attribute(k, v)
public_send("#{k}=", v)
rescue NoMethodError => e
if respond_to?("#{k}=")
raise e
else
raise UnknownAttributeError, "unknown attribute: #{k}"
end
end
def create_or_update
raise ReadOnlyRecord if readonly?

View File

@@ -31,8 +31,6 @@ Rake::TestTask.new { |t|
t.libs << activesupport_path if File.directory?(activesupport_path)
t.libs << "test"
t.pattern = 'test/**/*_test.rb'
t.verbose = true
t.warning = true
}

View File

@@ -0,0 +1,17 @@
Gem::Specification.new do |s|
s.name = 'activeresource'
s.version = '2.3.18'
s.summary = 'Think Active Record for web resources.'
s.description = 'Wraps web resources in model classes that can be manipulated through XML over REST.'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.files = ['README']
s.rdoc_options = ['--main', 'README']
s.extra_rdoc_files = ['README']
s.add_dependency 'activesupport', '= 2.3.18'
end

View File

@@ -18,8 +18,6 @@ task :default => :test
Rake::TestTask.new { |t|
t.libs << "test"
t.pattern = 'test/**/*_test.rb'
t.verbose = true
t.warning = true
}
# Create compressed packages

View File

@@ -0,0 +1,12 @@
Gem::Specification.new do |s|
s.name = 'activesupport'
s.version = '2.3.18'
s.summary = 'Support and utility classes used by the Rails framework.'
s.description = 'Utility library which carries commonly used classes and goodies from the Rails framework'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
end

View File

@@ -1,79 +1,74 @@
require 'active_support/base64'
require 'active_support/deprecation'
require 'active_support/core_ext/object/blank'
module ActiveSupport
# MessageVerifier makes it easy to generate and verify messages which are signed
# +MessageVerifier+ makes it easy to generate and verify messages which are signed
# to prevent tampering.
#
#
# This is useful for cases like remember-me tokens and auto-unsubscribe links where the
# session store isn't suitable or available.
#
# Remember Me:
# cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now])
#
#
# In the authentication filter:
#
# id, time = @verifier.verify(cookies[:remember_me])
# if time < Time.now
# self.current_user = User.find(id)
# end
#
#
# By default it uses Marshal to serialize the message. If you want to use another
# serialization method, you can set the serializer attribute to something that responds
# to dump and load, e.g.:
#
# @verifier.serializer = YAML
class MessageVerifier
class InvalidSignature < StandardError; end
def initialize(secret, digest = 'SHA1')
def initialize(secret, options = {})
unless options.is_a?(Hash)
ActiveSupport::Deprecation.warn "The second parameter should be an options hash. Use :digest => 'algorithm' to specify the digest algorithm."
options = { :digest => options }
end
@secret = secret
@digest = digest
@digest = options[:digest] || 'SHA1'
@serializer = options[:serializer] || Marshal
end
def verify(signed_message)
raise InvalidSignature if signed_message.blank?
data, digest = signed_message.split("--")
if data.present? && digest.present? && secure_compare(digest, generate_digest(data))
Marshal.load(ActiveSupport::Base64.decode64(data))
@serializer.load(::Base64.decode64(data))
else
raise InvalidSignature
end
end
def generate(value)
data = ActiveSupport::Base64.encode64s(Marshal.dump(value))
data = ::Base64.strict_encode64(@serializer.dump(value))
"#{data}--#{generate_digest(data)}"
end
private
if "foo".respond_to?(:force_encoding)
# constant-time comparison algorithm to prevent timing attacks
def secure_compare(a, b)
a = a.dup.force_encoding(Encoding::BINARY)
b = b.dup.force_encoding(Encoding::BINARY)
if a.length == b.length
result = 0
for i in 0..(a.length - 1)
result |= a[i].ord ^ b[i].ord
end
result == 0
else
false
end
end
else
# For <= 1.8.6
def secure_compare(a, b)
if a.length == b.length
result = 0
for i in 0..(a.length - 1)
result |= a[i] ^ b[i]
end
result == 0
else
false
end
end
private
# constant-time comparison algorithm to prevent timing attacks
def secure_compare(a, b)
return false unless a.bytesize == b.bytesize
l = a.unpack "C#{a.bytesize}"
res = 0
b.each_byte { |byte| res |= byte ^ l.shift }
res == 0
end
def generate_digest(data)
require 'openssl' unless defined?(OpenSSL)
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(@digest), @secret, data)
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@digest).new, @secret, data)
end
end
end

View File

@@ -178,6 +178,8 @@ class MemoryStoreTest < ActiveSupport::TestCase
end
uses_memcached 'memcached backed store' do
next # these tests are broken on CI
class MemCacheStoreTest < ActiveSupport::TestCase
def setup
@cache = ActiveSupport::Cache.lookup_store(:mem_cache_store)

View File

@@ -1,16 +1,36 @@
require 'abstract_unit'
class MessageVerifierTest < Test::Unit::TestCase
def setup
@verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!")
@data = {:some=>"data", :now=>Time.now}
begin
require 'openssl'
OpenSSL::Digest::SHA1
rescue LoadError, NameError
$stderr.puts "Skipping MessageVerifier test: broken OpenSSL install"
else
require 'active_support/json'
class MessageVerifierTest < ActiveSupport::TestCase
class JSONSerializer
def dump(value)
ActiveSupport::JSON.encode(value)
end
def load(value)
ActiveSupport::JSON.decode(value)
end
end
def setup
@verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!")
@data = { :some => "data", :now => Time.local(2010) }
end
def test_simple_round_tripping
message = @verifier.generate(@data)
assert_equal @data, @verifier.verify(message)
end
def test_missing_signature_raises
assert_not_verified(nil)
assert_not_verified("")
@@ -23,9 +43,23 @@ class MessageVerifierTest < Test::Unit::TestCase
assert_not_verified("purejunk")
end
def test_alternative_serialization_method
verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!", :serializer => JSONSerializer.new)
message = verifier.generate({ :foo => 123, 'bar' => Time.utc(2010) })
assert_equal verifier.verify(message), { "foo" => 123, "bar" => "2010/01/01 00:00:00 +0000" }
end
def test_digest_algorithm_as_second_parameter_deprecation
assert_deprecated(/options hash/) do
ActiveSupport::MessageVerifier.new("secret", "SHA1")
end
end
def assert_not_verified(message)
assert_raise(ActiveSupport::MessageVerifier::InvalidSignature) do
@verifier.verify(message)
end
end
end
end

View File

@@ -35,8 +35,6 @@ end
Rake::TestTask.new("regular_test") do |t|
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.warning = true
t.verbose = true
end

22
railties/railties.gemspec Normal file
View File

@@ -0,0 +1,22 @@
Gem::Specification.new do |s|
s.name = 'rails'
s.version = '2.3.18'
s.summary = 'Web-application framework with template engine, control-flow layer, and ORM.'
s.description = "Rails is a framework for building web-application using CGI, FCGI, mod_ruby, or WEBrick\non top of either MySQL, PostgreSQL, SQLite, DB2, SQL Server, or Oracle with eRuby- or Builder-based templates."
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.files = ['bin/rails']
s.executables = ['rails']
s.rdoc_options = ['--exclude', '.']
s.add_dependency 'rake', '>= 0.8.3'
s.add_dependency 'activesupport', '= 2.3.18'
s.add_dependency 'activerecord', '= 2.3.18'
s.add_dependency 'actionpack', '= 2.3.18'
s.add_dependency 'actionmailer', '= 2.3.18'
s.add_dependency 'activeresource', '= 2.3.18'
end

View File

@@ -3,38 +3,5 @@
set -x
set -e
RUBY_VERSION="$(cat .ruby-version)"
# Use the right Ruby /without/ rbenv
ruby_dir=$(dirname "$(RBENV_VERSION=$RUBY_VERSION rbenv which ruby)")
export PATH=$ruby_dir:$PATH
# Announce who we are
ruby -v
# Because Rails 2.3 doesn't use Bundler for its own tests,
# we need to setup an isolated gem environment.
gem_environment_version="$(md5sum Gemfile.sh | cut -d' ' -f1)-$(ruby -e 'print RUBY_VERSION')"
gem_dir=`pwd`/.gem
gem_pristine_dir=${gem_dir}-${gem_environment_version}
export GEM_HOME=$gem_dir
export GEM_PATH=$gem_dir:$GEM_PATH
export GEM_ROOT=$gem_dir
rm -rf $gem_dir
if [ ! -d $gem_pristine_dir ]; then
mkdir $gem_dir
. Gemfile.sh
mv $gem_dir $gem_pristine_dir
fi
cp -r $gem_pristine_dir $gem_dir
# Go ham
rake
script/cibuild-on 1.9.3-p231-tcs-github
script/cibuild-on 2.0.0-github

40
script/cibuild-on Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
set -x
set -e
RUBY_VERSION="$1"
# Use the right Ruby /without/ rbenv
ruby_dir=$(dirname "$(RBENV_VERSION=$RUBY_VERSION rbenv which ruby)")
export PATH=$ruby_dir:$PATH
# Announce who we are
ruby -v
# Because Rails 2.3 doesn't use Bundler for its own tests,
# we need to setup an isolated gem environment.
gem_environment_version="$(md5sum Gemfile.sh | cut -d' ' -f1)-$(ruby -e 'print RUBY_VERSION')"
gem_dir=`pwd`/.gem
gem_pristine_dir=${gem_dir}-${gem_environment_version}
export GEM_HOME=$gem_dir
export GEM_PATH=$gem_dir:$GEM_PATH
export GEM_ROOT=$gem_dir
rm -rf $gem_dir
if [ ! -d $gem_pristine_dir ]; then
mkdir $gem_dir
. Gemfile.sh
mv $gem_dir $gem_pristine_dir
fi
cp -r $gem_pristine_dir $gem_dir
# Go ham
rake