Commit 5a7a0445 authored by Pavlo Dudchenko's avatar Pavlo Dudchenko

24083 /tableflip quick action is interpreted even if inside code block

parent ec85e345
---
title: 'Fix: tableflip quick action is interpreted even if inside code block'
merge_request:
author: Pavlo Dudchenko
type: fixed
...@@ -13,6 +13,7 @@ module Gitlab ...@@ -13,6 +13,7 @@ module Gitlab
def initialize(command_definitions) def initialize(command_definitions)
@command_definitions = command_definitions @command_definitions = command_definitions
@commands_regex = {}
end end
# Extracts commands from content and return an array of commands. # Extracts commands from content and return an array of commands.
...@@ -58,7 +59,8 @@ module Gitlab ...@@ -58,7 +59,8 @@ module Gitlab
content = content.dup content = content.dup
content.delete!("\r") content.delete!("\r")
content.gsub!(commands_regex(only: only)) do names = command_names(limit_to_commands: only).map(&:to_s)
content.gsub!(commands_regex(names: names)) do
command, output = process_commands($~, redact) command, output = process_commands($~, redact)
commands << command commands << command
output output
...@@ -91,10 +93,8 @@ module Gitlab ...@@ -91,10 +93,8 @@ module Gitlab
# It looks something like: # It looks something like:
# #
# /^\/(?<cmd>close|reopen|...)(?:( |$))(?<arg>[^\/\n]*)(?:\n|$)/ # /^\/(?<cmd>close|reopen|...)(?:( |$))(?<arg>[^\/\n]*)(?:\n|$)/
def commands_regex(only:) def commands_regex(names:)
names = command_names(limit_to_commands: only).map(&:to_s) @commands_regex[names] ||= %r{
@commands_regex ||= %r{
(?<code> (?<code>
# Code blocks: # Code blocks:
# ``` # ```
...@@ -151,14 +151,18 @@ module Gitlab ...@@ -151,14 +151,18 @@ module Gitlab
end end
substitution_definitions.each do |substitution| substitution_definitions.each do |substitution|
match_data = substitution.match(content.downcase) regex = commands_regex(names: substitution.all_names)
if match_data content = content.gsub(regex) do |text|
command = [substitution.name.to_s] if $~[:cmd]
command << match_data[1] unless match_data[1].empty? command = [substitution.name.to_s]
commands << command command << $~[:arg] if $~[:arg].present?
commands << command
substitution.perform_substitution(self, text)
else
text
end
end end
content = substitution.perform_substitution(self, content)
end end
[content, commands] [content, commands]
......
...@@ -17,7 +17,7 @@ module Gitlab ...@@ -17,7 +17,7 @@ module Gitlab
return unless content return unless content
all_names.each do |a_name| all_names.each do |a_name|
content = content.gsub(%r{/#{a_name}(?![\S]) ?(.*)$}i, execute_block(action_block, context, '\1')) content = content.sub(%r{/#{a_name}(?![\S]) ?(.*)$}i, execute_block(action_block, context, '\1'))
end end
content content
......
...@@ -216,6 +216,22 @@ describe Gitlab::QuickActions::Extractor do ...@@ -216,6 +216,22 @@ describe Gitlab::QuickActions::Extractor do
expect(msg).to eq "hello\nworld\nthis is great? SHRUG" expect(msg).to eq "hello\nworld\nthis is great? SHRUG"
end end
it 'extracts and performs multiple substitution commands' do
msg = %(hello\nworld\n/reopen\n/shrug this is great?\n/shrug meh)
msg, commands = extractor.extract_commands(msg)
expect(commands).to eq [['reopen'], ['shrug', 'this is great?'], %w(shrug meh)]
expect(msg).to eq "hello\nworld\nthis is great? SHRUG\nmeh SHRUG"
end
it 'does not extract substitution command in inline code' do
msg = %(hello\nworld\n/reopen\n`/tableflip this is great`?)
msg, commands = extractor.extract_commands(msg)
expect(commands).to eq [['reopen']]
expect(msg).to eq "hello\nworld\n`/tableflip this is great`?"
end
it 'extracts and performs substitution commands case insensitive' do it 'extracts and performs substitution commands case insensitive' do
msg = %(hello\nworld\n/reOpen\n/sHRuG this is great?) msg = %(hello\nworld\n/reOpen\n/sHRuG this is great?)
msg, commands = extractor.extract_commands(msg) msg, commands = extractor.extract_commands(msg)
......
...@@ -7,6 +7,7 @@ describe Gitlab::QuickActions::SubstitutionDefinition do ...@@ -7,6 +7,7 @@ describe Gitlab::QuickActions::SubstitutionDefinition do
<<EOF <<EOF
Hello! Let's do this! Hello! Let's do this!
/sub_name I like this stuff /sub_name I like this stuff
/sub_name second substitution
EOF EOF
end end
...@@ -24,6 +25,7 @@ EOF ...@@ -24,6 +25,7 @@ EOF
expect(subject.perform_substitution(self, content)).to eq <<EOF expect(subject.perform_substitution(self, content)).to eq <<EOF
Hello! Let's do this! Hello! Let's do this!
I like this stuff foo I like this stuff foo
/sub_name second substitution
EOF EOF
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment