+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.
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 */
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 *))
{
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)
_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;
_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. */
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 *)