Skip to content

Commit

Permalink
Merge pull request #1427 from PombeirP/fix/verbatim-backticks-sanitiz…
Browse files Browse the repository at this point in the history
…ation

Improve @mention sanitizer for for verbatim backticks in code blocks
  • Loading branch information
feelepxyz authored Oct 8, 2019
2 parents dd8aea4 + e289ab2 commit 5b20bfc
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class LinkAndMentionSanitizer
github\.com/(?<repo>#{GITHUB_USERNAME}/[^/\s]+)/
(?:issue|pull)s?/(?<number>\d+)
}x.freeze
CODEBLOCK_REGEX = /```|~~~/.freeze
CODEBLOCK_REGEX = /(`+).*?(\1)|~~~.*?~~~/m.freeze
# End of string
EOS_REGEX = /\z/.freeze

Expand All @@ -26,23 +26,34 @@ def initialize(github_redirection_service:)
def sanitize_links_and_mentions(text:)
# We don't want to sanitize any links or mentions that are contained
# within code blocks, so we split the text on "```" or "~~~"
lines = []
sanitized_text = []
scan = StringScanner.new(text)
until scan.eos?
line = scan.scan_until(CODEBLOCK_REGEX) ||
scan.scan_until(EOS_REGEX)
delimiter = line.match(CODEBLOCK_REGEX)&.to_s
unless delimiter && lines.count { |l| l.include?(delimiter) }.odd?
line = sanitize_mentions(line)
line = sanitize_links(line)
end
lines << line
block = scan.scan_until(CODEBLOCK_REGEX) ||
scan.scan_until(EOS_REGEX)
sanitized_text << sanitize_links_and_mentions_in_block(block)
end
lines.join
sanitized_text.join
end

private

def sanitize_links_and_mentions_in_block(block)
# Handle code blocks one by one
normal_text = block
verbatim_text = ""
match = block.match(CODEBLOCK_REGEX)
if match
# Part leading up to start of code block
normal_text = match.pre_match
# Entire code block copied verbatim
verbatim_text = match.to_s
end
normal_text = sanitize_mentions(normal_text)
normal_text = sanitize_links(normal_text)
normal_text + verbatim_text
end

def sanitize_mentions(text)
text.gsub(%r{(?<![A-Za-z0-9`~])@#{GITHUB_USERNAME}/?}) do |mention|
next mention if mention.end_with?("/")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,35 @@
end
end

context "with mentions inside a complex code fence" do
let(:text) do
"Take a look at this code: ```` @not-a-mention "\
"```@not-a-mention``` ````"
end

it "sanitizes the text without touching the code fence" do
expect(sanitize_links_and_mentions).to eq(
"Take a look at this code: ```` @not-a-mention "\
"```@not-a-mention``` ````"
)
end

context "and a real mention after" do
let(:text) do
"Take a look at this code: ```` @not-a-mention "\
"```@not-a-mention``` ```` This is a @mention!"
end

it "sanitizes the text without touching the code fence" do
expect(sanitize_links_and_mentions).to eq(
"Take a look at this code: ```` @not-a-mention "\
"```@not-a-mention``` ```` "\
"This is a [@&#8203;mention](https://github.com/mention)!"
)
end
end
end

context "with mixed syntax code blocks" do
let(:text) { "```@command ```\n~~~ @test~~~ @feelepxyz" }

Expand All @@ -132,11 +161,11 @@
end

context "that is formatted suprisingly" do
let(:text) { "```````\nThis is an @mention!" }
let(:text) { "```````\nThis is a @mention!" }

it "sanitizes the mention" do
expect(sanitize_links_and_mentions).to eq(
"```````\nThis is an [@&#8203;mention](https://github.com/mention)!"
"```````\nThis is a [@&#8203;mention](https://github.com/mention)!"
)
end
end
Expand Down

0 comments on commit 5b20bfc

Please sign in to comment.