Avoid 'defined?' buggy behavior in ruby 2.5.0. Fixes #253

'defined?' is buggy in ruby 2.5.0, which under certain circumstances
users using rack-attack can hit. See issue #253.

I reported (https://bugs.ruby-lang.org/issues/14407) and
fixed (https://github.com/ruby/ruby/pull/1800) the issue in
ruby already, but i guess i would take some time before there's
a new ruby release including that fix.

So for now we would need to circumvent this bug by using
'const_defined?' instead of 'defined?' for this particular case.

More details:

Anyone using:
  * ruby 2.5.0
  * redis
  * rack-attack without redis-store and using at least one throttle
  * having a toplevel class named Store

will hit this ruby 2.5.0 bug https://bugs.ruby-lang.org/issues/14407

That's because of the following buggy behavior of 'defined?' under ruby
2.5:

```
$ ruby -v
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]

$ irb
> class Redis
> end
=> nil
> class Store
> end
=> nil
> defined?(::Redis::Store)
=> "constant"
> ::Redis::Store
  NameError (uninitialized constant Redis::Store
    Did you mean?  Store)
```
This commit is contained in:
Gonzalo Rodriguez 2018-01-29 12:19:05 -03:00
parent d7cc49117f
commit 6af29fb44e

View file

@ -5,7 +5,14 @@ module Rack
module StoreProxy
class RedisStoreProxy < SimpleDelegator
def self.handle?(store)
defined?(::Redis::Store) && store.is_a?(::Redis::Store)
# Using const_defined? for now.
#
# Go back to use defined? once this ruby issue is
# fixed and released:
# https://bugs.ruby-lang.org/issues/14407
#
# defined?(::Redis::Store) && store.is_a?(::Redis::Store)
const_defined?("::Redis::Store") && store.is_a?(::Redis::Store)
end
def initialize(store)