Skip to content

Instantly share code, notes, and snippets.

@Intrepidd
Last active December 14, 2018 16:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Intrepidd/e3fe090fa5fe70e443b0abeec64f282b to your computer and use it in GitHub Desktop.
Save Intrepidd/e3fe090fa5fe70e443b0abeec64f282b to your computer and use it in GitHub Desktop.
class RuboCop::Cop::Security::LinkToBlank < RuboCop::Cop::Cop
MSG = 'Specify a `:rel` option containing noopener.'.freeze
def_node_matcher :link_to?, <<-PATTERN
(send nil? :link_to ...)
PATTERN
def_node_matcher :blank_target?, <<-PATTERN
(pair {(sym :target) (str "target")} (str "_blank"))
PATTERN
def_node_matcher :includes_noopener?, <<-PATTERN
(pair {(sym :rel) (str "rel")} (str #contains_noopener?))
PATTERN
def on_send(node)
return unless link_to?(node)
option_nodes = [node.children.last.children, node.children[3]&.children].compact
option_nodes.each do |options|
blank = options.find { |o| blank_target?(o) }
add_offense(blank) if blank && options.none? { |o| includes_noopener?(o) }
end
end
private
def contains_noopener?(str)
str&.include?('noopener')
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment