Be more forgiving when validating URLs. Fixes #141.

This commit is contained in:
Florian Bruhin 2014-10-03 16:58:30 +02:00
parent 18ff6ea06a
commit 4dcaa1fdec
8 changed files with 37 additions and 19 deletions

View File

@ -421,7 +421,8 @@ displaying it to the user.
* Mention in the docstring whether your function needs a URL string or a
`QUrl`.
* Call `ensure_valid` from `utils.qtutils` whenever getting or creating a
`QUrl` and take appropriate action if not.
`QUrl` and take appropriate action if not. Note the URL of the current page
always could be an invalid QUrl (if nothing is loaded yet).
Style conventions

View File

@ -92,6 +92,11 @@ class CommandDispatcher:
tab: Whether to open in a new tab.
background: Whether to open in the background.
"""
if not url.isValid():
errstr = "Invalid URL {}"
if url.errorString():
errstr += " - {}".format(url.errorString())
raise cmdexc.CommandError(errstr)
tabbed_browser = objreg.get('tabbed-browser')
if tab and background:
raise cmdexc.CommandError("Only one of -t/-b can be given!")
@ -715,9 +720,6 @@ class CommandDispatcher:
"""
urlstr = quickmarks.get(name)
url = QUrl(urlstr)
if not url.isValid():
raise cmdexc.CommandError("Invalid URL {} ({})".format(
urlstr, url.errorString()))
self._open(url, tab, bg)
@cmdutils.register(instance='command-dispatcher', name='inspector')

View File

@ -359,7 +359,9 @@ class DownloadManager(QObject):
url: The URL to get, as QUrl
page: The QWebPage to get the download from.
"""
qtutils.ensure_valid(url)
if not url.isValid():
urlutils.invalid_url_error(url, "start download")
return
req = QNetworkRequest(url)
reply = page.networkAccessManager().get(req)
self.fetch(reply)

View File

@ -327,7 +327,6 @@ class HintManager(QObject):
Args:
url: The URL to open as a QURL.
"""
qtutils.ensure_valid(url)
sel = self._context.target == Target.yank_primary
mode = QClipboard.Selection if sel else QClipboard.Clipboard
urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword)
@ -341,7 +340,6 @@ class HintManager(QObject):
Args:
url: The URL to open as a QUrl.
"""
qtutils.ensure_valid(url)
urlstr = url.toDisplayString(QUrl.FullyEncoded)
args = self._context.get_args(urlstr)
message.set_cmd_text(' '.join(args))
@ -357,19 +355,16 @@ class HintManager(QObject):
message.error("No suitable link found for this element.",
immediately=True)
return
qtutils.ensure_valid(url)
objreg.get('download-manager').get(url, elem.webFrame().page())
def _call_userscript(self, url):
"""Call an userscript from a hint."""
qtutils.ensure_valid(url)
cmd = self._context.args[0]
args = self._context.args[1:]
userscripts.run(cmd, *args, url=url)
def _spawn(self, url):
"""Spawn a simple command from a hint."""
qtutils.ensure_valid(url)
urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword)
args = self._context.get_args(urlstr)
subprocess.Popen(args)
@ -396,6 +391,7 @@ class HintManager(QObject):
if baseurl is None:
baseurl = self._context.baseurl
url = baseurl.resolved(url)
qtutils.ensure_valid(url)
return url
def _find_prevnext(self, frame, prev=False):
@ -511,7 +507,6 @@ class HintManager(QObject):
if url is None:
raise cmdexc.CommandError("No {} links found!".format(
"prev" if prev else "forward"))
qtutils.ensure_valid(url)
if newtab:
objreg.get('tabbed-browser').tabopen(url, background=False)
else:

View File

@ -64,7 +64,9 @@ def prompt_save(url):
Args:
url: The quickmark url as a QUrl.
"""
qtutils.ensure_valid(url)
if not url.isValid():
urlutils.invalid_url_error(url, "save quickmark")
return
urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
message.ask_async("Add quickmark:", usertypes.PromptMode.text,
functools.partial(quickmark_add, urlstr))

View File

@ -28,7 +28,7 @@ from PyQt5.QtCore import QUrl
from PyQt5.QtNetwork import QHostInfo
from qutebrowser.config import config
from qutebrowser.utils import log, qtutils
from qutebrowser.utils import log, qtutils, message
# FIXME: we probably could raise some exceptions on invalid URLs
@ -262,6 +262,17 @@ def qurl_from_user_input(urlstr):
return QUrl('http://[{}]{}'.format(ipstr, rest))
def invalid_url_error(url, action):
"""Display an error message for an URL."""
if url.isValid():
raise ValueError("Calling invalid_url_error with valid URL {}".format(
url.toDisplayString()))
errstring = "Trying to {} with invalid URL".format(action)
if url.errorString():
errstring += " - {}".format(url.errorString())
message.error(errstring)
class FuzzyUrlError(Exception):
"""Exception raised by fuzzy_url on problems."""

View File

@ -247,11 +247,13 @@ class TabbedBrowser(tabwidget.TabWidget):
self._now_focused = None
if tab is objreg.get('last-focused-tab', None):
objreg.delete('last-focused-tab')
if not tab.cur_url.isEmpty():
qtutils.ensure_valid(tab.cur_url)
if tab.cur_url.isValid():
history_data = qtutils.serialize(tab.history())
entry = UndoEntry(tab.cur_url, history_data)
self._undo_stack.append(entry)
else:
urlutils.invalid_url_error(url, "saving tab")
return
tab.shutdown()
self._tabs.remove(tab)
self.removeTab(idx)

View File

@ -335,10 +335,13 @@ class WebView(QWebView):
@pyqtSlot('QUrl')
def on_url_changed(self, url):
"""Update cur_url when URL has changed."""
qtutils.ensure_valid(url)
self.cur_url = url
self.url_text_changed.emit(url.toDisplayString())
"""Update cur_url when URL has changed.
If the URL is invalid, we just ignore it here.
"""
if url.isValid():
self.cur_url = url
self.url_text_changed.emit(url.toDisplayString())
@pyqtSlot('QMouseEvent')
def on_mouse_event(self, evt):