Thanks for doing all this. The gnulib patches are good as far as they go, but
they need one more change: alignments should also change from int to size_t.
The first attached gnulib patch does that, plus it fixes a longstanding integer
overflow bug that can occur with large alignments (plus large sizes). While
we're in the neighborhood we should be using C11's alignof rather than
reinventing that particular wheel; the second attached gnulib patch does that.
I've installed your five gnulib patches plus the two attached patches into gnulib.
Two things for the glibc patch. First, the updated gnulib patches need to be
merged into the glibc patch. Second, the manual needs to be updated to match
the revised API induced by all these patches.
And thanks again.
From 421a53ad006c9ad9a1cad0b1e42246c01ffa3154 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Tue, 28 Oct 2014 23:58:42 -0700
Subject: [PATCH 1/2] 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.
---
ChangeLog | 10 ++++++++++
lib/obstack.c | 18 +++++++++++-------
lib/obstack.h | 8 +++++---
3 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 7aac7eb..8bf2baa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2014-10-28 Paul Eggert <egg...@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 <egg...@cs.ucla.edu>
socketlib, sockets, sys_socket: Use AC_REQUIRE to pacify autoconf.
diff --git a/lib/obstack.c b/lib/obstack.c
index 8e247fb..342f9f8 100644
--- a/lib/obstack.c
+++ b/lib/obstack.c
@@ -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;
diff --git a/lib/obstack.h b/lib/obstack.h
index 909d0d3..ba4de1d 100644
--- a/lib/obstack.h
+++ b/lib/obstack.h
@@ -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 *)
--
1.9.3
From 3574ba6f1d5246384dd4582558fd520aeedb8b91 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Wed, 29 Oct 2014 00:22:08 -0700
Subject: [PATCH 2/2] obstack: prefer alignof to calculating alignments by hand
* lib/obstack.c: Include <stdalign.h>.
(struct fooalign): Remove.
(DEFAULT_ALIGNMENT): Use alignof rather than the old offsetof hack.
* modules/obstack (Depends-on): Add stdalign.
---
ChangeLog | 8 ++++++++
lib/obstack.c | 8 ++------
modules/obstack | 1 +
3 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 8bf2baa..ffe7285 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2014-10-29 Paul Eggert <egg...@cs.ucla.edu>
+
+ obstack: prefer alignof to calculating alignments by hand
+ * lib/obstack.c: Include <stdalign.h>.
+ (struct fooalign): Remove.
+ (DEFAULT_ALIGNMENT): Use alignof rather than the old offsetof hack.
+ * modules/obstack (Depends-on): Add stdalign.
+
2014-10-28 Paul Eggert <egg...@cs.ucla.edu>
obstack: use size_t alignments and check for overflow
diff --git a/lib/obstack.c b/lib/obstack.c
index 342f9f8..03281ae 100644
--- a/lib/obstack.c
+++ b/lib/obstack.c
@@ -48,6 +48,7 @@
#endif
#ifndef _OBSTACK_ELIDE_CODE
+# include <stdalign.h>
# include <stdlib.h>
# include <stdint.h>
@@ -58,17 +59,12 @@ union fooround
long double d;
void *p;
};
-struct fooalign
-{
- char c;
- union fooround u;
-};
/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
But in fact it might be less smart and round addresses to as much as
DEFAULT_ROUNDING. So we prepare for it to do that. */
enum
{
- DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
+ DEFAULT_ALIGNMENT = alignof (union fooround),
DEFAULT_ROUNDING = sizeof (union fooround)
};
diff --git a/modules/obstack b/modules/obstack
index bceecdc..c2c6390 100644
--- a/modules/obstack
+++ b/modules/obstack
@@ -8,6 +8,7 @@ lib/obstack.c
Depends-on:
gettext-h
exitfail
+stdalign
stdint
stdlib
--
1.9.3