make-dfsg/debian/patches/0009-handle_excessive_command_length-Patch-to-fix-large-c.patch
Manoj Srivastava 6536b40890 [master]: A new bug fixing release
* 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. There is a
  patch used by people to solve this (gentoo, etc). Adam Conrad has
  provided a patch to fix this.  (Closes: #688601).
* Pre-4.0 make had an memory corruption issue that caused repeated
  execution of a specific makefile to display the cirruption. Running
  with make 4.0 does not show the issue. (Closes: #682895).
* recently, the Multi-Arch: foreign tag was added toth make binary
  package.  Jakub Wilk pointed out that this is not correct, some of the
  make interfaces are actually architecture-dependent. Reverting that
  change.
* Bug fix #688601: "fails to execute extraordinarily long command
  lines", thanks to Daniel Stone
* Bug fix #682895: "incorrect variable handling and corruption", thanks
  to Tim Spriggs
2014-05-04 18:14:56 -07:00

126 lines
4 KiB
Diff

From 028da9112fca053cb91642bc085ef75655604306 Mon Sep 17 00:00:00 2001
From: Manoj Srivastava <srivasta@golden-gryphon.com>
Date: Sun, 4 May 2014 17:08:48 -0700
Subject: [PATCH 9/9] [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.
Signed-off-by: Manoj Srivastava <srivasta@golden-gryphon.com>
---
configure.ac | 3 ++-
job.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index 7490b4d..404c7ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,7 +62,8 @@ AC_HEADER_DIRENT
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])
+ memory.h sys/param.h sys/resource.h sys/time.h sys/timeb.h \
+ sys/user.h linux/binfmts.h])
AM_PROG_CC_C_O
AC_C_CONST
diff --git a/job.c b/job.c
index 7b061a6..63a6253 100644
--- a/job.c
+++ b/job.c
@@ -27,6 +27,14 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <string.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
#include <windows.h>
@@ -3067,6 +3075,7 @@ construct_command_argv_internal (char *line, char **restp, 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)
@@ -3232,8 +3241,17 @@ construct_command_argv_internal (char *line, char **restp, 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
@@ -3253,6 +3271,30 @@ construct_command_argv_internal (char *line, char **restp, 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')
@@ -3300,6 +3342,13 @@ construct_command_argv_internal (char *line, char **restp, 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)
{
--
2.0.0.rc0