From 1096dcd6022b4b03e178b5ea3fde8d588f3c7f4c Mon Sep 17 00:00:00 2001
From: Sam <sam.saffron@gmail.com>
Date: Thu, 20 Jul 2017 13:02:31 -0400
Subject: [PATCH] correct bbcode parsing edge case

---
 .../discourse-markdown/bbcode-block.js.es6    | 20 +++++++++----------
 .../discourse-markdown/bbcode-inline.js.es6   |  1 -
 spec/components/pretty_text_spec.rb           |  6 ++++++
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/app/assets/javascripts/pretty-text/engines/discourse-markdown/bbcode-block.js.es6 b/app/assets/javascripts/pretty-text/engines/discourse-markdown/bbcode-block.js.es6
index 6ee272b295a..1f12a4a1e63 100644
--- a/app/assets/javascripts/pretty-text/engines/discourse-markdown/bbcode-block.js.es6
+++ b/app/assets/javascripts/pretty-text/engines/discourse-markdown/bbcode-block.js.es6
@@ -11,7 +11,7 @@ function trailingSpaceOnly(src, start, max) {
   return true;
 }
 
-const ATTR_REGEX = /(([a-z0-9]*)\s*=)/ig;
+const ATTR_REGEX = /((([a-z0-9]*)\s*)=)(["'].*["']|\S+)/ig;
 
 // parse a tag [test a=1 b=2] to a data structure
 // {tag: "test", attrs={a: "1", b: "2"}
@@ -76,20 +76,18 @@ export function parseBBCodeTag(src, start, max, multiline) {
       let match, key, val;
 
       while(match = ATTR_REGEX.exec(raw)) {
-        if (key) {
-          val = raw.slice(attrs[key],match.index) || '';
+        key = match[3];
+        if (key === '') {
+          key = '_default';
+        }
+
+        val = match[4];
+
+        if (val) {
           val = val.trim();
           val = val.replace(/^["'](.*)["']$/, '$1');
           attrs[key] = val;
         }
-        key = match[2] || '_default';
-        attrs[key] = match.index + match[0].length;
-      }
-
-      if (key) {
-        val = raw.slice(attrs[key]);
-        val = val.replace(/^["'](.*)["']$/, '$1');
-        attrs[key] = val;
       }
     }
 
diff --git a/app/assets/javascripts/pretty-text/engines/discourse-markdown/bbcode-inline.js.es6 b/app/assets/javascripts/pretty-text/engines/discourse-markdown/bbcode-inline.js.es6
index f302fd3f257..e508509298c 100644
--- a/app/assets/javascripts/pretty-text/engines/discourse-markdown/bbcode-inline.js.es6
+++ b/app/assets/javascripts/pretty-text/engines/discourse-markdown/bbcode-inline.js.es6
@@ -167,7 +167,6 @@ export function setup(helper) {
     ruler.push('url', {
       tag: 'url',
       wrap: function(startToken, endToken, tagInfo, content) {
-
         const url = (tagInfo.attrs['_default'] || content).trim();
 
         if (simpleUrlRegex.test(url)) {
diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb
index 2ba1d727713..6701e742afb 100644
--- a/spec/components/pretty_text_spec.rb
+++ b/spec/components/pretty_text_spec.rb
@@ -879,6 +879,12 @@ HTML
     expect(cooked).to eq(html)
   end
 
+  it "supports query params in bbcode url" do
+    cooked = PrettyText.cook("[url=https://www.amazon.com/Camcorder-Hausbell-302S-Control-Infrared/dp/B01KLOA1PI/?tag=discourse]BBcode link[/url]")
+    html = '<p><a href="https://www.amazon.com/Camcorder-Hausbell-302S-Control-Infrared/dp/B01KLOA1PI/?tag=discourse" data-bbcode="true" rel="nofollow noopener">BBcode link</a></p>'
+    expect(cooked).to eq(html)
+  end
+
   it "supports inline code bbcode" do
     cooked = PrettyText.cook "Testing [code]codified **stuff** and `more` stuff[/code]"
     html = "<p>Testing <code>codified **stuff** and `more` stuff</code></p>"