[latex3-commits] [git/LaTeX3-latex3-l3build] spaces: Consistently normalize and escape paths before passing them to the shell (a1e920c)

Marcel Fabian Krüger tex at 2krueger.de
Wed Sep 14 19:12:39 CEST 2022


Repository : https://github.com/latex3/l3build
On branch  : spaces
Link       : https://github.com/latex3/l3build/commit/a1e920cebb4e3fbc9792c9a36c54ed543182f3e6

>---------------------------------------------------------------

commit a1e920cebb4e3fbc9792c9a36c54ed543182f3e6
Author: Marcel Fabian Krüger <tex at 2krueger.de>
Date:   Tue Apr 19 18:49:37 2022 +0200

    Consistently normalize and escape paths before passing them to the shell


>---------------------------------------------------------------

a1e920cebb4e3fbc9792c9a36c54ed543182f3e6
 l3build-aux.lua            |  8 ++++----
 l3build-check.lua          | 28 +++++++++++++++++-----------
 l3build-file-functions.lua | 28 ++++++++++++++++------------
 l3build-typesetting.lua    | 26 +++++++++++++-------------
 4 files changed, 50 insertions(+), 40 deletions(-)

diff --git a/l3build-aux.lua b/l3build-aux.lua
index 2f6902a..070a909 100644
--- a/l3build-aux.lua
+++ b/l3build-aux.lua
@@ -121,12 +121,12 @@ function call(modules, target, opts)
           end
         end
       end
-      cli_opts = cli_opts .. " --" .. k .. value
+      cli_opts = cli_opts .. " " .. escape_arg("--" .. k .. value)
     end
   end
   if opts.names then
     for _, name in pairs(opts.names) do
-      cli_opts = cli_opts .. " " .. name
+      cli_opts = cli_opts .. " " .. escape_arg(name)
     end
   end
   local script_name = get_script_name()
@@ -140,7 +140,7 @@ function call(modules, target, opts)
     print("Running l3build with target \"" .. target .. "\"" .. text )
     local error_level = run(
       module,
-      "texlua " .. script_name .. " " .. target .. cli_opts
+      "texlua " .. escape_arg(script_name) .. " " .. escape_arg(target) .. cli_opts
     )
     if error_level ~= 0 then
       return error_level
@@ -159,7 +159,7 @@ function dep_install(deps)
   local error_level
   for _, dep in ipairs(deps) do
     print("Installing dependency: " .. dep)
-    error_level = run(dep, "texlua " .. get_script_name() .. " unpack -q")
+    error_level = run(dep, "texlua " .. escape_arg(get_script_name()) .. " unpack -q")
     if error_level ~= 0 then
       return error_level
     end
diff --git a/l3build-check.lua b/l3build-check.lua
index 7b3191a..346f5e9 100644
--- a/l3build-check.lua
+++ b/l3build-check.lua
@@ -81,7 +81,7 @@ function checkinit()
   for _,i in ipairs(checksuppfiles) do
     cp(i, supportdir, testdir)
   end
-  execute(os_ascii .. ">" .. testdir .. "/ascii.tcx")
+  execute(os_ascii .. ">" .. normalize_and_escape(testdir .. "/ascii.tcx"))
   return checkinit_hook()
 end
 
@@ -678,7 +678,8 @@ function base_compare(test_type,name,engine,cleanup)
     return compare(difffile, reffile, genfile, cleanup, name, engine)
   end
   local errorlevel = execute(os_diffexe .. " "
-    .. normalize_path(reffile .. " " .. genfile .. " > " .. difffile))
+    .. normalize_and_escape(reffile) .. " " .. normalize_and_escape(genfile)
+    .. " > " .. normalize_and_escape(difffile))
   if errorlevel == 0 or cleanup then
     remove(difffile)
   end
@@ -701,15 +702,19 @@ function compare_tlg(difffile, tlgfile, logfile, cleanup, name, engine)
     local luatlgfile = testdir .. "/" .. testname .. tlgext
     rewrite(tlgfile,luatlgfile,normalize_lua_log)
     rewrite(logfile,lualogfile,normalize_lua_log,true)
-    errorlevel = execute(os_diffexe .. " "
-      .. normalize_path(luatlgfile .. " " .. lualogfile .. " > " .. difffile))
+    errorlevel = execute(os_diffexe
+      .. " " .. normalize_and_escape(luatlgfile)
+      .. " " .. normalize_and_escape(lualogfile)
+      .. " > " .. normalize_and_escape(difffile))
     if cleanup then
       remove(lualogfile)
       remove(luatlgfile)
     end
   else
-    errorlevel = execute(os_diffexe .. " "
-      .. normalize_path(tlgfile .. " " .. logfile .. " > " .. difffile))
+    errorlevel = execute(os_diffexe
+      .. " " .. normalize_and_escape(tlgfile)
+      .. " " .. normalize_and_escape(logfile)
+      .. " > " .. normalize_and_escape(difffile))
   end
   if errorlevel == 0 or cleanup then
     remove(difffile)
@@ -736,7 +741,7 @@ function runtest(name, engine, hide, ext, test_type, breakout)
       binary    = engine_info.binary  or binary
       format    = engine_info.format  or format
       checkopts = engine_info.options or checkopts
-      tokens    = engine_info.tokens and (' "' .. engine_info.tokens .. '" ')
+      tokens    = engine_info.tokens and (' ' .. escape_arg(engine_info.tokens))
                     or tokens
     end
   end
@@ -753,10 +758,10 @@ function runtest(name, engine, hide, ext, test_type, breakout)
     return " -jobname=" .. name .. tokens .. ' "\\input ' .. file .. '" '
   end
   if match(checkformat,"^context$") then
-    function setup(file) return tokens .. ' "' .. file .. '" '  end
+    function setup(file) return tokens .. ' ' .. escape_arg(file) .. ' '  end
   end
   if match(binary,"make4ht") then
-    function setup(file) return tokens .. ' "' .. file .. '" '  end
+    function setup(file) return tokens .. ' "' .. escape_arg(file) .. '" '  end
     format = ""
     checkopts = ""
   end
@@ -778,14 +783,15 @@ function runtest(name, engine, hide, ext, test_type, breakout)
   rmfile(testdir,name .. logext)
   local errlevels = {}
   for i = 1, checkruns do
+    -- FIXME
     errlevels[i] = run(
       testdir,
       -- No use of localdir here as the files get copied to testdir:
       -- avoids any paths in the logs
-      os_setenv .. " TEXINPUTS=." .. localtexmf()
+      os_setenv .. " TEXINPUTS=." .. escape_arg(localtexmf())
         .. (checksearch and os_pathsep or "")
         .. os_concat ..
-      os_setenv .. " LUAINPUTS=." .. localtexmf()
+      os_setenv .. " LUAINPUTS=." .. escape_arg(localtexmf())
         .. (checksearch and os_pathsep or "")
         .. os_concat ..
       -- Avoid spurious output from (u)pTeX
diff --git a/l3build-file-functions.lua b/l3build-file-functions.lua
index 17f0bd8..acec2b0 100644
--- a/l3build-file-functions.lua
+++ b/l3build-file-functions.lua
@@ -183,7 +183,7 @@ function abspath(path)
 end
 
 -- TODO: Fix the cross platform problem
-function escapepath(path)
+function escape_arg(path)
   if os_type == "windows" then
     local path,count = gsub(path,'"','')
     if count % 2 ~= 0 then
@@ -202,6 +202,10 @@ function escapepath(path)
   end
 end
 
+function normalize_and_escape(path)
+  return escape_arg(normalize_path(path))
+end
+
 -- For cleaning out a directory, which also ensures that it exists
 function cleandir(dir)
   local errorlevel = mkdir(dir)
@@ -234,13 +238,13 @@ function cp(glob, source, dest)
     if os_type == "windows" then
       if direxists(p.cwd) then
         errorlevel = execute(
-          'xcopy /y /e /i "' .. unix_to_win(p.cwd) .. '" '
-             .. unix_to_win(dest .. '/' .. escapepath(p.src)) .. ' > nul'
+          'xcopy /y /e /i ' .. normalize_and_escape(p.cwd) .. ' '
+             .. normalize_and_escape(dest .. '/' .. p.src) .. ' > nul'
         ) and 0 or 1
       else
         errorlevel = execute(
-          'xcopy /y "' .. unix_to_win(p.cwd) .. '" '
-             .. unix_to_win(dest .. '/') .. ' > nul'
+          'xcopy /y ' .. normalize_and_escape(p.cwd) .. ' '
+             .. normalize_and_escape(dest .. '/') .. ' > nul'
         ) and 0 or 1
       end
     else
@@ -250,7 +254,7 @@ function cp(glob, source, dest)
         if errorlevel ~=0 then return errorlevel end
       end
       errorlevel = execute(
-        "cp -RLf '" .. p.cwd .. "' " .. dest
+        "cp -RLf " .. normalize_and_escape(p.cwd) .. " " .. normalize_and_escape(dest)
       ) and 0 or 1
     end
     if errorlevel ~=0 then
@@ -372,7 +376,7 @@ function remove_duplicates(a)
 end
 
 function mkdir(dir)
-  dir = escapepath(dir)
+  dir = normalize_and_escape(dir)
   if os_type == "windows" then
     -- Windows (with the extensions) will automatically make directory trees
     -- but issues a warning if the dir already exists: avoid by including a test
@@ -391,9 +395,9 @@ function ren(dir, source, dest)
   if os_type == "windows" then
     source = gsub(source, "^%.+/", "")
     dest = gsub(dest, "^%.+/", "")
-    return execute("ren " .. unix_to_win(dir) .. source .. " " .. dest)
+    return execute("ren " .. normalize_and_escape(dir .. source) .. ' ' .. normalize_and_escape(dest))
   else
-    return execute("mv " .. dir .. source .. " " .. dir .. dest)
+    return execute("mv " .. normalize_and_escape(dir .. source) .. ' ' .. normalize_and_escape(dir .. dest))
   end
 end
 
@@ -418,15 +422,15 @@ function rmdir(dir)
   -- First, make sure it exists to avoid any errors
   mkdir(dir)
   if os_type == "windows" then
-    return execute("rmdir /s /q " .. unix_to_win(dir))
+    return execute("rmdir /s /q " .. normalize_and_escape(dir))
   else
-    return execute("rm -r " .. dir)
+    return execute("rm -r " .. normalize_and_escape(dir))
   end
 end
 
 -- Run a command in a given directory
 function run(dir, cmd)
-  return execute("cd " .. dir .. os_concat .. cmd)
+  return execute("cd " .. normalize_and_escape(dir) .. os_concat .. cmd)
 end
 
 -- Split a path into file and directory component
diff --git a/l3build-typesetting.lua b/l3build-typesetting.lua
index c173b25..917f6f3 100644
--- a/l3build-typesetting.lua
+++ b/l3build-typesetting.lua
@@ -39,10 +39,10 @@ function dvitopdf(name, dir, engine, hide)
   run(
     dir,
     set_epoch_cmd(epoch, forcecheckepoch) ..
-    "dvips " .. name .. dviext
+    "dvips " .. normalize_and_escape(name .. dviext)
       .. (hide and (" > " .. os_null) or "")
       .. os_concat ..
-    "ps2pdf " .. ps2pdfopt .. name .. psext
+    "ps2pdf " .. ps2pdfopt .. normalize_and_escape(name .. psext)
       .. (hide and (" > " .. os_null) or "")
   )
 end
@@ -70,7 +70,7 @@ end
 function biber(name,dir)
   if fileexists(dir .. "/" .. name .. ".bcf") then
     return
-      runcmd(biberexe .. " " .. biberopts .. " " .. name,dir,{"BIBINPUTS"})
+      runcmd(biberexe .. " " .. biberopts .. " " .. normalize_and_escape(name),dir,{"BIBINPUTS"})
   end
   return 0
 end
@@ -82,18 +82,18 @@ function bibtex(name,dir)
     -- look inside it for a \citation line
     local grep
     if os_type == "windows" then
-      grep = "\\\\"
+      grep = [[\\]]
     else
-     grep = "\\\\\\\\"
+     grep = [[\\\\]]
     end
     if run(dir,
-        os_grepexe .. " \"^" .. grep .. "citation{\" " .. name .. ".aux > "
-          .. os_null
+        os_grepexe .. " \"^" .. grep .. "citation{\" " .. normalize_and_escape(name .. ".aux")
+          .. " > " .. os_null
       ) + run(dir,
-        os_grepexe .. " \"^" .. grep .. "bibdata{\" " .. name .. ".aux > "
-          .. os_null
+        os_grepexe .. " \"^" .. grep .. "bibdata{\" " .. normalize_and_escape(name .. ".aux")
+          .. " > " .. os_null
       ) == 0 then
-      return runcmd(bibtexexe .. " " .. bibtexopts .. " " .. name,dir,
+      return runcmd(bibtexexe .. " " .. bibtexopts .. " " .. normalize_and_escape(name),dir,
         {"BIBINPUTS","BSTINPUTS"})
     end
   end
@@ -105,9 +105,9 @@ function makeindex(name,dir,inext,outext,logext,style)
   if fileexists(dir .. "/" .. name .. inext) then
     if style == "" then style = nil end
     return runcmd(makeindexexe .. " " .. makeindexopts
-      .. " -o " .. name .. outext
-      .. (style and (" -s " .. style) or "")
-      .. " -t " .. name .. logext .. " "  .. name .. inext,
+      .. " -o " .. normalize_and_escape(name .. outext)
+      .. (style and (" -s " .. escape_arg(style)) or "")
+      .. " -t " .. normalize_and_escape(name .. logext) .. " "  .. normalize_and_escape(name .. inext),
       dir,
       {"INDEXSTYLE"})
   end





More information about the latex3-commits mailing list.