From 3a9021eb89899d81e2471fb6961d650d55adb824 Mon Sep 17 00:00:00 2001 From: Vincenzo Mantova Date: Sun, 7 Jan 2024 13:48:42 +0000 Subject: [PATCH] escape kpsewhich arguments on Windows --- Makefile.PL | 4 +++- lib/LaTeXML/Util/Pathname.pm | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Makefile.PL b/Makefile.PL index e34a44e40..8b3932e63 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -75,9 +75,11 @@ WriteMakefile(NAME => 'LaTeXML', 'URI' => 0, 'version' => 0, # Windows terminal handling (see Common::Error) + # Windows argument escaping (see Util::Pathname) ($^O eq 'MSWin32' ? ('Win32::Console' => 0, - 'Win32::Console::ANSI' => 0) + 'Win32::Console::ANSI' => 0, + 'Win32::ShellQuote' => 0) : ()), # If we have an "old" version of XML::LibXML, # we also need XPathContext. diff --git a/lib/LaTeXML/Util/Pathname.pm b/lib/LaTeXML/Util/Pathname.pm index 829df9606..9a2146e49 100644 --- a/lib/LaTeXML/Util/Pathname.pm +++ b/lib/LaTeXML/Util/Pathname.pm @@ -46,6 +46,13 @@ our @EXPORT = qw( &pathname_find &pathname_findall &pathname_kpsewhich &pathname_cwd &pathname_chdir &pathname_mkdir &pathname_copy &pathname_installation); +my $ISWINDOWS; + +BEGIN { + $ISWINDOWS = $^O =~ /^(MSWin|NetWare|cygwin)/i; + require Win32::ShellQuote if $ISWINDOWS; +} + # NOTE: For absolute pathnames, the directory component starts with # whatever File::Spec considers to be the volume, or "/". #====================================================================== @@ -54,7 +61,6 @@ our @EXPORT = qw( &pathname_find &pathname_findall &pathname_kpsewhich ### my $SEP = '/'; # [CONSTANT] # Some indicators that this is not sufficient? (calls to libraries/externals???) # PRELIMINARY test, probably need to be even more careful -my $ISWINDOWS = $^O =~ /^(MSWin|NetWare|cygwin)/i; my $SEP = ($ISWINDOWS ? '\\' : '/'); # [CONSTANT] my $KPATHSEP = ($ISWINDOWS ? ';' : ':'); # [CONSTANT] my $LITERAL_RE = '(?:literal)(?=:)'; # [CONSTANT] @@ -400,7 +406,12 @@ sub pathname_kpsewhich { # For multiple calls, this is slower in general. But MiKTeX, eg., doesn't use texmf ls-R files! if ($kpse_toolchain) { push(@candidates, $kpse_toolchain); } - if ($kpsewhich && open(my $resfh, '-|', $kpsewhich, @candidates)) { + if ($kpsewhich && open(my $resfh, '-|', + # on Windows, ($kpsewhich, @candidates) is joined into a single string, which most binaries + # parse with CommandLineToArgvW, so the arguments must be escaped accordingly + # WARNING: @candidates MUST NOT be empty to guarantee that Perl runs $kpsewhich directly rather + # than through a shell/cmd.exe + $ISWINDOWS ? Win32::ShellQuote::quote_system_list($kpsewhich, @candidates) : ($kpsewhich, @candidates))) { my $result = <$resfh>; # we only need the first line { local $/; <$resfh>; } # discard the rest of the output close($resfh); # ignore exit status (only one of @candidates exists, usually)