]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix SAFE_ALLOCA to not exhaust the stack when in a loop.
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 23 Sep 2014 05:42:47 +0000 (22:42 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Tue, 23 Sep 2014 05:42:47 +0000 (22:42 -0700)
Problem reported by Dmietry Antipov in thread leading to:
http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00713.html
This patch fixes only SAFE_ALLOCA, SAFE_NALLOCA, and SAFE_ALLOCA_LISP;
the experimental local_* macros enabled by USE_LOCAL_ALLOCATORS
remain unfixed.
* callproc.c (call_process): Save and restore sa_avail.
* lisp.h (USE_SAFE_ALLOCA): Define sa_avail.
(AVAIL_ALLOCA): New macro.
(SAFE_ALLOCA, SAFE_NALLOCA, SAFE_ALLOCA_LISP):
Use it, and check against sa_avail rather than MAX_ALLOCA.

src/ChangeLog
src/callproc.c
src/lisp.h

index 09426cfbf99bb27b43e7799d861bf9aafc46eb71..02d7871e8848e743983cefc1af1c18435823eb78 100644 (file)
@@ -1,3 +1,17 @@
+2014-09-23  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Fix SAFE_ALLOCA to not exhaust the stack when in a loop.
+       Problem reported by Dmietry Antipov in thread leading to:
+       http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00713.html
+       This patch fixes only SAFE_ALLOCA, SAFE_NALLOCA, and SAFE_ALLOCA_LISP;
+       the experimental local_* macros enabled by USE_LOCAL_ALLOCATORS
+       remain unfixed.
+       * callproc.c (call_process): Save and restore sa_avail.
+       * lisp.h (USE_SAFE_ALLOCA): Define sa_avail.
+       (AVAIL_ALLOCA): New macro.
+       (SAFE_ALLOCA, SAFE_NALLOCA, SAFE_ALLOCA_LISP):
+       Use it, and check against sa_avail rather than MAX_ALLOCA.
+
 2014-09-22  Dmitry Antipov  <dmantipov@yandex.ru>
 
        On OSX, do not free font-specific data more than once (Bug#18501).
index 798f441bdefd95c86c3ee3fe573639e518b02056..4bedf671e83de2413486e7adb990981eb43dad01 100644 (file)
@@ -632,6 +632,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
     int volatile fd_error_volatile = fd_error;
     int volatile filefd_volatile = filefd;
     ptrdiff_t volatile count_volatile = count;
+    ptrdiff_t volatile sa_avail_volatile = sa_avail;
     ptrdiff_t volatile sa_count_volatile = sa_count;
     char **volatile new_argv_volatile = new_argv;
     int volatile callproc_fd_volatile[CALLPROC_FDS];
@@ -648,6 +649,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
     fd_error = fd_error_volatile;
     filefd = filefd_volatile;
     count = count_volatile;
+    sa_avail = sa_avail_volatile;
     sa_count = sa_count_volatile;
     new_argv = new_argv_volatile;
 
index 3795795c49a56f83b4117c238547db7e07b975e5..21f652b81aceba8400dd9df14fdfa83a9b9e416a 100644 (file)
@@ -4496,12 +4496,15 @@ enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 };
 extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
 
 #define USE_SAFE_ALLOCA                        \
+  ptrdiff_t sa_avail = MAX_ALLOCA;     \
   ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false
 
+#define AVAIL_ALLOCA(size) (sa_avail -= (size), alloca (size))
+
 /* SAFE_ALLOCA allocates a simple buffer.  */
 
-#define SAFE_ALLOCA(size) ((size) <= MAX_ALLOCA        \
-                          ? alloca (size)      \
+#define SAFE_ALLOCA(size) ((size) <= sa_avail                          \
+                          ? AVAIL_ALLOCA (size)                        \
                           : (sa_must_free = true, record_xmalloc (size)))
 
 /* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER *
@@ -4510,8 +4513,8 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
 
 #define SAFE_NALLOCA(buf, multiplier, nitems)                   \
   do {                                                          \
-    if ((nitems) <= MAX_ALLOCA / sizeof *(buf) / (multiplier))  \
-      (buf) = alloca (sizeof *(buf) * (multiplier) * (nitems));         \
+    if ((nitems) <= sa_avail / sizeof *(buf) / (multiplier))    \
+      (buf) = AVAIL_ALLOCA (sizeof *(buf) * (multiplier) * (nitems)); \
     else                                                        \
       {                                                                 \
        (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \
@@ -4543,8 +4546,8 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
 
 #define SAFE_ALLOCA_LISP(buf, nelt)                           \
   do {                                                        \
-    if ((nelt) <= MAX_ALLOCA / word_size)                     \
-      (buf) = alloca ((nelt) * word_size);                    \
+    if ((nelt) <= sa_avail / word_size)                               \
+      (buf) = AVAIL_ALLOCA ((nelt) * word_size);              \
     else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \
       {                                                               \
        Lisp_Object arg_;                                      \