From 54107031fe8cdfb5d7ac0229016af95818b8adf0 Mon Sep 17 00:00:00 2001
From: Naveen M K <naveen521kk@gmail.com>
Date: Mon, 7 Jun 2021 23:42:01 +0530
Subject: [PATCH] runscript: always quote args

Signed-off-by: Naveen M K <naveen521kk@gmail.com>
---
 .../texlive/w64_mingw_wrapper/runscript_dll.c | 43 +++++++++++++++----
 1 file changed, 34 insertions(+), 9 deletions(-)

diff --git a/texk/texlive/w64_mingw_wrapper/runscript_dll.c b/texk/texlive/w64_mingw_wrapper/runscript_dll.c
index 588c84b9..395990a1 100644
--- a/texk/texlive/w64_mingw_wrapper/runscript_dll.c
+++ b/texk/texlive/w64_mingw_wrapper/runscript_dll.c
@@ -22,13 +22,44 @@ char subsys_mode[] = "CUI_MODE\n";
 char err_env_var[] = "RUNSCRIPT_ERROR_MESSAGE";
 char msg_buf[MAX_MSG];
 
+char *quote(char *data) {
+    int i, ln = strlen(data), nb;
+
+    /* We allocate twice as much space as needed to deal with worse-case
+       of having to escape everything. */
+    char *result = calloc(ln*2+3, sizeof(char));
+    char *presult = result;
+
+    *presult++ = '"';
+    for (nb=0, i=0; i < ln; i++)
+      {
+        if (data[i] == '\\')
+          nb += 1;
+        else if (data[i] == '"')
+          {
+            for (; nb > 0; nb--)
+              *presult++ = '\\';
+            *presult++ = '\\';
+          }
+        else
+          nb = 0;
+        *presult++ = data[i];
+      }
+
+    for (; nb > 0; nb--)        /* Deal w trailing slashes */
+      *presult++ = '\\';
+
+    *presult++ = '"';
+    *presult++ = 0;
+    return result;
+}
+
 
 __declspec(dllexport) int dllrunscript( int argc, char *argv[] ) 
 {
   static char own_path[MAX_PATH];
   static char fpath[MAX_PATH];
   char *fname, *argline, **lua_argv;
-  char *quoted_argline;
   int k, quoted, lua_argc;
   HMODULE module_handle = NULL;
 
@@ -56,24 +87,20 @@ __declspec(dllexport) int dllrunscript( int argc, char *argv[] )
   argline = GetCommandLine();
 
   if ( argline == NULL ) DIE("failed to retrieve command line string\n");
-  quoted_argline = malloc((1+strlen(argline)+1 + 1)*sizeof(char));
-  if ( quoted_argline == NULL ) DIE("failed to quote command line string\n");
   // skip over argv[0] (it can contain embedded double quotes if launched from cmd.exe!)
   for ( quoted = 0; (*argline) && ( !IS_WHITESPACE(*argline) || quoted ); argline++ )
     if ( *argline == '"' ) quoted = !quoted;
   while ( IS_WHITESPACE(*argline) ) argline++; // remove leading whitespace if any
-  // we need to quote our string , it seems.
-  snprintf(quoted_argline, (size_t)(1+strlen(argline)+1 + 1), "\"%s\"", argline); 
 
   // set up argument list for texlua script
   lua_argv = (char **)malloc( (argc + 6) * sizeof(char *) );
   lua_argv[lua_argc=0] = texlua_name;
   lua_argv[++lua_argc] = fpath; // script to execute
-  for ( k = 1; k < argc; k++ ) lua_argv[++lua_argc] = argv[k]; // copy argument list
+  for ( k = 1; k < argc; k++ ) lua_argv[++lua_argc] = quote(argv[k]); // copy argument list
   lua_argv[++lua_argc] = subsys_mode; // sentinel argument
   lua_argv[++lua_argc] = argc ? argv[0] : own_path; // original argv[0]
   //lua_argv[++lua_argc] = argline; // unparsed arguments
-  lua_argv[++lua_argc] = quoted_argline; // unparsed arguments
+  lua_argv[++lua_argc] = quote(argline); // unparsed arguments
   lua_argv[++lua_argc] = NULL;
 
   // call texlua interpreter
@@ -123,5 +150,3 @@ __declspec(dllexport) int dllwrunscript(
   return dllrunscript( 0, NULL );
 #endif
 }
-
-
-- 
2.31.1.windows.1

