-
-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dig can cause weird exceptions #128
Conversation
`dig` throws a `TypeError` exception when `params[scope]` is set (e.g. to a string). Example this works: ```ruby params = { actor: { name: "Nicolas Cage" } } # digging with keys that don't exist params.dig(:foo, :bar) => nil # digging with keys that partially exist params.dig(:actor, :name, :whatever) => TypeError: String does not have #dig method ``` Full article: http://anamaria.martinezgomez.name/2018/01/07/ruby-dig.html Original discussion: https://bugs.ruby-lang.org/issues/11762
Codecov Report
@@ Coverage Diff @@
## master #128 +/- ##
=======================================
Coverage 98.39% 98.39%
=======================================
Files 22 22
Lines 435 435
=======================================
Hits 428 428
Misses 7 7
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks 👍
Thanks for the super quick merge :)
(in this section: https://github.com/markets/invisible_captcha/blob/master/README.md#controller-method-options) |
Ah right! Good catch 🧐 We can remove this note now (basically revert #124). Would you like to send a PR? |
Sure: |
cc @maxveldink |
Thanks @jankoegel! I'd like to release a new version soon, this is the current diff: v2.1.0...master Maybe it's worth a patch release v2.1.1 now? |
@markets i'm wondering whether the specs from here could be useful: Looking for a way to prevent the next person from re-adding I have 6 failing specs locally, though. Using Ruby 3.2.2: Rspec output 1) InvisibleCaptcha::ControllerExt honeypot attribute with random honeypot with no scope passes with no spam
Failure/Error: expect(response.body).to be_present
expected `"".present?` to be truthy, got false
# ./spec/controllers_spec.rb:151:in `block (5 levels) in <top (required)>'
2) InvisibleCaptcha::ControllerExt honeypot attribute with random honeypot with no scope with parameter the same name as the controller passes with no spam
Failure/Error: if params[default_honeypot].present? || (params[scope] && params[scope][default_honeypot].present?)
TypeError:
no implicit conversion of Symbol into Integer
# ./lib/invisible_captcha/controller_ext.rb:102:in `[]'
# ./lib/invisible_captcha/controller_ext.rb:102:in `block in honeypot_spam?'
# ./lib/invisible_captcha/controller_ext.rb:101:in `each'
# ./lib/invisible_captcha/controller_ext.rb:101:in `honeypot_spam?'
# ./lib/invisible_captcha/controller_ext.rb:24:in `detect_spam'
# ./lib/invisible_captcha/controller_ext.rb:13:in `block in invisible_captcha'
# ./spec/controllers_spec.rb:162:in `block (6 levels) in <top (required)>'
3) InvisibleCaptcha::ControllerExt honeypot attribute with random honeypot auto-scoped passes with no spam
Failure/Error: expect(response.body).to be_present
expected `"".present?` to be truthy, got false
# ./spec/controllers_spec.rb:129:in `block (5 levels) in <top (required)>'
4) InvisibleCaptcha::ControllerExt honeypot attribute with random honeypot auto-scoped with parameter the same name as the controller passes with no spam
Failure/Error: if params[default_honeypot].present? || (params[scope] && params[scope][default_honeypot].present?)
TypeError:
no implicit conversion of Symbol into Integer
# ./lib/invisible_captcha/controller_ext.rb:102:in `[]'
# ./lib/invisible_captcha/controller_ext.rb:102:in `block in honeypot_spam?'
# ./lib/invisible_captcha/controller_ext.rb:101:in `each'
# ./lib/invisible_captcha/controller_ext.rb:101:in `honeypot_spam?'
# ./lib/invisible_captcha/controller_ext.rb:24:in `detect_spam'
# ./lib/invisible_captcha/controller_ext.rb:13:in `block in invisible_captcha'
# ./spec/controllers_spec.rb:140:in `block (6 levels) in <top (required)>'
5) InvisibleCaptcha::ControllerExt submission timestamp_threshold successful submissions allow to set a custom timestamp_threshold per action
Failure/Error: expect(response.body).to be_present
expected `"".present?` to be truthy, got false
# ./spec/controllers_spec.rb:99:in `block (4 levels) in <top (required)>'
6) InvisibleCaptcha::ControllerExt submission timestamp_threshold successful submissions passes if submission on or after timestamp_threshold
Failure/Error: expect(response.body).to be_present
expected `"".present?` to be truthy, got false
# ./spec/controllers_spec.rb:87:in `block (4 levels) in <top (required)>' |
🤔 Weird... The CI already runs on Ruby 3.2.2 with success: https://github.com/markets/invisible_captcha/actions/runs/6629004356/job/18007346398#step:3:13 |
The problem
OneTimePasswordsController
and the form input field is calledone_time_password
.invisible_captcha
gem breaks in unexpected waysWhere does it happen
92
and102
here call Ruby'sdig
method (permalink for current master's code):invisible_captcha/lib/invisible_captcha/controller_ext.rb
Lines 92 to 102 in 1b70b6e
dig
was added in this commit:954312b#diff-0e2f2afd505e226663c121b957ac3ea24ff5cc092ad4fa6a4129351c03407441R91
Why it happens
dig
throws aTypeError
exception whenparams[scope]
is set (e.g. to a string).simpler Ruby example
this works:
but this breaks with an exception:
Full article on
dig
and its problems: http://anamaria.martinezgomez.name/2018/01/07/ruby-dig.htmlrelated discussion from the Ruby mailing list: https://bugs.ruby-lang.org/issues/11762
Suggested Fix
dig
, it's not a 1:1 replacement forparams[scope] && params[scope][honeypot]