Fix Qt 5.11 issues with clicking invalid links

See #3661
This commit is contained in:
Florian Bruhin 2018-06-06 23:08:14 +02:00
parent eb6478dd3e
commit 3d53d0d2c5
3 changed files with 31 additions and 3 deletions

View File

@ -33,7 +33,8 @@ from PyQt5.QtGui import QMouseEvent
from qutebrowser.config import config from qutebrowser.config import config
from qutebrowser.keyinput import modeman from qutebrowser.keyinput import modeman
from qutebrowser.mainwindow import mainwindow from qutebrowser.mainwindow import mainwindow
from qutebrowser.utils import log, usertypes, utils, qtutils, objreg from qutebrowser.utils import (log, usertypes, utils, qtutils, objreg,
urlutils, message)
Group = enum.Enum('Group', ['all', 'links', 'images', 'url', 'inputs']) Group = enum.Enum('Group', ['all', 'links', 'images', 'url', 'inputs'])
@ -275,11 +276,13 @@ class AbstractWebElement(collections.abc.MutableMapping):
"""Remove target from link.""" """Remove target from link."""
raise NotImplementedError raise NotImplementedError
def resolve_url(self, baseurl): def resolve_url(self, baseurl, *, return_invalid=False):
"""Resolve the URL in the element's src/href attribute. """Resolve the URL in the element's src/href attribute.
Args: Args:
baseurl: The URL to base relative URLs on as QUrl. baseurl: The URL to base relative URLs on as QUrl.
return_invalid: Whether to return an invalid QUrl.
If False, None is returned for invalid URLs.
Return: Return:
A QUrl with the absolute URL, or None. A QUrl with the absolute URL, or None.
@ -296,7 +299,7 @@ class AbstractWebElement(collections.abc.MutableMapping):
url = QUrl(text) url = QUrl(text)
if not url.isValid(): if not url.isValid():
return None return url if return_invalid else None
if url.isRelative(): if url.isRelative():
url = baseurl.resolved(url) url = baseurl.resolved(url)
qtutils.ensure_valid(url) qtutils.ensure_valid(url)
@ -404,6 +407,15 @@ class AbstractWebElement(collections.abc.MutableMapping):
self._click_fake_event(click_target) self._click_fake_event(click_target)
return return
if qtutils.version_check('5.11', compiled=False):
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-63378
baseurl = self._tab.url()
url = self.resolve_url(baseurl, return_invalid=True)
if url is not None and not url.isValid():
msg = urlutils.get_errstring(url, "Invalid link clicked")
message.error(msg)
return
if click_target == usertypes.ClickTarget.normal: if click_target == usertypes.ClickTarget.normal:
if self.is_link(): if self.is_link():
log.webelem.debug("Clicking via JS click()") log.webelem.debug("Clicking via JS click()")

View File

@ -342,6 +342,11 @@ class WebEnginePage(QWebEnginePage):
navigation_type=type_map[typ], navigation_type=type_map[typ],
is_main_frame=is_main_frame) is_main_frame=is_main_frame)
self.navigation_request.emit(navigation) self.navigation_request.emit(navigation)
if not url.isValid() and qtutils.version_check('5.11', compiled=False):
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-63378
return True
return navigation.accepted return navigation.accepted
@pyqtSlot('QUrl') @pyqtSlot('QUrl')

View File

@ -872,3 +872,14 @@ def test_resolve_url_relative_base():
elem = get_webelem(attributes={'href': 'foo'}) elem = get_webelem(attributes={'href': 'foo'})
with pytest.raises(ValueError): with pytest.raises(ValueError):
elem.resolve_url(QUrl('base')) elem.resolve_url(QUrl('base'))
@pytest.mark.parametrize('return_invalid', [True, False])
def test_resolve_url_invalid(return_invalid):
elem = get_webelem(attributes={'href': 'what://::'})
baseurl = QUrl('http://www.example.com/')
resolved = elem.resolve_url(baseurl, return_invalid=return_invalid)
if return_invalid:
assert not resolved.isValid()
else:
assert resolved is None