diff --git a/gns3server/compute/dynamips/nodes/router.py b/gns3server/compute/dynamips/nodes/router.py index e97a33ba..c82bcfd9 100644 --- a/gns3server/compute/dynamips/nodes/router.py +++ b/gns3server/compute/dynamips/nodes/router.py @@ -806,7 +806,7 @@ class Router(BaseNode): """ await self._hypervisor.send('vm set_ghost_file "{name}" {ghost_file}'.format(name=self._name, - ghost_file=shlex.quote(ghost_file))) + ghost_file=shlex.quote(ghost_file))) log.info('Router "{name}" [{id}]: ghost file set to {ghost_file}'.format(name=self._name, id=self._id, diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py index 52a979e3..87d4b9ab 100644 --- a/gns3server/compute/qemu/qemu_vm.py +++ b/gns3server/compute/qemu/qemu_vm.py @@ -25,7 +25,6 @@ import os import re import math import shutil -import shlex import asyncio import socket import gns3server @@ -33,7 +32,7 @@ import subprocess import time import json -from gns3server.utils import parse_version +from gns3server.utils import parse_version, shlex_quote from gns3server.utils.asyncio import subprocess_check_output, cancellable_wait_run_in_executor from .qemu_error import QemuError from .utils.qcow2 import Qcow2, Qcow2Error @@ -969,7 +968,7 @@ class QemuVM(BaseNode): self.check_available_ram(self.ram) command = await self._build_command() - command_string = " ".join(shlex.quote(s) for s in command) + command_string = " ".join(shlex_quote(s) for s in command) try: log.info("Starting QEMU with: {}".format(command_string)) self._stdout_file = os.path.join(self.working_dir, "qemu.log") @@ -1566,7 +1565,7 @@ class QemuVM(BaseNode): self._qemu_img_stdout_file = os.path.join(self.working_dir, "qemu-img.log") log.info("logging to {}".format(self._qemu_img_stdout_file)) - command_string = " ".join(shlex.quote(s) for s in command) + command_string = " ".join(shlex_quote(s) for s in command) log.info("Executing qemu-img with: {}".format(command_string)) with open(self._qemu_img_stdout_file, "w", encoding="utf-8") as fd: process = await asyncio.create_subprocess_exec(*command, stdout=fd, stderr=subprocess.STDOUT, cwd=self.working_dir) diff --git a/gns3server/compute/vmware/__init__.py b/gns3server/compute/vmware/__init__.py index ce8845e7..59357490 100644 --- a/gns3server/compute/vmware/__init__.py +++ b/gns3server/compute/vmware/__init__.py @@ -27,12 +27,11 @@ import asyncio import subprocess import logging import codecs -import shlex from collections import OrderedDict from gns3server.utils.interfaces import interfaces from gns3server.utils.asyncio import subprocess_check_output -from gns3server.utils import parse_version +from gns3server.utils import parse_version, shlex_quote log = logging.getLogger(__name__) @@ -387,7 +386,7 @@ class VMware(BaseManager): command = [vmrun_path, "-T", self.host_type, subcommand] command.extend(args) - command_string = " ".join([shlex.quote(c) for c in command]) + command_string = " ".join([shlex_quote(c) for c in command]) log.log(log_level, "Executing vmrun with command: {}".format(command_string)) try: process = await asyncio.create_subprocess_exec(*command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) diff --git a/gns3server/utils/__init__.py b/gns3server/utils/__init__.py index 06b56d0d..7aabbcd0 100644 --- a/gns3server/utils/__init__.py +++ b/gns3server/utils/__init__.py @@ -16,7 +16,9 @@ # along with this program. If not, see . +import sys import re +import shlex import textwrap import posixpath @@ -87,3 +89,14 @@ def parse_version(version): version.append("000000") version.append("final") return tuple(version) + + +def shlex_quote(s): + """ + Compatible shlex_quote to handle case where Windows needs double quotes around file names, not single quotes. + """ + + if sys.platform.startswith("win"): + return s if re.match(r'^[-_\w./]+$', s) else '"%s"' % s.replace('"', '\\"') + else: + return shlex.quote(s)