also add path transformations to :download

This commit is contained in:
Daniel Schadt 2017-03-24 12:30:29 +01:00
parent 07b3a7db7c
commit df83f7aa99
4 changed files with 36 additions and 22 deletions

View File

@ -1334,6 +1334,9 @@ class CommandDispatcher:
scope='window', window=self._win_id) scope='window', window=self._win_id)
target = None target = None
if dest is not None: if dest is not None:
dest = downloads.transform_path(dest)
if dest is None:
raise cmdexc.CommandError("Invalid target filename")
target = downloads.FileDownloadTarget(dest) target = downloads.FileDownloadTarget(dest)
tab = self._current_widget() tab = self._current_widget()

View File

@ -19,11 +19,13 @@
"""Shared QtWebKit/QtWebEngine code for downloads.""" """Shared QtWebKit/QtWebEngine code for downloads."""
import re
import sys import sys
import html import html
import os.path import os.path
import collections import collections
import functools import functools
import pathlib
import tempfile import tempfile
import sip import sip
@ -161,6 +163,25 @@ def get_filename_question(*, suggested_filename, url, parent=None):
return q return q
def transform_path(path):
r"""Do platform-specific transformations, like changing E: to E:\.
Returns None if the path is invalid on the current platform.
"""
if sys.platform != "win32":
return path
path = utils.expand_windows_drive(path)
# Drive dependent working directories are not supported, e.g.
# E:filename is invalid
if re.match(r'[A-Z]:[^\\]', path, re.IGNORECASE):
return None
# Paths like COM1, ...
# See https://github.com/qutebrowser/qutebrowser/issues/82
if pathlib.Path(path).is_reserved():
return None
return path
class NoFilenameError(Exception): class NoFilenameError(Exception):
"""Raised when we can't find out a filename in DownloadTarget.""" """Raised when we can't find out a filename in DownloadTarget."""

View File

@ -19,11 +19,9 @@
"""Showing prompts above the statusbar.""" """Showing prompts above the statusbar."""
import re
import sys import sys
import os.path import os.path
import html import html
import pathlib
import collections import collections
import sip import sip
@ -646,31 +644,13 @@ class FilenamePrompt(_BasePrompt):
self._file_model.directoryLoaded.connect( self._file_model.directoryLoaded.connect(
lambda: self._file_model.sort(0)) lambda: self._file_model.sort(0))
def _transform_path(self, path):
r"""Do platform-specific transformations, like changing E: to E:\.
Returns None if the path is invalid on the current platform.
"""
if sys.platform != "win32":
return path
path = utils.expand_windows_drive(path)
# Drive dependent working directories are not supported, e.g.
# E:filename is invalid
if re.match(r'[A-Z]:[^\\]', path, re.IGNORECASE):
return None
# Paths like COM1, ...
# See https://github.com/qutebrowser/qutebrowser/issues/82
if pathlib.Path(path).is_reserved():
return None
return path
def _show_error(self, msg): def _show_error(self, msg):
log.prompt.error(msg) log.prompt.error(msg)
QToolTip.showText(self._lineedit.mapToGlobal(QPoint(0, 0)), msg) QToolTip.showText(self._lineedit.mapToGlobal(QPoint(0, 0)), msg)
def accept(self, value=None): def accept(self, value=None):
text = value if value is not None else self._lineedit.text() text = value if value is not None else self._lineedit.text()
text = self._transform_path(text) text = downloads.transform_path(text)
if text is None: if text is None:
self._show_error("Invalid filename") self._show_error("Invalid filename")
return False return False
@ -725,7 +705,7 @@ class DownloadFilenamePrompt(FilenamePrompt):
def accept(self, value=None): def accept(self, value=None):
text = value if value is not None else self._lineedit.text() text = value if value is not None else self._lineedit.text()
text = self._transform_path(text) text = downloads.transform_path(text)
if text is None: if text is None:
self._show_error("Invalid filename") self._show_error("Invalid filename")
return False return False

View File

@ -140,6 +140,16 @@ Feature: Downloading things from a website.
And I run :prompt-cancel And I run :prompt-cancel
Then "Invalid filename" should be logged Then "Invalid filename" should be logged
@windows
Scenario: Downloading a file to a reserved path with :download
When I run :download data/downloads/download.bin --dest=COM1
Then the error "Invalid target filename" should be shown
@windows
Scenario: Download a file to a drive-relative working directory with :download
When I run :download data/downloads/download.bin --dest=C:foobar
Then the error "Invalid target filename" should be shown
## :download-retry ## :download-retry
Scenario: Retrying a failed download Scenario: Retrying a failed download