]> Savannah Git Hosting - gnulib.git/commitdiff
obstack: use size_t alignments and check for overflow
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 29 Oct 2014 06:58:42 +0000 (23:58 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 29 Oct 2014 07:23:39 +0000 (00:23 -0700)
* 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.

ChangeLog
lib/obstack.c
lib/obstack.h

index 7aac7ebbeb95f3d6596f859d3fab095be6b4c14c..8bf2baa2a33f476e582099d249338083dd2357b5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
index 8e247fb0a193db2303d4a1b441b44bc2c9e32996..342f9f84040d7bec067b325a9ff72e9c72952f1d 100644 (file)
@@ -106,7 +106,7 @@ typedef void (*freefun_type) (void *, struct _obstack_chunk *);
 
 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 @@ _obstack_begin_worker (struct obstack *h,
 
 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 @@ _obstack_begin (struct obstack *h,
 
 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 @@ void
 _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;
index 909d0d385158f2a8ed09c477745136e2c4b594a6..ba4de1d4acfd736348c455d3de3c33a50fdcab5d 100644 (file)
@@ -166,7 +166,7 @@ struct obstack          /* control current object in current chunk */
     _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 @@ struct obstack          /* control current object in current chunk */
 
 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 *)