bugdown: Force absolute urls in topic links.

If a url doesn't have a scheme, browsers would treat it as a relative
url and open something like: https://chat.zulip.org/google.com instead.

This PR fixes the issue on the backend; the frontend implementation
remains out of sync and the user sending the message wouldn't see
any linkification for urls without a scheme.

Fixes #12791.
This commit is contained in:
Rohitt Vashishtha
2019-07-19 11:16:07 +05:30
committed by Tim Abbott
parent afa251de5d
commit 726d5003e1
5 changed files with 22 additions and 3 deletions

View File

@@ -14,6 +14,7 @@ Jinja2==2.10.1
# Needed for markdown processing # Needed for markdown processing
Markdown==3.1.1 Markdown==3.1.1
Pygments==2.3.1 Pygments==2.3.1
hyperlink==19.0.0
# Needed for manage.py # Needed for manage.py
ipython==6.5.0 ipython==6.5.0

View File

@@ -73,7 +73,7 @@ httpretty==0.9.6
hypchat==0.21 hypchat==0.21
hyper==0.7.0 # via apns2 hyper==0.7.0 # via apns2
hyperframe==3.2.0 # via h2, hyper hyperframe==3.2.0 # via h2, hyper
hyperlink==19.0.0 # via twisted hyperlink==19.0.0
idna==2.8 # via hyperlink, requests idna==2.8 # via hyperlink, requests
ijson==2.3 ijson==2.3
imagesize==1.1.0 # via sphinx imagesize==1.1.0 # via sphinx

View File

@@ -55,7 +55,8 @@ httplib2==0.12.3
hypchat==0.21 hypchat==0.21
hyper==0.7.0 # via apns2 hyper==0.7.0 # via apns2
hyperframe==3.2.0 # via h2, hyper hyperframe==3.2.0 # via h2, hyper
idna==2.8 # via requests hyperlink==19.0.0
idna==2.8 # via hyperlink, requests
ijson==2.3 ijson==2.3
ipython-genutils==0.2.0 # via traitlets ipython-genutils==0.2.0 # via traitlets
ipython==6.5.0 ipython==6.5.0

View File

@@ -18,6 +18,7 @@ import ujson
import xml.etree.cElementTree as etree import xml.etree.cElementTree as etree
from xml.etree.cElementTree import Element from xml.etree.cElementTree import Element
import ahocorasick import ahocorasick
from hyperlink import parse
from collections import deque, defaultdict from collections import deque, defaultdict
@@ -2074,7 +2075,11 @@ def topic_links(realm_filters_key: int, topic_name: str) -> List[str]:
for sub_string in basic_link_splitter.split(topic_name): for sub_string in basic_link_splitter.split(topic_name):
link_match = re.match(get_web_link_regex(), sub_string) link_match = re.match(get_web_link_regex(), sub_string)
if link_match: if link_match:
matches.append(link_match.group('url')) url = link_match.group('url')
url_object = parse(url)
if not url_object.scheme:
url = url_object.replace(scheme='https').to_text()
matches.append(url)
return matches return matches

View File

@@ -832,6 +832,18 @@ class BugdownTest(ZulipTestCase):
converted_topic = bugdown.topic_links(realm.id, msg.topic_name()) converted_topic = bugdown.topic_links(realm.id, msg.topic_name())
self.assertEqual(converted_topic, [u'https://google.com/hello-world']) self.assertEqual(converted_topic, [u'https://google.com/hello-world'])
msg.set_topic_name("http://google.com/hello-world")
converted_topic = bugdown.topic_links(realm.id, msg.topic_name())
self.assertEqual(converted_topic, [u'http://google.com/hello-world'])
msg.set_topic_name("Without scheme google.com/hello-world")
converted_topic = bugdown.topic_links(realm.id, msg.topic_name())
self.assertEqual(converted_topic, [u'https://google.com/hello-world'])
msg.set_topic_name("Without scheme random.words/hello-world")
converted_topic = bugdown.topic_links(realm.id, msg.topic_name())
self.assertEqual(converted_topic, [])
msg.set_topic_name("Try out http://ftp.debian.org, https://google.com/ and https://google.in/.") msg.set_topic_name("Try out http://ftp.debian.org, https://google.com/ and https://google.in/.")
converted_topic = bugdown.topic_links(realm.id, msg.topic_name()) converted_topic = bugdown.topic_links(realm.id, msg.topic_name())
self.assertEqual(converted_topic, [u'http://ftp.debian.org', 'https://google.com/', 'https://google.in/']) self.assertEqual(converted_topic, [u'http://ftp.debian.org', 'https://google.com/', 'https://google.in/'])