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

Fix gemspec sanitization bug when heredoc has methods chained onto it #3220

Merged

Conversation

jasonrudolph
Copy link
Contributor

@jasonrudolph jasonrudolph commented Mar 2, 2021

When dependabot is processing a gemspec, it performs some sanitization of the gemspec's content. In most situations, it handles a heredoc by replacing the heredoc's content as seen in this test.

Given a gemspec like this:

Spec.new do |s|
  s.version = "0.1.0"
  s.post_install_message = <<~DESCRIPTION
    My description
  DESCRIPTION
end

The sanitized output should look like this:

Spec.new do |s|
  s.version = "0.1.0"
  "sanitized"
end

That's the current behavior, and it meets our needs. However, if the heredoc has methods chained onto it, the sanitzation currently produces invalid Ruby code.

Given a gemspec like this:

Spec.new do |s|
  s.version = "0.1.0"
  s.post_install_message = <<~DESCRIPTION.strip.downcase
    My description
  DESCRIPTION
end

We should get the same sanitized output that we got in the previous example, but we currently get the following output instead:

Spec.new do |s|
  s.version = "0.1.0"
  "sanitized"
    My description
  DESCRIPTION
end

Later on in the dependabot-core workflow, when we ask bundler to evaluate the sanitized gemspec, it fails with a parser error because the output above is invalid Ruby code.

TODO

  • Add a failing test to demonstrate the bug
  • Fix the bug

Given a gemspec like this:

  Spec.new do |s|
    s.version = "0.1.0"
    s.post_install_message = <<~DESCRIPTION.strip.downcase
      My description
    DESCRIPTION
  end

The sanitized output should look like this:

  Spec.new do |s|
    s.version = "0.1.0"
    "sanitized"
  end

But it actually looks like this:

  Spec.new do |s|
    s.version = "0.1.0"
    "sanitized"
      My description
    DESCRIPTION
  end

I'll look into a fix for this bug in a follow-up commit.
@feelepxyz
Copy link
Contributor

Looks like this is where we try and do the sanitisation: https://github.com/dependabot/dependabot-core/blob/main/bundler/lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb#L237-L242 haven't worked on this code but would be up for spending a short block on trying to fix it.

@jasonrudolph jasonrudolph marked this pull request as ready for review March 4, 2021 17:29
@jasonrudolph jasonrudolph requested a review from a team as a code owner March 4, 2021 17:29
Comment on lines +258 to +271
def find_heredoc_end_range(node)
return unless node.is_a?(Parser::AST::Node)

node.children.each do |child|
next unless child.is_a?(Parser::AST::Node)

return child.location.heredoc_end if child.location.respond_to?(:heredoc_end)

range = find_heredoc_end_range(child)
return range if range
end

nil
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We (@feelepxyz and I) suspect that there's a more readable way to implement this. We explored a few options, but the other options were a bit harder to follow in our opinion. So, if you have ideas for an alternative implementation that would be easier to read/maintain, definitely let us know. 🙇

@jasonrudolph
Copy link
Contributor Author

The npm_and_yarn CI job is failing due to a flaky test. That flaky test is fixed in #3229. Once #3229 is merged, I'll merge main into this branch, and that should give us a green build.

@feelepxyz
Copy link
Contributor

feelepxyz commented Mar 4, 2021 via email

@xlgmokha xlgmokha self-assigned this Mar 4, 2021
@xlgmokha xlgmokha enabled auto-merge March 5, 2021 22:47
@xlgmokha xlgmokha merged commit 3cb458b into main Mar 6, 2021
@xlgmokha xlgmokha deleted the gracefully-handle-gemspecs-with-heredocs-with-method-chains branch March 6, 2021 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants