Source: make-dfsg
Severity: normal

Dear Maintainer,

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=688601 was fixed back in
2014 by applying a patch (dgit:407e2fb3130d4540482a04987222dead70936122)
and this fix worked well for us for several years.

Unfortunately, this change appears to have been removed as part of:

 commit 0e957340243587eeffb525aff3200b5e143ac274
 Author: Manoj Srivastava <sriva...@debian.org>
 Date:   Mon Feb 12 16:26:34 2018 -0800

     [master]: revert debian specific patches that have been integrated 
differently upstream.

     Signed-off-by: Manoj Srivastava <sriva...@debian.org>

so this fix is no longer present in Buster, and apparently Bullseye. I've
been unable to find any other information about reverting the fix.

The main part of the original patch still applied and the conflicts in the
configure.ac file appeared to be straightforward to resolve. The resulting
patch is attached. Applying it fixed the problem for me.

-- System Information:
Debian Release: bullseye/sid
  APT prefers testing
  APT policy: (400, 'testing'), (50, 'unstable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 5.9.0-1-amd64 (SMP w/8 CPU threads)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_GB:en
Shell: /bin/sh linked to /bin/bash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
commit f079489160d620e5eb50dc09e51f09f71a7dcffb
Author: Mike Crowe <m...@mcrowe.com>
Date:   Fri Nov 6 15:22:37 2020 +0000

    Resurrect fix for large command line
    
    This patch was originally applied by Manoj Srivastava to fix Debian bug
    other changes that had apparently been fixed differently upstream. That
    turns out not to have been true for this particular fix.
    
    The original patch description follows.
    
    ---8<---
        [handle_excessive_command_length]: Patch to fix large cmmand line
    
        When presented with a very very long command line (e.g. WebKit's linking
        of libWebCore.la in current git), make fails to execute the command as
        it doesn't split the command line to fit within the limits.
    
        This patch provides a POSIX specific fix.
    --->8---

diff --git a/configure.ac b/configure.ac
index a1d41640..98dd2309 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,7 +75,7 @@ AC_HEADER_STAT
 AC_HEADER_TIME
 AC_CHECK_HEADERS([stdlib.h locale.h unistd.h limits.h fcntl.h string.h \
                   memory.h sys/param.h sys/resource.h sys/time.h sys/timeb.h \
-                  sys/select.h sys/file.h spawn.h])
+                  sys/select.h sys/file.h spawn.h sys/user.h linux/binfmts.h])
 
 AM_PROG_CC_C_O
 AC_C_CONST
diff --git a/src/job.c b/src/job.c
index ae1f18b9..3abba81a 100644
--- a/src/job.c
+++ b/src/job.c
@@ -26,6 +26,14 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "variable.h"
 #include "os.h"
 
+#if defined (HAVE_LINUX_BINFMTS_H) && defined (HAVE_SYS_USER_H)
+#include <sys/user.h>
+#include <linux/binfmts.h>
+#endif
+#ifndef PAGE_SIZE
+# define PAGE_SIZE (sysconf(_SC_PAGESIZE))
+#endif
+
 /* Default shell to use.  */
 #ifdef WINDOWS32
 # ifdef HAVE_STRINGS_H
@@ -3217,6 +3225,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
 #ifdef WINDOWS32
     char *command_ptr = NULL; /* used for batch_mode_shell mode */
 #endif
+    char *args_ptr;
 
 # ifdef __EMX__ /* is this necessary? */
     if (!unixy_shell && shellflags)
@@ -3382,8 +3391,17 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
         return new_argv;
       }
 
+#ifdef MAX_ARG_STRLEN
+    static char eval_line[] = "eval\\ \\\"set\\ x\\;\\ shift\\;\\ ";
+#define ARG_NUMBER_DIGITS 5
+#define EVAL_LEN (sizeof(eval_line)-1 + shell_len + 4                   \
+                  + (7 + ARG_NUMBER_DIGITS) * 2 * line_len / (MAX_ARG_STRLEN - 2))
+#else
+#define EVAL_LEN 0
+#endif
+
     new_line = xmalloc ((shell_len*2) + 1 + sflags_len + 1
-                        + (line_len*2) + 1);
+                        + (line_len*2) + 1 + EVAL_LEN);
     ap = new_line;
     /* Copy SHELL, escaping any characters special to the shell.  If
        we don't escape them, construct_command_argv_internal will
@@ -3403,6 +3421,30 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
 #ifdef WINDOWS32
     command_ptr = ap;
 #endif
+
+#if !defined (WINDOWS32) && defined (MAX_ARG_STRLEN)
+    if (unixy_shell && line_len > MAX_ARG_STRLEN)
+      {
+       unsigned j;
+       memcpy (ap, eval_line, sizeof (eval_line) - 1);
+       ap += sizeof (eval_line) - 1;
+       for (j = 1; j <= 2 * line_len / (MAX_ARG_STRLEN - 2); j++)
+         ap += sprintf (ap, "\\$\\{%u\\}", j);
+       *ap++ = '\\';
+       *ap++ = '"';
+       *ap++ = ' ';
+       /* Copy only the first word of SHELL to $0.  */
+       for (p = shell; *p != '\0'; ++p)
+         {
+           if (isspace ((unsigned char)*p))
+             break;
+           *ap++ = *p;
+         }
+       *ap++ = ' ';
+      }
+#endif
+    args_ptr = ap;
+
     for (p = line; *p != '\0'; ++p)
       {
         if (restp != NULL && *p == '\n')
@@ -3450,6 +3492,13 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
           }
 #endif
         *ap++ = *p;
+#if !defined (WINDOWS32) && defined (MAX_ARG_STRLEN)
+       if (unixy_shell && line_len > MAX_ARG_STRLEN && (ap - args_ptr > MAX_ARG_STRLEN - 2))
+         {
+           *ap++ = ' ';
+           args_ptr = ap;
+         }
+#endif
       }
     if (ap == new_line + shell_len + sflags_len + 2)
       {

Reply via email to