changeset 37460:da2c411aece7

obstack: use size_t alignments and check for overflow * lib/obstack.c, lib/obstack.h (_obstack_begin, _obstack_begin_1): * lib/obstack.c (_obstack_begin_worker, _obstack_newchunk): * lib/obstack.h (struct obstack.alignment_mask): Use _OBSTACK_SIZE_T, not int, for alignments. * lib/obstack.c (_obstack_newchunk): Fail if the size calculation overflows, e.g., when adding the alignment.
author Paul Eggert <eggert@cs.ucla.edu>
date Tue, 28 Oct 2014 23:58:42 -0700
parents 8970ea48f088
children e161e7208cbe
files ChangeLog lib/obstack.c lib/obstack.h
diffstat 3 files changed, 26 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Oct 29 14:03:00 2014 +1030
+++ b/ChangeLog	Tue Oct 28 23:58:42 2014 -0700
@@ -1,3 +1,13 @@
+2014-10-28  Paul Eggert  <eggert@cs.ucla.edu>
+
+	obstack: use size_t alignments and check for overflow
+	* lib/obstack.c, lib/obstack.h (_obstack_begin, _obstack_begin_1):
+	* lib/obstack.c (_obstack_begin_worker, _obstack_newchunk):
+	* lib/obstack.h (struct obstack.alignment_mask):
+	Use _OBSTACK_SIZE_T, not int, for alignments.
+	* lib/obstack.c (_obstack_newchunk): Fail if the size calculation
+	overflows, e.g., when adding the alignment.
+
 2014-10-24  Paul Eggert  <eggert@cs.ucla.edu>
 
 	socketlib, sockets, sys_socket: Use AC_REQUIRE to pacify autoconf.
--- a/lib/obstack.c	Wed Oct 29 14:03:00 2014 +1030
+++ b/lib/obstack.c	Tue Oct 28 23:58:42 2014 -0700
@@ -106,7 +106,7 @@
 
 static int
 _obstack_begin_worker (struct obstack *h,
-                       _OBSTACK_SIZE_T size, int alignment,
+                       _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
                        chunkfun_type chunkfun, freefun_type freefun)
 {
   struct _obstack_chunk *chunk; /* points to new chunk */
@@ -150,7 +150,7 @@
 
 int
 _obstack_begin (struct obstack *h,
-                _OBSTACK_SIZE_T size, int alignment,
+                _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
                 void *(*chunkfun) (size_t),
                 void (*freefun) (void *))
 {
@@ -162,7 +162,7 @@
 
 int
 _obstack_begin_1 (struct obstack *h,
-                  _OBSTACK_SIZE_T size, int alignment,
+                  _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
                   void *(*chunkfun) (void *, size_t),
                   void (*freefun) (void *, void *),
                   void *arg)
@@ -184,18 +184,22 @@
 _obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length)
 {
   struct _obstack_chunk *old_chunk = h->chunk;
-  struct _obstack_chunk *new_chunk;
-  size_t new_size;
+  struct _obstack_chunk *new_chunk = 0;
   size_t obj_size = h->next_free - h->object_base;
   char *object_base;
 
   /* Compute size for new chunk.  */
-  new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
+  size_t sum1 = obj_size + length;
+  size_t sum2 = sum1 + h->alignment_mask;
+  size_t new_size = sum2 + (obj_size >> 3) + 100;
+  if (new_size < sum2)
+    new_size = sum2;
   if (new_size < h->chunk_size)
     new_size = h->chunk_size;
 
   /* Allocate and initialize the new chunk.  */
-  new_chunk = CALL_CHUNKFUN (h, new_size);
+  if (obj_size <= sum1 && sum1 <= sum2)
+    new_chunk = CALL_CHUNKFUN (h, new_size);
   if (!new_chunk)
     (*obstack_alloc_failed_handler)();
   h->chunk = new_chunk;
--- a/lib/obstack.h	Wed Oct 29 14:03:00 2014 +1030
+++ b/lib/obstack.h	Tue Oct 28 23:58:42 2014 -0700
@@ -166,7 +166,7 @@
     _OBSTACK_SIZE_T i;
     void *p;
   } temp;                       /* Temporary for some macros.  */
-  int alignment_mask;           /* Mask of alignment for each object. */
+  _OBSTACK_SIZE_T alignment_mask;  /* Mask of alignment for each object. */
   /* These prototypes vary based on 'use_extra_arg', and we use
      casts to the prototypeless function type in all assignments,
      but having prototypes here quiets -Wstrict-prototypes.  */
@@ -187,9 +187,11 @@
 
 extern void _obstack_newchunk (struct obstack *, _OBSTACK_SIZE_T);
 extern void _obstack_free (struct obstack *, void *);
-extern int _obstack_begin (struct obstack *, _OBSTACK_SIZE_T, int,
+extern int _obstack_begin (struct obstack *,
+                           _OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
                            void *(*)(size_t), void (*)(void *));
-extern int _obstack_begin_1 (struct obstack *, _OBSTACK_SIZE_T, int,
+extern int _obstack_begin_1 (struct obstack *,
+                             _OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
                              void *(*)(void *, size_t),
                              void (*)(void *, void *), void *);
 extern _OBSTACK_SIZE_T _obstack_memory_used (struct obstack *)