Skip to content
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

Infinite loop between Lint/SymbolConversion and Style/QuotedSymbols #11836

Closed
schcamille opened this issue May 2, 2023 · 1 comment
Closed
Labels

Comments

@schcamille
Copy link

Expected behavior

Running rubocop --only Lint/SymbolConversion,Style/QuotedSymbols -A should autocorrect and not raise an infinite loop on the following example symbol:

:'select * from table where name = ""'

Actual behavior

We’ve noticed an infinite loop between Lint/SymbolConversion and Style/QuotedSymbols:

rubocop --only Lint/SymbolConversion,Style/QuotedSymbols --debug -A test.rb
For <FILE_PATH>: Default configuration from <RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/config/default.yml
Use parallel by default.
Skipping parallel inspection: only a single file needs inspection
Inspecting 1 file
Scanning <FILE_PATH>/test.rb
W

Offenses:

test.rb:15:50: W: [Corrected] Lint/SymbolConversion: Unnecessary symbol conversion; use :"select * from table where name = \"\"" instead.
Person.where(SafeActiveRecord::TrustedSymbol.new(:'select * from table where name = ""'))
                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test.rb:15:50: C: [Corrected] Style/QuotedSymbols: Prefer single-quoted symbols when you don't need string interpolation or special symbols.
Person.where(SafeActiveRecord::TrustedSymbol.new(:"select * from table where name = \"\""))
                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0 files inspected, 2 offenses detected, 2 offenses corrected
Infinite loop detected in <FILE_PATH>/test.rb and caused by Lint/SymbolConversion -> Style/QuotedSymbols
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:332:in `check_for_infinite_loop'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:315:in `block in iterate_until_no_changes'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:314:in `loop'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:314:in `iterate_until_no_changes'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:283:in `do_inspection_loop'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:164:in `block in file_offenses'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:189:in `file_offense_cache'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:163:in `file_offenses'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:154:in `process_file'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:135:in `block in each_inspected_file'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:134:in `each'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:134:in `reduce'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:134:in `each_inspected_file'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:120:in `inspect_files'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/runner.rb:73:in `run'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/cli/command/execute_runner.rb:26:in `block in execute_runner'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/cli/command/execute_runner.rb:52:in `with_redirect'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/cli/command/execute_runner.rb:25:in `execute_runner'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/cli/command/execute_runner.rb:17:in `run'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/cli/command.rb:11:in `run'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/cli/environment.rb:18:in `run'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/cli.rb:118:in `run_command'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/cli.rb:125:in `execute_runners'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/cli.rb:51:in `block in run'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/cli.rb:77:in `profile_if_needed'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/lib/rubocop/cli.rb:43:in `run'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/exe/rubocop:19:in `block in <top (required)>'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/3.0.0/benchmark.rb:308:in `realtime'
<RUBY_PATH>/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/rubocop-1.50.2/exe/rubocop:19:in `<top (required)>'
<RUBY_PATH>/installs/ruby/3.0.3/bin/rubocop:25:in `load'
<RUBY_PATH>/installs/ruby/3.0.3/bin/rubocop:25:in `<main>'

Steps to reproduce the problem

Gemfile:

gem 'safe_active_record', git: 'https://github.com/google/safe-active-record'
gem 'rails'

test.rb:

require 'active_record'
require 'safe_active_record'

SafeActiveRecord.activate!({ dry_run: true, intercept_load: false })

class Person < ActiveRecord::Base
  establish_connection adapter: 'sqlite3', database: 'foobar.db'
  connection.create_table table_name, force: true do |t|
    t.string :name
  end
end

Person.where(SafeActiveRecord::TrustedSymbol.new(:'select * from table where name = ""'))

Run rubocop:

rubocop --only Lint/SymbolConversion,Style/QuotedSymbols -A test.rb

RuboCop version

$ rubocop -V
1.50.2 (using Parser 3.2.2.1, rubocop-ast 1.28.1, running on ruby 3.0.3) [x86_64-linux]
@koic koic added the bug label May 2, 2023
@chrisops
Copy link

chrisops commented May 29, 2023

I've been looking for a ✨good first contribution✨ and I've found that RuboCop::Cop::Lint::SymbolConversion is incorrectly finding an offence for properly_quoted? where it tries to compare the node source to the value:

pry> node.source
=> ":'select * from table where name = \"\"'"

pry> node.value.inspect
=> ":\"select * from table where name = \\\"\\\"\""

Symbol.inspect seems to add a whole lot of extra backslashes and so fails the cop check

This causes an infinite loop where it will replace the single quotes with double quotes, then Style/QuotedSymbols will change it back again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants