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

Incorrect auto-correction for Style/StringLiterals cop #11123

Closed
konieczkow opened this issue Oct 25, 2022 · 3 comments · Fixed by #11144
Closed

Incorrect auto-correction for Style/StringLiterals cop #11123

konieczkow opened this issue Oct 25, 2022 · 3 comments · Fixed by #11144
Labels

Comments

@konieczkow
Copy link

Hi there, thanks to all the people working on Rubocop.

I noticed a weird behaviour when applying an autocorrection to the following code.

a = {
  b: "{\"[\\\"*\\\"]\""
}

This gets correctly marked as violating Style/StringLiterals but when I run rubocop with -a (which I assume means it will correct all the cops as long as it is safe to do so) I get this as the output:

a = {
  b: '{"["*"]"'
}

It seems to me that the autocorrection is too greedy and swollows too many escape characters?


Expected behavior

I would expect rubocop to either correctly escape the code to:

a = {
  b: {"[\"*\"]"
}

or it should say that the cop is unsafe and can be used with -A, instead of -a.

Actual behavior

Autocorrecting:

a = {
  b: "{\"[\\\"*\\\"]\""
}

produces:

a = {
  b: '{"["*"]"'
}

Steps to reproduce the problem

Create an empty ruby file, add the following piece of code to it:

a = {
  b: "{\"[\\\"*\\\"]\""
}

run:

rubocop -a [name-of-the-file]

check the file again.

RuboCop version

$ rubocop -V
1.37.1 (using Parser 3.1.2.1, rubocop-ast 1.23.0, running on ruby 2.7.6) [x86_64-linux]
@konieczkow konieczkow changed the title Incorrect auto-correction for Style/StringLiterals cop Incorrect auto-correction for Style/StringLiterals cop Oct 25, 2022
@koic koic added the bug label Oct 25, 2022
@konieczkow
Copy link
Author

Had a look at the source code and it seems to me that the problem is somewhere here:

"'#{string.gsub('\"', '"').gsub('\\') { '\\\\' }}'"

Switching the order of the gsubs fixes my issue:

original_string = "{\"[\\\"*\\\"]\"".freeze

irb(main):038:0> original_string.gsub('\"', '"').gsub('\\') { '\\\\' }
=> "{\"[\"*\"]\""
irb(main):039:0> original_string.gsub('\\') { '\\\\' }.gsub('\"', '"')
=> "{\"[\\\"*\\\"]\""

but not sure if it doesn't break anything else. Will clone the project and run the test suite to see.

@konieczkow
Copy link
Author

Running the specs - this breaks a few examples in spec/rubocop/cop/style/quoted_symbols_spec.rb.

@tdeo
Copy link
Contributor

tdeo commented Nov 2, 2022

@konieczkow if you want to open a PR for this it seems to me the issue is actually that QuotedSymbols calls to_string_literal not with the intended argument style.

Indeed, StringLiterals through StringLiteralCorrector calls it with the result of DStrNode.str_content, which takes care of handling some escaping:

str = node.str_content
if style == :single_quotes
corrector.replace(node, to_string_literal(str))

While QuotedSymbols calls it directly with the source of the node which retains escape-backslashes as characters:

str = if hash_colon_key?(node)
# strip quotes
correct_quotes(node.source[1..-2])
else
# strip leading `:` and quotes
":#{correct_quotes(node.source[2..-2])}"

It seems that on top of your fix, changing those lines to using eval to replicate the behavior of str_content actually makes the tests pass for Style/QuotedSymbols:

# Using eval to replicate the behavior of `#str_content`
str = if hash_colon_key?(node)
                  correct_quotes(eval(node.source))
                else
                  # strip leading `:`
                  ":#{correct_quotes(eval(node.source[1..]))}"
                end

But I'm not sure whether using eval here would be accepted - maybe the proper solution is to implement str_content on SymNode that behaves similarly as for DstrNode. Maybe a rubocop maintainer could point in the preferred direction for implementation?

si-lens added a commit to si-lens/rubocop that referenced this issue Nov 12, 2022
koic added a commit that referenced this issue Nov 12, 2022
…yle/StringLiterals

[Fix #11123 ] Fix auto correction bug for Style/StringLiterals
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants