Skip to content

Commit 973a16e

Browse files
MarkusBauerMarkus Bauerhenryiii
committed
fix: escape paths with spaces in pybind11-config (#4874)
* fix: Escape paths with spaces in include list from --includes * fix: --includes should not use shlex on Windows platforms * Apply suggestions from code review * fix: use custom impl Signed-off-by: Henry Schreiner <[email protected]> * Support trailing backslashes Co-authored-by: Henry Schreiner <[email protected]> --------- Signed-off-by: Henry Schreiner <[email protected]> Co-authored-by: Markus Bauer <[email protected]> Co-authored-by: Henry Schreiner <[email protected]>
1 parent 75c1176 commit 973a16e

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

pybind11/__main__.py

+26-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,35 @@
22
from __future__ import annotations
33

44
import argparse
5+
import re
56
import sys
67
import sysconfig
78

89
from ._version import __version__
910
from .commands import get_cmake_dir, get_include, get_pkgconfig_dir
1011

12+
# This is the conditional used for os.path being posixpath
13+
if "posix" in sys.builtin_module_names:
14+
from shlex import quote
15+
elif "nt" in sys.builtin_module_names:
16+
# See https://github.com/mesonbuild/meson/blob/db22551ed9d2dd7889abea01cc1c7bba02bf1c75/mesonbuild/utils/universal.py#L1092-L1121
17+
# and the original documents:
18+
# https://docs.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments and
19+
# https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/
20+
UNSAFE = re.compile("[ \t\n\r]")
21+
22+
def quote(s: str) -> str:
23+
if s and not UNSAFE.search(s):
24+
return s
25+
26+
# Paths cannot contain a '"' on Windows, so we don't need to worry
27+
# about nuanced counting here.
28+
return f'"{s}\\"' if s.endswith("\\") else f'"{s}"'
29+
else:
30+
31+
def quote(s: str) -> str:
32+
return s
33+
1134

1235
def print_includes() -> None:
1336
dirs = [
@@ -22,7 +45,7 @@ def print_includes() -> None:
2245
if d and d not in unique_dirs:
2346
unique_dirs.append(d)
2447

25-
print(" ".join("-I" + d for d in unique_dirs))
48+
print(" ".join(quote(f"-I{d}") for d in unique_dirs))
2649

2750

2851
def main() -> None:
@@ -54,9 +77,9 @@ def main() -> None:
5477
if args.includes:
5578
print_includes()
5679
if args.cmakedir:
57-
print(get_cmake_dir())
80+
print(quote(get_cmake_dir()))
5881
if args.pkgconfigdir:
59-
print(get_pkgconfig_dir())
82+
print(quote(get_pkgconfig_dir()))
6083

6184

6285
if __name__ == "__main__":

0 commit comments

Comments
 (0)