Discussion:
[PATCH 08/13] getgroups: use walloc
Add Reply
Paul Eggert
2017-06-05 06:45:58 UTC
Reply
Permalink
Raw Message
* lib/getgroups.c: Include minmax.h, walloc.h, limits.h.
(rpl_getgroups): Use walloc.h functions instead of checking for
overflow by hand.
* modules/getgroups (Depends-on): Add minmax, walloc.
Remove malloc-posix.
---
ChangeLog | 7 +++++++
lib/getgroups.c | 24 ++++++++++--------------
modules/getgroups | 3 ++-
3 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e3be3b3..4ced38a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2017-06-04 Paul Eggert <***@cs.ucla.edu>

+ getgroups: use walloc
+ * lib/getgroups.c: Include minmax.h, walloc.h, limits.h.
+ (rpl_getgroups): Use walloc.h functions instead of checking for
+ overflow by hand.
+ * modules/getgroups (Depends-on): Add minmax, walloc.
+ Remove malloc-posix.
+
exclude: use xwalloc instead of xalloc
* lib/exclude.c: Include xwalloc.h instead of walloc.h.
(struct exclude_pattern, exclude_add_pattern_buffer):
diff --git a/lib/getgroups.c b/lib/getgroups.c
index dce0f2d..0ac303e 100644
--- a/lib/getgroups.c
+++ b/lib/getgroups.c
@@ -21,7 +21,11 @@

#include <unistd.h>

+#include "minmax.h"
+#include "walloc.h"
+
#include <errno.h>
+#include <limits.h>
#include <stdlib.h>
#include <stdint.h>

@@ -84,12 +88,7 @@ rpl_getgroups (int n, gid_t *group)
if (sizeof *group == sizeof *gbuf)
return getgroups (n, (GETGROUPS_T *) group);

- if (SIZE_MAX / sizeof *gbuf <= n)
- {
- errno = ENOMEM;
- return -1;
- }
- gbuf = malloc (n * sizeof *gbuf);
+ gbuf = wreallocarray (NULL, n, sizeof *gbuf);
if (!gbuf)
return -1;
result = getgroups (n, gbuf);
@@ -105,20 +104,17 @@ rpl_getgroups (int n, gid_t *group)
return result;
}

- n = 20;
+ ptrdiff_t nalloc = 13;
while (1)
{
- /* No need to worry about address arithmetic overflow here,
- since the ancient systems that we're running on have low
- limits on the number of secondary groups. */
- gbuf = malloc (n * sizeof *gbuf);
+ int nalloc_max = MIN (INT_MAX, PTRDIFF_MAX);
+ gbuf = wgrowalloc (NULL, &nalloc, 1, nalloc_max, sizeof *gbuf);
if (!gbuf)
return -1;
- n_groups = getgroups (n, gbuf);
- if (n_groups == -1 ? errno != EINVAL : n_groups < n)
+ n_groups = getgroups (nalloc, gbuf);
+ if (n_groups == -1 ? errno != EINVAL : n_groups < nalloc)
break;
free (gbuf);
- n *= 2;
}

saved_errno = errno;
diff --git a/modules/getgroups b/modules/getgroups
index 9926a12..527f35d 100644
--- a/modules/getgroups
+++ b/modules/getgroups
@@ -7,8 +7,9 @@ m4/getgroups.m4

Depends-on:
unistd
-malloc-posix [test $HAVE_GETGROUPS = 0 || test $REPLACE_GETGROUPS = 1]
+minmax [test $HAVE_GETGROUPS = 0 || test $REPLACE_GETGROUPS = 1]
stdint [test $HAVE_GETGROUPS = 0 || test $REPLACE_GETGROUPS = 1]
+walloc [test $HAVE_GETGROUPS = 0 || test $REPLACE_GETGROUPS = 1]

configure.ac:
gl_FUNC_GETGROUPS
--
2.9.4
Paul Eggert
2017-06-05 06:46:00 UTC
Reply
Permalink
Raw Message
* lib/propername.c: Include xwalloc.h rather than xalloc.h.
(proper_name, proper_name_utf8): Use xwalloc.h rather than
xalloc.h functions.
* modules/propername (Depends-on): Remove xalloc, add xwalloc.
---
ChangeLog | 6 ++++++
lib/propername.c | 14 +++++++-------
modules/propername | 2 +-
3 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index db3adba..8714e51 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2017-06-04 Paul Eggert <***@cs.ucla.edu>

+ propername: use xwalloc rather than xalloc
+ * lib/propername.c: Include xwalloc.h rather than xalloc.h.
+ (proper_name, proper_name_utf8): Use xwalloc.h rather than
+ xalloc.h functions.
+ * modules/propername (Depends-on): Remove xalloc, add xwalloc.
+
group-member: use walloc
* lib/group-member.c: Include walloc.h instead of
xalloc-oversized.
diff --git a/lib/propername.c b/lib/propername.c
index 1e5e28b..1af965d 100644
--- a/lib/propername.c
+++ b/lib/propername.c
@@ -41,7 +41,7 @@
#include "localcharset.h"
#include "c-strcase.h"
#include "xstriconv.h"
-#include "xalloc.h"
+#include "xwalloc.h"
#include "gettext.h"


@@ -168,8 +168,8 @@ proper_name (const char *name)
else
{
/* Return "TRANSLATION (NAME)". */
- char *result =
- XNMALLOC (strlen (translation) + 2 + strlen (name) + 1 + 1, char);
+ char *result
+ = xwmalloc (strlen (translation) + 2 + strlen (name) + 1 + 1);

sprintf (result, "%s (%s)", translation, name);
return result;
@@ -210,8 +210,8 @@ proper_name_utf8 (const char *name_ascii, const char *name_utf8)
{
char *converted_translit;

- size_t len = strlen (locale_code);
- char *locale_code_translit = XNMALLOC (len + 10 + 1, char);
+ ptrdiff_t len = strlen (locale_code);
+ char *locale_code_translit = xwmalloc (len + 10 + 1);
memcpy (locale_code_translit, locale_code, len);
memcpy (locale_code_translit + len, "//TRANSLIT", 10 + 1);

@@ -270,8 +270,8 @@ proper_name_utf8 (const char *name_ascii, const char *name_utf8)
else
{
/* Return "TRANSLATION (NAME)". */
- char *result =
- XNMALLOC (strlen (translation) + 2 + strlen (name) + 1 + 1, char);
+ char *result
+ = xwmalloc (strlen (translation) + 2 + strlen (name) + 1 + 1);

sprintf (result, "%s (%s)", translation, name);

diff --git a/modules/propername b/modules/propername
index 0cc93bf..c54f9f5 100644
--- a/modules/propername
+++ b/modules/propername
@@ -21,7 +21,7 @@ iconv
localcharset
c-strcase
xstriconv
-xalloc
+xwalloc
gettext-h

configure.ac:
--
2.9.4
Paul Eggert
2017-06-05 06:45:57 UTC
Reply
Permalink
Raw Message
* lib/exclude.c: Include xwalloc.h instead of walloc.h.
(struct exclude_pattern, exclude_add_pattern_buffer):
(new_exclude, new_exclude_segment, free_exclude_segment):
(fnmatch_no_wildcards, file_pattern_matches, excluded_file_name):
(add_exclude, add_exclude_fp):
Use xwalloc.h rather than xalloc.h functions.
Use ptrdiff_t, not size_t, for sizes intended for walloc.
* modules/exclude (Depends-on): Add xwalloc, remove xalloc.
---
ChangeLog | 10 ++++++++++
lib/exclude.c | 44 ++++++++++++++++++++++----------------------
modules/exclude | 2 +-
3 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d4173d4..e3be3b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2017-06-04 Paul Eggert <***@cs.ucla.edu>

+ exclude: use xwalloc instead of xalloc
+ * lib/exclude.c: Include xwalloc.h instead of walloc.h.
+ (struct exclude_pattern, exclude_add_pattern_buffer):
+ (new_exclude, new_exclude_segment, free_exclude_segment):
+ (fnmatch_no_wildcards, file_pattern_matches, excluded_file_name):
+ (add_exclude, add_exclude_fp):
+ Use xwalloc.h rather than xalloc.h functions.
+ Use ptrdiff_t, not size_t, for sizes intended for walloc.
+ * modules/exclude (Depends-on): Add xwalloc, remove xalloc.
+
acl-permissions: use walloc
* lib/get-permissions.c: Include walloc.h.
(get_permissions): Use wreallocarray to fix possible integer overflow.
diff --git a/lib/exclude.c b/lib/exclude.c
index fb3bbc2..17b2d90 100644
--- a/lib/exclude.c
+++ b/lib/exclude.c
@@ -38,7 +38,7 @@
#include "hash.h"
#include "mbuiter.h"
#include "fnmatch.h"
-#include "xalloc.h"
+#include "xwalloc.h"
#include "verify.h"
#include "filename.h"

@@ -88,8 +88,8 @@ struct patopts
struct exclude_pattern
{
struct patopts *exclude;
- size_t exclude_alloc;
- size_t exclude_count;
+ ptrdiff_t exclude_alloc;
+ ptrdiff_t exclude_count;
};

enum exclude_type
@@ -131,7 +131,7 @@ struct exclude
void
exclude_add_pattern_buffer (struct exclude *ex, char *buf)
{
- struct pattern_buffer *pbuf = xmalloc (sizeof *pbuf);
+ struct pattern_buffer *pbuf = xwmalloc (sizeof *pbuf);
pbuf->base = buf;
pbuf->next = ex->patbuf;
ex->patbuf = pbuf;
@@ -190,7 +190,7 @@ unescape_pattern (char *str)
struct exclude *
new_exclude (void)
{
- return xzalloc (sizeof *new_exclude ());
+ return xwzalloc (sizeof *new_exclude ());
}

/* Calculate the hash of string. */
@@ -254,7 +254,7 @@ string_free (void *data)
static void
new_exclude_segment (struct exclude *ex, enum exclude_type type, int options)
{
- struct exclude_segment *sp = xzalloc (sizeof (struct exclude_segment));
+ struct exclude_segment *sp = xwzalloc (sizeof (struct exclude_segment));
sp->type = type;
sp->options = options;
switch (type)
@@ -281,7 +281,7 @@ new_exclude_segment (struct exclude *ex, enum exclude_type type, int options)
static void
free_exclude_segment (struct exclude_segment *seg)
{
- size_t i;
+ ptrdiff_t i;

switch (seg->type)
{
@@ -338,7 +338,7 @@ fnmatch_no_wildcards (char const *pattern, char const *f, int options)
: strcmp (pattern, f));
else if (! (options & FNM_CASEFOLD))
{
- size_t patlen = strlen (pattern);
+ ptrdiff_t patlen = strlen (pattern);
int r = strncmp (pattern, f, patlen);
if (! r)
{
@@ -357,7 +357,7 @@ fnmatch_no_wildcards (char const *pattern, char const *f, int options)
Also, the copy should not be necessary. However, fixing this
will probably involve a change to the mbs* API. */

- char *fcopy = xstrdup (f);
+ char *fcopy = xwstrdup (f);
char *p;
int r;
for (p = fcopy; ; *p++ = '/')
@@ -407,9 +407,9 @@ exclude_patopts (struct patopts const *opts, char const *f)
static bool
file_pattern_matches (struct exclude_segment const *seg, char const *f)
{
- size_t exclude_count = seg->v.pat.exclude_count;
+ ptrdiff_t exclude_count = seg->v.pat.exclude_count;
struct patopts const *exclude = seg->v.pat.exclude;
- size_t i;
+ ptrdiff_t i;

for (i = 0; i < exclude_count; i++)
{
@@ -485,7 +485,7 @@ excluded_file_name (struct exclude const *ex, char const *f)
if (seg->type == exclude_hash)
{
if (!filename)
- filename = xmalloc (strlen (f) + 1);
+ filename = xwmalloc (strlen (f) + 1);
if (file_name_matches (seg, f, filename))
break;
}
@@ -533,8 +533,8 @@ add_exclude (struct exclude *ex, char const *pattern, int options)

pat = &seg->v.pat;
if (pat->exclude_count == pat->exclude_alloc)
- pat->exclude = x2nrealloc (pat->exclude, &pat->exclude_alloc,
- sizeof *pat->exclude);
+ pat->exclude = xwgrowalloc (pat->exclude, &pat->exclude_alloc,
+ 1, -1, sizeof *pat->exclude);
patopts = &pat->exclude[pat->exclude_count++];

patopts->options = options;
@@ -547,7 +547,7 @@ add_exclude (struct exclude *ex, char const *pattern, int options)
if (options & FNM_LEADING_DIR)
{
char *tmp;
- size_t len = strlen (pattern);
+ ptrdiff_t len = strlen (pattern);

while (len > 0 && ISSLASH (pattern[len-1]))
--len;
@@ -556,7 +556,7 @@ add_exclude (struct exclude *ex, char const *pattern, int options)
rc = 1;
else
{
- tmp = xmalloc (len + 7);
+ tmp = xwmalloc (len + 7);
memcpy (tmp, pattern, len);
strcpy (tmp + len, "(/.*)?");
rc = regcomp (&patopts->v.re, tmp, cflags);
@@ -576,7 +576,7 @@ add_exclude (struct exclude *ex, char const *pattern, int options)
{
if (options & EXCLUDE_ALLOC)
{
- pattern = xstrdup (pattern);
+ pattern = xwstrdup (pattern);
exclude_add_pattern_buffer (ex, (char*) pattern);
}
patopts->v.pattern = pattern;
@@ -593,7 +593,7 @@ add_exclude (struct exclude *ex, char const *pattern, int options)
new_exclude_segment (ex, exclude_hash, options);
seg = ex->head;

- str = xstrdup (pattern);
+ str = xwstrdup (pattern);
if ((options & (EXCLUDE_WILDCARDS | FNM_NOESCAPE)) == EXCLUDE_WILDCARDS)
unescape_pattern (str);
p = hash_insert (seg->v.table, str);
@@ -617,22 +617,22 @@ add_exclude_fp (void (*add_func) (struct exclude *, char const *, int, void *),
char *p;
char *pattern;
char const *lim;
- size_t buf_alloc = 0;
- size_t buf_count = 0;
+ ptrdiff_t buf_alloc = 0;
+ ptrdiff_t buf_count = 0;
int c;
int e = 0;

while ((c = getc (fp)) != EOF)
{
if (buf_count == buf_alloc)
- buf = x2realloc (buf, &buf_alloc);
+ buf = xwgrowalloc (buf, &buf_alloc, 1, -1, sizeof *buf);
buf[buf_count++] = c;
}

if (ferror (fp))
e = errno;

- buf = xrealloc (buf, buf_count + 1);
+ buf = xwrealloc (buf, buf_count + 1);
buf[buf_count] = line_end;
lim = buf + buf_count + ! (buf_count == 0 || buf[buf_count - 1] == line_end);

diff --git a/modules/exclude b/modules/exclude
index 04fb0e5..a7e2abb 100644
--- a/modules/exclude
+++ b/modules/exclude
@@ -14,7 +14,7 @@ mbuiter
regex
stdbool
verify
-xalloc
+xwalloc

configure.ac:
--
2.9.4
Paul Eggert
2017-06-05 06:45:53 UTC
Reply
Permalink
Raw Message
* lib/allocator.h: Adjust comment to allow reasons other
than size overflow to result in SIZE_MAX.
---
ChangeLog | 4 ++++
lib/allocator.h | 4 ++--
2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2f99ccc..5aae016 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2017-06-04 Paul Eggert <***@cs.ucla.edu>

+ allocator: allow reasons other than size overflow
+ * lib/allocator.h: Adjust comment to allow reasons other
+ than size overflow to result in SIZE_MAX.
+
xwalloc, xwalloc-die, xwallocator: new modules
* lib/xwalloc-die.c, lib/xwalloc.c, lib/xwalloc.h, lib/xwallocator.c:
* modules/xwalloc, modules/xwalloc-die, modules/xwalloc-tests:
diff --git a/lib/allocator.h b/lib/allocator.h
index 650f8e0..9f4c30f 100644
--- a/lib/allocator.h
+++ b/lib/allocator.h
@@ -47,8 +47,8 @@ struct allocator

/* If nonnull, call DIE (SIZE) if MALLOC (SIZE) or REALLOC (...,
SIZE) fails. DIE should not return. SIZE should equal SIZE_MAX
- if size_t overflow was detected while calculating sizes to be
- passed to MALLOC or REALLOC. */
+ if the size is unknown, e.g., if size_t overflow was detected
+ while calculating sizes to be passed to MALLOC or REALLOC. */
void (*die) (size_t);
};
--
2.9.4
Paul Eggert
2017-06-05 06:45:59 UTC
Reply
Permalink
Raw Message
* lib/group-member.c: Include walloc.h instead of
xalloc-oversized.
(get_group_info): Use walloc.h function instead of checking for
overflow by hand.
* modules/group-member: Remove xalloc-oversized.
Add walloc.
---
ChangeLog | 6 ++++++
lib/group-member.c | 7 +++----
modules/group-member | 2 +-
3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4ced38a..db3adba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2017-06-04 Paul Eggert <***@cs.ucla.edu>

+ group-member: use walloc
+ * lib/group-member.c: Include walloc.h instead of
+ xalloc-oversized.
+ (get_group_info): Use walloc.h function instead of checking for
+ overflow by hand.
+
getgroups: use walloc
* lib/getgroups.c: Include minmax.h, walloc.h, limits.h.
(rpl_getgroups): Use walloc.h functions instead of checking for
diff --git a/lib/group-member.c b/lib/group-member.c
index 20f8ee8..6fe6bd5 100644
--- a/lib/group-member.c
+++ b/lib/group-member.c
@@ -25,7 +25,7 @@
#include <sys/types.h>
#include <stdlib.h>

-#include "xalloc-oversized.h"
+#include "walloc.h"

/* Most processes have no more than this many groups, and for these
processes we can avoid using malloc. */
@@ -53,10 +53,9 @@ get_group_info (struct group_info *gi)
if (n_groups < 0)
{
int n_group_slots = getgroups (0, NULL);
- if (0 <= n_group_slots
- && ! xalloc_oversized (n_group_slots, sizeof *gi->group))
+ if (0 <= n_group_slots)
{
- gi->group = malloc (n_group_slots * sizeof *gi->group);
+ gi->group = wreallocarray (NULL, n_group_slots, sizeof *gi->group);
if (gi->group)
n_groups = getgroups (n_group_slots, gi->group);
}
diff --git a/modules/group-member b/modules/group-member
index 9baf8e9..d8f19b2 100644
--- a/modules/group-member
+++ b/modules/group-member
@@ -9,7 +9,7 @@ Depends-on:
unistd
extensions
getgroups [test $HAVE_GROUP_MEMBER = 0]
-xalloc-oversized [test $HAVE_GROUP_MEMBER = 0]
+walloc [test $HAVE_GROUP_MEMBER = 0]

configure.ac:
gl_FUNC_GROUP_MEMBER
--
2.9.4
Paul Eggert
2017-06-05 06:46:03 UTC
Reply
Permalink
Raw Message
* lib/xstriconv.c: Include xwalloc.h instead of xalloc.h.
(xmem_cd_iconv, xstr_cd_iconv, xstr_iconv):
Use xwalloc_die instead of xalloc_die.
* modules/xstriconv (Depends-on): Remove xalloc, add xwalloc.
---
ChangeLog | 6 ++++++
lib/xstriconv.c | 8 ++++----
modules/xstriconv | 2 +-
3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4b34cb9..5c50179 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2017-06-04 Paul Eggert <***@cs.ucla.edu>

+ xstriconv: use xwalloc rather than xalloc
+ * lib/xstriconv.c: Include xwalloc.h instead of xalloc.h.
+ (xmem_cd_iconv, xstr_cd_iconv, xstr_iconv):
+ Use xwalloc_die instead of xalloc_die.
+ * modules/xstriconv (Depends-on): Remove xalloc, add xwalloc.
+
trim: use xwalloc rather than xalloc
* lib/trim.c: Include xwalloc.h instead of xalloc.h.
(trim2): Use xwstrdup rather than strdup and xalloc_die.
diff --git a/lib/xstriconv.c b/lib/xstriconv.c
index 21546b6..a5ebfff 100644
--- a/lib/xstriconv.c
+++ b/lib/xstriconv.c
@@ -23,7 +23,7 @@
#include <errno.h>

#include "striconv.h"
-#include "xalloc.h"
+#include "xwalloc.h"


#if HAVE_ICONV
@@ -35,7 +35,7 @@ xmem_cd_iconv (const char *src, size_t srclen, iconv_t cd,
int retval = mem_cd_iconv (src, srclen, cd, resultp, lengthp);

if (retval < 0 && errno == ENOMEM)
- xalloc_die ();
+ xwalloc_die (-1);
return retval;
}

@@ -45,7 +45,7 @@ xstr_cd_iconv (const char *src, iconv_t cd)
char *result = str_cd_iconv (src, cd);

if (result == NULL && errno == ENOMEM)
- xalloc_die ();
+ xwalloc_die (-1);
return result;
}

@@ -57,6 +57,6 @@ xstr_iconv (const char *src, const char *from_codeset, const char *to_codeset)
char *result = str_iconv (src, from_codeset, to_codeset);

if (result == NULL && errno == ENOMEM)
- xalloc_die ();
+ xwalloc_die (-1);
return result;
}
diff --git a/modules/xstriconv b/modules/xstriconv
index ce95f86..908a2ba 100644
--- a/modules/xstriconv
+++ b/modules/xstriconv
@@ -8,7 +8,7 @@ lib/xstriconv.c

Depends-on:
striconv
-xalloc
+xwalloc

configure.ac:
--
2.9.4
Paul Eggert
2017-06-05 06:45:54 UTC
Reply
Permalink
Raw Message
* NEWS: Mention ptrdiff_t.
* lib/careadlinkat.c: Include stdint.h, intprops.h, minmax.h, walloc.h.
(SSIZE_MAX): Use TYPE_MAXIMUM.
(careadlinkat): Accept ptrdiff_t, not size_t.
Use wallocmore instead of rolling our own allocator.
* lib/careadlinkat.h (careadlinkat): Accept ptrdiff_t, not size_t.
* modules/careadlinkat (Depends-on): Add intprops, minmax, stdint,
walloc. Remove allocator.
---
ChangeLog | 10 ++++++++
NEWS | 4 ++++
lib/careadlinkat.c | 64 +++++++++++++++++++---------------------------------
lib/careadlinkat.h | 2 +-
modules/careadlinkat | 5 +++-
5 files changed, 42 insertions(+), 43 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5aae016..d7e6afc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2017-06-04 Paul Eggert <***@cs.ucla.edu>

+ careadlinkat: use walloc
+ * NEWS: Mention ptrdiff_t.
+ * lib/careadlinkat.c: Include stdint.h, intprops.h, minmax.h, walloc.h.
+ (SSIZE_MAX): Use TYPE_MAXIMUM.
+ (careadlinkat): Accept ptrdiff_t, not size_t.
+ Use wallocmore instead of rolling our own allocator.
+ * lib/careadlinkat.h (careadlinkat): Accept ptrdiff_t, not size_t.
+ * modules/careadlinkat (Depends-on): Add intprops, minmax, stdint,
+ walloc. Remove allocator.
+
allocator: allow reasons other than size overflow
* lib/allocator.h: Adjust comment to allow reasons other
than size overflow to result in SIZE_MAX.
diff --git a/NEWS b/NEWS
index b75ca01..ff60817 100644
--- a/NEWS
+++ b/NEWS
@@ -42,6 +42,10 @@ User visible incompatible changes

Date Modules Changes

+2017-06-04 careadlinkat careadlinkat now takes
+ ptrdiff_t instead of size_t arguments for object
+ and byte counts.
+
2017-05-19 closeout close_stdout longer closes stderr when addresses
are being sanitized, as the sanitizer outputs to
stderr afterwards.
diff --git a/lib/careadlinkat.c b/lib/careadlinkat.c
index 455e00e..f939b0f 100644
--- a/lib/careadlinkat.c
+++ b/lib/careadlinkat.c
@@ -24,19 +24,18 @@

#include <errno.h>
#include <limits.h>
+#include <stdint.h>
#include <string.h>
#include <unistd.h>

-/* Define this independently so that stdint.h is not a prerequisite. */
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-
#ifndef SSIZE_MAX
-# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
+# define SSIZE_MAX TYPE_MAXIMUM (ssize_t)
#endif

#include "allocator.h"
+#include "intprops.h"
+#include "minmax.h"
+#include "walloc.h"

/* Assuming the current directory is FD, get the symbolic link value
of FILENAME as a null-terminated string and put it into a buffer.
@@ -49,8 +48,7 @@

If the link is not small, put it into a dynamically allocated
buffer managed by ALLOC. It is the caller's responsibility to free
- the returned value if it is nonnull and is not BUFFER. A null
- ALLOC stands for the standard allocator.
+ the returned value if it is nonnull and is not BUFFER.

The PREADLINKAT function specifies how to read links. It operates
like POSIX readlinkat()
@@ -62,19 +60,15 @@

char *
careadlinkat (int fd, char const *filename,
- char *buffer, size_t buffer_size,
+ char *buffer, ptrdiff_t buffer_size,
struct allocator const *alloc,
ssize_t (*preadlinkat) (int, char const *, char *, size_t))
{
char *buf;
- size_t buf_size;
- size_t buf_size_max =
- SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
+ ptrdiff_t buf_size;
+ ptrdiff_t buf_size_max = MIN (PTRDIFF_MAX, SSIZE_MAX);
char stack_buf[1024];

- if (! alloc)
- alloc = &stdlib_allocator;
-
if (! buffer_size)
{
/* Allocate the initial buffer on the stack. This way, in the
@@ -92,7 +86,6 @@ careadlinkat (int fd, char const *filename,
{
/* Attempt to read the link into the current buffer. */
ssize_t link_length = preadlinkat (fd, filename, buf, buf_size);
- size_t link_size;
if (link_length < 0)
{
/* On AIX 5L v5.3 and HP-UX 11i v2 04/09, readlink returns -1
@@ -108,26 +101,27 @@ careadlinkat (int fd, char const *filename,
return NULL;
}
}
-
- link_size = link_length;
-
- if (link_size < buf_size)
+ else if (link_length < buf_size)
{
- buf[link_size++] = '\0';
+ buf[link_length++] = '\0';

if (buf == stack_buf)
{
- char *b = (char *) alloc->allocate (link_size);
- buf_size = link_size;
+ char *b = alloc->allocate (link_length);
if (! b)
- break;
- memcpy (b, buf, link_size);
+ {
+ if (alloc->die)
+ alloc->die (link_length);
+ break;
+ }
+ memcpy (b, buf, link_length);
buf = b;
+ buf_size = link_length;
}
- else if (link_size < buf_size && buf != buffer && alloc->reallocate)
+ else if (buf != buffer)
{
/* Shrink BUF before returning it. */
- char *b = (char *) alloc->reallocate (buf, link_size);
+ char *b = alloc->reallocate (buf, link_length);
if (b)
buf = b;
}
@@ -138,23 +132,11 @@ careadlinkat (int fd, char const *filename,
if (buf != buffer)
alloc->free (buf);

- if (buf_size <= buf_size_max / 2)
- buf_size *= 2;
- else if (buf_size < buf_size_max)
- buf_size = buf_size_max;
- else if (buf_size_max < SIZE_MAX)
- {
- errno = ENAMETOOLONG;
- return NULL;
- }
- else
- break;
- buf = (char *) alloc->allocate (buf_size);
+ /* BUF_SIZE was not big enough; try again with a larger value. */
+ buf = wallocmore (NULL, &buf_size, 1, buf_size_max, sizeof *buf, alloc);
}
while (buf);

- if (alloc->die)
- alloc->die (buf_size);
errno = ENOMEM;
return NULL;
}
diff --git a/lib/careadlinkat.h b/lib/careadlinkat.h
index 528a828..b66e4bd 100644
--- a/lib/careadlinkat.h
+++ b/lib/careadlinkat.h
@@ -47,7 +47,7 @@ struct allocator;
set errno. */

char *careadlinkat (int fd, char const *filename,
- char *buffer, size_t buffer_size,
+ char *buffer, ptrdiff_t buffer_size,
struct allocator const *alloc,
ssize_t (*preadlinkat) (int, char const *,
char *, size_t));
diff --git a/modules/careadlinkat b/modules/careadlinkat
index 9dd7471..5079429 100644
--- a/modules/careadlinkat
+++ b/modules/careadlinkat
@@ -6,9 +6,12 @@ lib/careadlinkat.c
lib/careadlinkat.h

Depends-on:
-allocator
+intprops
+minmax
ssize_t
+stdint
unistd
+walloc

configure.ac:
AC_CHECK_FUNCS_ONCE([readlinkat])
--
2.9.4
Paul Eggert
2017-06-05 06:45:56 UTC
Reply
Permalink
Raw Message
* lib/get-permissions.c: Include walloc.h.
(get_permissions): Use wreallocarray to fix possible integer overflow.
* lib/set-permissions.c: Include stdint.h, walloc.h.
(set_acls_from_mode): Use wgrowalloc instead of doing it by hand,
fixing a possible integer overflow.
* modules/acl-permissions (Depends-on): Add walloc.
---
ChangeLog | 8 ++++++++
lib/get-permissions.c | 7 +++++--
lib/set-permissions.c | 19 +++++++------------
modules/acl-permissions | 1 +
4 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ebd74b5..d4173d4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2017-06-04 Paul Eggert <***@cs.ucla.edu>

+ acl-permissions: use walloc
+ * lib/get-permissions.c: Include walloc.h.
+ (get_permissions): Use wreallocarray to fix possible integer overflow.
+ * lib/set-permissions.c: Include stdint.h, walloc.h.
+ (set_acls_from_mode): Use wgrowalloc instead of doing it by hand,
+ fixing a possible integer overflow.
+ * modules/acl-permissions (Depends-on): Add walloc.
+
dfa: use xwalloc instead of xalloc
* NEWS: Mention dfa.
* lib/dfa.c: Include xwalloc.h instead of xalloc.h, intprops.h.
diff --git a/lib/get-permissions.c b/lib/get-permissions.c
index dc77748..c8e1369 100644
--- a/lib/get-permissions.c
+++ b/lib/get-permissions.c
@@ -23,6 +23,7 @@
#include "acl.h"

#include "acl-internal.h"
+#include "walloc.h"

/* Read the permissions of a file into CTX. If DESC is a valid file descriptor,
use file descriptor operations, else use filename based operations on NAME.
@@ -130,7 +131,8 @@ get_permissions (const char *name, int desc, mode_t mode,
if (ctx->ace_count == 0)
break;

- ctx->ace_entries = (ace_t *) malloc (ctx->ace_count * sizeof (ace_t));
+ ctx->ace_entries = (ace_t *) wreallocarray (NULL, ctx->ace_count,
+ sizeof (ace_t));
if (ctx->ace_entries == NULL)
{
errno = ENOMEM;
@@ -185,7 +187,8 @@ get_permissions (const char *name, int desc, mode_t mode,
if (ctx->count == 0)
break;

- ctx->entries = (aclent_t *) malloc (ctx->count * sizeof (aclent_t));
+ ctx->entries = (aclent_t *) wreallocarray (NULL, ctx->count,
+ sizeof (aclent_t));
if (ctx->entries == NULL)
{
errno = ENOMEM;
diff --git a/lib/set-permissions.c b/lib/set-permissions.c
index 75bb2dc..14a28d0 100644
--- a/lib/set-permissions.c
+++ b/lib/set-permissions.c
@@ -21,7 +21,10 @@

#include "acl.h"

+#include <stdint.h>
+
#include "acl-internal.h"
+#include "walloc.h"

#if USE_ACL
# if ! defined HAVE_ACL_FROM_MODE && defined HAVE_ACL_FROM_TEXT /* FreeBSD, IRIX, Tru64 */
@@ -70,11 +73,7 @@ set_acls_from_mode (const char *name, int desc, mode_t mode, bool *must_chmod)
{
/* Initially, try to read the entries into a stack-allocated buffer.
Use malloc if it does not fit. */
- enum
- {
- alloc_init = 4000 / sizeof (ace_t), /* >= 3 */
- alloc_max = MIN (INT_MAX, SIZE_MAX / sizeof (ace_t))
- };
+ enum { alloc_init = 4000 / sizeof (ace_t) }; /* >= 3 */
ace_t buf[alloc_init];
size_t alloc = alloc_init;
ace_t *entries = buf;
@@ -90,13 +89,9 @@ set_acls_from_mode (const char *name, int desc, mode_t mode, bool *must_chmod)
{
/* Increase the size of the buffer. */
free (malloced);
- if (alloc > alloc_max / 2)
- {
- errno = ENOMEM;
- return -1;
- }
- alloc = 2 * alloc; /* <= alloc_max */
- entries = malloced = (ace_t *) malloc (alloc * sizeof (ace_t));
+ entries = malloced = wgrowalloc (NULL, &alloc, 1,
+ MIN (INT_MAX, PTRDIFF_MAX),
+ sizeof *entries);
if (entries == NULL)
{
errno = ENOMEM;
diff --git a/modules/acl-permissions b/modules/acl-permissions
index 49b91ff..b043d3d 100644
--- a/modules/acl-permissions
+++ b/modules/acl-permissions
@@ -16,6 +16,7 @@ extern-inline
fstat
stdbool
sys_stat
+walloc

configure.ac:
gl_FUNC_ACL
--
2.9.4
Paul Eggert
2017-06-05 06:46:02 UTC
Reply
Permalink
Raw Message
* lib/trim.c: Include xwalloc.h instead of xalloc.h.
(trim2): Use xwstrdup rather than strdup and xalloc_die.
* modules/trim (Depends-on): Remove xalloc, add xwalloc.
---
ChangeLog | 5 +++++
lib/trim.c | 9 ++-------
modules/trim | 2 +-
3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 460a383..4b34cb9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2017-06-04 Paul Eggert <***@cs.ucla.edu>

+ trim: use xwalloc rather than xalloc
+ * lib/trim.c: Include xwalloc.h instead of xalloc.h.
+ (trim2): Use xwstrdup rather than strdup and xalloc_die.
+ * modules/trim (Depends-on): Remove xalloc, add xwalloc.
+
quotearg: use xwalloc rather than xalloc
* lib/quotearg.c: Include xwalloc.h instead of xalloc.h.
(clone_quoting_options, quotearg_alloc_mem, nslots)
diff --git a/lib/trim.c b/lib/trim.c
index a4dca9f..e06cba8 100644
--- a/lib/trim.c
+++ b/lib/trim.c
@@ -28,7 +28,7 @@

#include "mbchar.h"
#include "mbiter.h"
-#include "xalloc.h"
+#include "xwalloc.h"

/* Use this to suppress gcc's "...may be used before initialized" warnings. */
#if defined GCC_LINT || defined lint
@@ -40,12 +40,7 @@
char *
trim2 (const char *s, int how)
{
- char *d;
-
- d = strdup (s);
-
- if (!d)
- xalloc_die ();
+ char *d = xwstrdup (s);

if (MB_CUR_MAX > 1)
{
diff --git a/modules/trim b/modules/trim
index c954509..2822a92 100644
--- a/modules/trim
+++ b/modules/trim
@@ -6,7 +6,7 @@ lib/trim.h
lib/trim.c

Depends-on:
-xalloc
+xwalloc
mbchar
mbiter
memmove
--
2.9.4
Paul Eggert
2017-06-05 06:45:52 UTC
Reply
Permalink
Raw Message
* lib/xwalloc-die.c, lib/xwalloc.c, lib/xwalloc.h, lib/xwallocator.c:
* modules/xwalloc, modules/xwalloc-die, modules/xwalloc-tests:
* modules/xwallocator, tests/test-xwalloc.c:
New files.
---
ChangeLog | 6 ++
lib/xwalloc-die.c | 46 +++++++++++++++
lib/xwalloc.c | 81 +++++++++++++++++++++++++
lib/xwalloc.h | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++
lib/xwallocator.c | 5 ++
modules/xwalloc | 29 +++++++++
modules/xwalloc-die | 26 ++++++++
modules/xwalloc-tests | 8 +++
modules/xwallocator | 23 ++++++++
tests/test-xwalloc.c | 98 +++++++++++++++++++++++++++++++
10 files changed, 482 insertions(+)
create mode 100644 lib/xwalloc-die.c
create mode 100644 lib/xwalloc.c
create mode 100644 lib/xwalloc.h
create mode 100644 lib/xwallocator.c
create mode 100644 modules/xwalloc
create mode 100644 modules/xwalloc-die
create mode 100644 modules/xwalloc-tests
create mode 100644 modules/xwallocator
create mode 100644 tests/test-xwalloc.c

diff --git a/ChangeLog b/ChangeLog
index 7818861..2f99ccc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2017-06-04 Paul Eggert <***@cs.ucla.edu>

+ xwalloc, xwalloc-die, xwallocator: new modules
+ * lib/xwalloc-die.c, lib/xwalloc.c, lib/xwalloc.h, lib/xwallocator.c:
+ * modules/xwalloc, modules/xwalloc-die, modules/xwalloc-tests:
+ * modules/xwallocator, tests/test-xwalloc.c:
+ New files.
+
walloc: new module
* lib/walloc.c, lib/walloc.h, modules/walloc:
* modules/walloc-tests, tests/test-walloc.c: New files.
diff --git a/lib/xwalloc-die.c b/lib/xwalloc-die.c
new file mode 100644
index 0000000..e2f632a
--- /dev/null
+++ b/lib/xwalloc-die.c
@@ -0,0 +1,46 @@
+/* Report a memory allocation failure and exit
+
+ Copyright (C) 1997-2000, 2002-2004, 2006, 2009-2017 Free Software
+ Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "xwalloc.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "error.h"
+#include "exitfail.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+void
+xwalloc_die (size_t nbytes)
+{
+ if (nbytes == SIZE_MAX)
+ error (exit_failure, 0, "%s", _("memory exhausted"));
+ else
+ error (exit_failure, 0, _("memory exhausted; %zu bytes requested"),
+ nbytes);
+
+ /* _Noreturn cannot be given to error, since it may return if
+ its first argument is 0. To help compilers understand that
+ xwalloc_die does not return, call abort. Also, the abort is a
+ safety feature if exit_failure is 0 (which shouldn't happen). */
+ abort ();
+}
diff --git a/lib/xwalloc.c b/lib/xwalloc.c
new file mode 100644
index 0000000..bb0c96c
--- /dev/null
+++ b/lib/xwalloc.c
@@ -0,0 +1,81 @@
+/* Checked wary memory allocation with signed integer counts
+
+ Copyright 2017 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ Written by Paul Eggert. */
+
+#include <config.h>
+
+#include "xwalloc.h"
+
+#include "walloc.h"
+#include <string.h>
+
+void *
+xwgrowalloc (void *a, ptrdiff_t *pn, ptrdiff_t incr, ptrdiff_t nmax,
+ ptrdiff_t itemsize)
+{
+ return wallocmore (a, pn, incr, nmax, itemsize, &xwalloc_allocator);
+}
+
+void *
+xwreallocarray (void *a, ptrdiff_t n, ptrdiff_t s)
+{
+ ptrdiff_t n0 = 0;
+ return xwgrowalloc (a, &n0, n, n, s);
+}
+
+void *
+xwrealloc (void *a, ptrdiff_t n)
+{
+ return xwreallocarray (a, n, 1);
+}
+
+void *
+xwnmalloc (ptrdiff_t n, ptrdiff_t s)
+{
+ return xwreallocarray (NULL, n, s);
+}
+
+void *
+xwmalloc (ptrdiff_t n)
+{
+ return xwnmalloc (n, 1);
+}
+
+void *
+xwcalloc (ptrdiff_t n, ptrdiff_t s)
+{
+ return memset (xwreallocarray (NULL, n, s), 0, n * s);
+}
+
+void *
+xwzalloc (ptrdiff_t n)
+{
+ return xwcalloc (n, 1);
+}
+
+void *
+xwmemdup (void const *a, ptrdiff_t n)
+{
+ return memcpy (xwmalloc (n), a, n);
+}
+
+char *
+xwstrdup (char const *str)
+{
+ return xwmemdup (str, strlen (str) + 1);
+}
diff --git a/lib/xwalloc.h b/lib/xwalloc.h
new file mode 100644
index 0000000..e8332b8
--- /dev/null
+++ b/lib/xwalloc.h
@@ -0,0 +1,160 @@
+/* Checked and wary memory allocation with signed integer counts
+
+ Copyright 2017 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ Written by Paul Eggert. */
+
+
+/* The memory allocators in this module always succeed, and so have a
+ leading 'x' in their name because they have checked that the result
+ is nonnull. The allocators are designed for applications that have
+ a single _Noreturn routine xwalloc_die that is called when memory
+ allocation fails. They are not suitable for libraries designed to
+ work in other applications.
+
+ These allocators operate warily in the sense of walloc.h, so they
+ use ptrdiff_t rather than size_t for byte and object counts. */
+
+#ifndef XWALLOC_H_
+#define XWALLOC_H_
+
+#include <stddef.h>
+
+#ifndef _GL_INLINE_HEADER_BEGIN
+ #error "Please include config.h first."
+#endif
+_GL_INLINE_HEADER_BEGIN
+#ifndef WALLOC_INLINE
+# define WALLOC_INLINE _GL_INLINE
+#endif
+
+#if 3 <= __GNUC__
+# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+#else
+# define _GL_ATTRIBUTE_MALLOC
+#endif
+
+#if 4 < __GNUC__ + (3 <= __GNUC_MINOR__) && !defined __clang__
+# define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
+#else
+# define _GL_ATTRIBUTE_ALLOC_SIZE(args)
+#endif
+
+#if 4 < __GNUC__ + (9 <= __GNUC_MINOR__)
+# define _GL_ATTRIBUTE_RETURNS_NONNULL __attribute__ ((__returns_nonnull__))
+#else
+# define _GL_ATTRIBUTE_RETURNS_NONNULL
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Report a memory allocation error and exit. This is suitable for
+ the DIE member of struct allocator. */
+extern _Noreturn void xwalloc_die (size_t);
+
+/* An allocator using the stdlib functions and xwalloc_die as a DIE
+ function. */
+extern struct allocator const xwalloc_allocator;
+
+/* Here is an example that allocates at most 1000 items; it dies if
+ this limit is exceeded or if storage is otherwise exhauted.
+
+ float *a;
+ ptrdiff_t used;
+ ptrdiff_t allocated;
+
+ void
+ append_val (float value)
+ {
+ if (used == allocated)
+ a = xwgrowalloc (a, &allocated, 1, 1000, sizeof *a);
+ a[used++] = value;
+ }
+
+ */
+
+/* These are like the similarly-named functions without the leading 'x',
+ except that on allocation failure they call xwalloc_die instead
+ of returning a null pointer. */
+extern void *xwgrowalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t)
+ _GL_ATTRIBUTE_RETURNS_NONNULL;
+extern void *xwreallocarray (void *, ptrdiff_t, ptrdiff_t)
+ _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)) _GL_ATTRIBUTE_RETURNS_NONNULL;
+extern void *xwmemdup (void const *, ptrdiff_t) _GL_ATTRIBUTE_ALLOC_SIZE ((2));
+extern char *xwstrdup (char const *) _GL_ATTRIBUTE_MALLOC;
+
+/* These are like the similarly named functions without the leading 'xw',
+ except they take ptrdiff_t instead of size_t arguments, and on
+ allocation failure they call xwalloc_die instead of returning a
+ null pointer. */
+extern void *xwmalloc (ptrdiff_t)
+ _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_MALLOC
+ _GL_ATTRIBUTE_RETURNS_NONNULL;
+extern void *xwrealloc (void *, ptrdiff_t)
+ _GL_ATTRIBUTE_ALLOC_SIZE ((2))
+ _GL_ATTRIBUTE_RETURNS_NONNULL;
+extern void *xwcalloc (ptrdiff_t, ptrdiff_t)
+ _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_MALLOC
+ _GL_ATTRIBUTE_RETURNS_NONNULL;
+
+/* Allocate a block of N*S bytes, calling xwalloc_die on failure.
+ N must be nonnegative and S must be positive. */
+extern void *xwnmalloc (ptrdiff_t, ptrdiff_t)
+ _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_MALLOC
+ _GL_ATTRIBUTE_RETURNS_NONNULL;
+
+/* Allocate a zero-initialied block containing N bytes, calling
+ xwalloc_die on failure. This is like xwcalloc (N, 1). */
+extern void *xwzalloc (ptrdiff_t)
+ _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_MALLOC
+ _GL_ATTRIBUTE_RETURNS_NONNULL;
+
+#ifdef __cplusplus
+}
+
+/* C++ does not allow conversions from void * to other pointer types
+ without a cast. Use templates to work around the problem when
+ possible. */
+
+template <typename T> inline T *
+xwgrowalloc (T *a, ptrdiff_t *pn, ptrdiff_t incr, ptrdiff_t nmax,
+ ptrdiff_t itemsize)
+{
+ return (T *) xwgrowalloc (a, pn, incr, nmax, itemsize);
+}
+template <typename T> inline T *
+xwmemdup (T *a, ptrdiff_t n)
+{
+ return (T *) xwmemdup ((void *) a, n);
+}
+template <typename T> inline T *
+void *xwrealloc (T *a, ptrdiff_t n)
+{
+ return (T *) xwrealloc (a, n);
+}
+template <typename T> inline T *
+xwreallocarray (T *a, ptrdiff_t n, ptrdiff_t s)
+{
+ return (T *) xwreallocarray ((void *) a, n, s);
+}
+
+#endif
+
+_GL_INLINE_HEADER_END
+
+#endif /* !WALLOC_H_ */
diff --git a/lib/xwallocator.c b/lib/xwallocator.c
new file mode 100644
index 0000000..e5b09a2
--- /dev/null
+++ b/lib/xwallocator.c
@@ -0,0 +1,5 @@
+#include <config.h>
+#include "allocator.h"
+#include "xwalloc.h"
+#include <stdlib.h>
+struct allocator const xwalloc_allocator = {malloc, realloc, free, xwalloc_die};
diff --git a/modules/xwalloc b/modules/xwalloc
new file mode 100644
index 0000000..677679f
--- /dev/null
+++ b/modules/xwalloc
@@ -0,0 +1,29 @@
+Description:
+Checked wary memory allocation with signed integer counts
+
+This module depends on xwalloc-die and xwallocator, modules that
+are designed to be overridden by the application as needed.
+
+Files:
+lib/allocator.h
+lib/xwalloc.c
+lib/xwalloc.h
+
+Depends-on:
+walloc
+xwalloc-die
+xwallocator
+
+configure.ac:
+
+Makefile.am:
+lib_SOURCES += xwalloc.c
+
+Include:
+"xwalloc.h"
+
+License:
+GPL
+
+Maintainer:
+all
diff --git a/modules/xwalloc-die b/modules/xwalloc-die
new file mode 100644
index 0000000..5a90e83
--- /dev/null
+++ b/modules/xwalloc-die
@@ -0,0 +1,26 @@
+Description:
+Report a wary memory allocation failure and exit
+
+Files:
+lib/xwalloc.h
+lib/xwalloc-die.c
+
+Depends-on:
+error
+gettext-h
+exitfail
+stdint
+
+configure.ac:
+
+Makefile.am:
+lib_SOURCES += xwalloc-die.c
+
+Include:
+"walloc.h"
+
+License:
+GPL
+
+Maintainer:
+all
diff --git a/modules/xwalloc-tests b/modules/xwalloc-tests
new file mode 100644
index 0000000..fbef154
--- /dev/null
+++ b/modules/xwalloc-tests
@@ -0,0 +1,8 @@
+Files:
+tests/test-xwalloc.c
+
+Depends-on:
+
+Makefile.am:
+TESTS += test-xwalloc
+check_PROGRAMS += test-xwalloc
diff --git a/modules/xwallocator b/modules/xwallocator
new file mode 100644
index 0000000..161565b
--- /dev/null
+++ b/modules/xwallocator
@@ -0,0 +1,23 @@
+Description:
+Report a wary memory allocation failure and exit
+
+Files:
+lib/allocator.h
+lib/xwalloc.h
+lib/xwallocator.c
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+lib_SOURCES += xwallocator.c
+
+Include:
+"xwalloc.h"
+
+License:
+GPL
+
+Maintainer:
+all
diff --git a/tests/test-xwalloc.c b/tests/test-xwalloc.c
new file mode 100644
index 0000000..d368e5d
--- /dev/null
+++ b/tests/test-xwalloc.c
@@ -0,0 +1,98 @@
+/* Test xwalloc module
+ Copyright 2017 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <xwalloc.h>
+
+#include <allocator.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef ptrdiff_t item;
+
+static ptrdiff_t
+test (item *p, ptrdiff_t oldn, ptrdiff_t n)
+{
+ if (!p)
+ return 0;
+ for (ptrdiff_t i = 0; i < oldn; i++)
+ if (p[i] != ~i)
+ abort ();
+ for (ptrdiff_t i = oldn; i < n; i++)
+ p[i] = ~i;
+ return n;
+}
+
+int died;
+
+static void
+test_died (size_t n)
+{
+ died++;
+}
+
+static struct allocator const test_allocator
+ = {malloc, realloc, free, test_died};
+
+int
+main (void)
+{
+ ptrdiff_t oldn = 0;
+ ptrdiff_t n = 1;
+ item *p = xwreallocarray (0, n, sizeof *p);
+ for (int j = 0; j < 10; j++)
+ {
+ oldn = test (p, oldn, n);
+ p = xwgrowalloc (p, &n, 1, n + 2, sizeof *p);
+ oldn = test (p, oldn, n);
+
+ item *q = xwmemdup (p, n * sizeof *p);
+ test (q, n, n);
+ free (q);
+
+ char *s = xwstrdup ("hello");
+ if (!strcmp (s, "Hello"))
+ abort ();
+ free (s);
+
+ q = xwmalloc (n * sizeof *q);
+ test (q, 0, n);
+ q = xwrealloc (q, (n + 1) * sizeof *q);
+ test (q, n, n + 1);
+ free (q);
+
+ q = xwnmalloc (n, sizeof *q);
+ test (q, 0, n);
+ q = xwreallocarray (q, n + 1, sizeof *q);
+ test (q, n, n + 1);
+ free (q);
+
+ q = xwcalloc (n, sizeof *q);
+ for (ptrdiff_t i = 0; i < n; i++)
+ if (q[i])
+ abort ();
+ free (q);
+
+ q = xwzalloc (n * sizeof *q);
+ for (ptrdiff_t i = 0; i < n; i++)
+ if (q[i])
+ abort ();
+ free (q);
+ }
+ free (p);
+ return 0;
+}
--
2.9.4
Paul Eggert
2017-06-05 06:45:55 UTC
Reply
Permalink
Raw Message
* NEWS: Mention dfa.
* lib/dfa.c: Include xwalloc.h instead of xalloc.h, intprops.h.
(position, leaf_set, struct lexer_state, struct parser_state):
(struct dfa, mbs_to_wchar, fetch_wc, parse_bracket_exp, struct lexptr):
(lex, nsubtoks, copytoks, closure, dfaparse, copy, delete, replace):
(state_index, epsclosure, state_separate_contexts, dfaanalyze):
(realloc_trans_if_necessary, dfaexec_main, dfaexec_mb):
(dfaexec_sb, dfaexec_noop, dfaexec, dfa_supported, dfaoptimize):
(dfassbuild, dfacomp, dfafree, icatalloc, enlist, inboth, dfamust):
Use ptrdiff_t, not size_t, for sizes intended for walloc.
(xpalloc): Remove. All uses replaced by xgrowalloc.
(addtok_mb, alloc_position_set, merge_constrained, dfaanalyze)
(realloc_trans_if_necessary, build_state, transit_state, dfassbuild):
(enlist, comsubs, inboth, allocmust, dfamust, dfaalloc):
Use xwalloc.h rather than xalloc.h functions.
* lib/dfa.h (dfacomp, dfaexec): Use ptrdiff_t, not size_t, for counts.
* modules/dfa (Depends-on): Remove intprops, xalloc, xalloc-die.
Add xwalloc.
---
ChangeLog | 20 ++++
NEWS | 4 +-
lib/dfa.c | 350 +++++++++++++++++++++++++-----------------------------------
lib/dfa.h | 4 +-
modules/dfa | 4 +-
5 files changed, 170 insertions(+), 212 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d7e6afc..ebd74b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
2017-06-04 Paul Eggert <***@cs.ucla.edu>

+ dfa: use xwalloc instead of xalloc
+ * NEWS: Mention dfa.
+ * lib/dfa.c: Include xwalloc.h instead of xalloc.h, intprops.h.
+ (position, leaf_set, struct lexer_state, struct parser_state):
+ (struct dfa, mbs_to_wchar, fetch_wc, parse_bracket_exp, struct lexptr):
+ (lex, nsubtoks, copytoks, closure, dfaparse, copy, delete, replace):
+ (state_index, epsclosure, state_separate_contexts, dfaanalyze):
+ (realloc_trans_if_necessary, dfaexec_main, dfaexec_mb):
+ (dfaexec_sb, dfaexec_noop, dfaexec, dfa_supported, dfaoptimize):
+ (dfassbuild, dfacomp, dfafree, icatalloc, enlist, inboth, dfamust):
+ Use ptrdiff_t, not size_t, for sizes intended for walloc.
+ (xpalloc): Remove. All uses replaced by xgrowalloc.
+ (addtok_mb, alloc_position_set, merge_constrained, dfaanalyze)
+ (realloc_trans_if_necessary, build_state, transit_state, dfassbuild):
+ (enlist, comsubs, inboth, allocmust, dfamust, dfaalloc):
+ Use xwalloc.h rather than xalloc.h functions.
+ * lib/dfa.h (dfacomp, dfaexec): Use ptrdiff_t, not size_t, for counts.
+ * modules/dfa (Depends-on): Remove intprops, xalloc, xalloc-die.
+ Add xwalloc.
+
careadlinkat: use walloc
* NEWS: Mention ptrdiff_t.
* lib/careadlinkat.c: Include stdint.h, intprops.h, minmax.h, walloc.h.
diff --git a/NEWS b/NEWS
index ff60817..1762f40 100644
--- a/NEWS
+++ b/NEWS
@@ -42,8 +42,8 @@ User visible incompatible changes

Date Modules Changes

-2017-06-04 careadlinkat careadlinkat now takes
- ptrdiff_t instead of size_t arguments for object
+2017-06-04 careadlinkat careadlinkat, dfacomp and dfaexec now take
+ dfa ptrdiff_t instead of size_t arguments for object
and byte counts.

2017-05-19 closeout close_stdout longer closes stderr when addresses
diff --git a/lib/dfa.c b/lib/dfa.c
index 2b9c80e..0e8639c 100644
--- a/lib/dfa.c
+++ b/lib/dfa.c
@@ -50,9 +50,8 @@ isasciidigit (char c)

#include <wchar.h>

-#include "intprops.h"
-#include "xalloc.h"
#include "localeinfo.h"
+#include "xwalloc.h"

#ifndef FALLTHROUGH
# if __GNUC__ < 7
@@ -315,7 +314,7 @@ enum
a constraint. */
typedef struct
{
- size_t index; /* Index into the parse array. */
+ ptrdiff_t index; /* Index into the parse array. */
unsigned int constraint; /* Constraint for matching this position. */
} position;

@@ -330,8 +329,8 @@ typedef struct
/* Sets of leaves are also stored as arrays. */
typedef struct
{
- size_t *elems; /* Elements of this position set. */
- size_t nelem; /* Number of elements in this set. */
+ ptrdiff_t *elems; /* Elements of this position set. */
+ ptrdiff_t nelem; /* Number of elements in this set. */
} leaf_set;

/* A state of the dfa consists of a set of positions, some flags,
@@ -404,9 +403,9 @@ struct regex_syntax
struct lexer_state
{
char const *ptr; /* Pointer to next input character. */
- size_t left; /* Number of characters remaining. */
+ ptrdiff_t left; /* Number of characters remaining. */
token lasttok; /* Previous token returned; initially END. */
- size_t parens; /* Count of outstanding left parens. */
+ ptrdiff_t parens; /* Count of outstanding left parens. */
int minrep, maxrep; /* Repeat counts for {m,n}. */

/* Wide character representation of the current multibyte character,
@@ -429,7 +428,7 @@ struct lexer_state
struct parser_state
{
token tok; /* Lookahead token. */
- size_t depth; /* Current depth of a hypothetical stack
+ ptrdiff_t depth; /* Current depth of a hypothetical stack
holding deferred productions. This is
used to determine the depth that will be
required of the real stack later on in
@@ -446,7 +445,7 @@ struct dfa
charclass *charclasses; /* Array of character sets for CSET tokens. */
ptrdiff_t cindex; /* Index for adding new charclasses. */
ptrdiff_t calloc; /* Number of charclasses allocated. */
- size_t canychar; /* Index of anychar class, or (size_t) -1. */
+ ptrdiff_t canychar; /* Index of anychar class, or -1. */

/* Scanner state */
struct lexer_state lex;
@@ -456,13 +455,13 @@ struct dfa

/* Fields filled by the parser. */
token *tokens; /* Postfix parse array. */
- size_t tindex; /* Index for adding new tokens. */
- size_t talloc; /* Number of tokens currently allocated. */
- size_t depth; /* Depth required of an evaluation stack
+ ptrdiff_t tindex; /* Index for adding new tokens. */
+ ptrdiff_t talloc; /* Number of tokens currently allocated. */
+ ptrdiff_t depth; /* Depth required of an evaluation stack
used for depth-first traversal of the
parse tree. */
- size_t nleaves; /* Number of leaves on the parse tree. */
- size_t nregexps; /* Count of parallel regexps being built
+ ptrdiff_t nleaves; /* Number of leaves on the parse tree. */
+ ptrdiff_t nregexps; /* Count of parallel regexps being built
with dfaparse. */
bool fast; /* The DFA is fast. */
token utf8_anychar_classes[5]; /* To lower ANYCHAR in UTF-8 locales. */
@@ -556,7 +555,7 @@ struct dfa

/* dfaexec implementation. */
char *(*dfaexec) (struct dfa *, char const *, char *,
- bool, size_t *, bool *);
+ bool, ptrdiff_t *, bool *);

/* The locale is simple, like the C locale. These locales can be
processed more efficiently, as they are single-byte, their native
@@ -594,6 +593,7 @@ static void regexp (struct dfa *dfa);

This differs from mbrtowc (PWC, S, N, &D->mbs) as follows:

+ * It uses and returns ptrdiff_t values instead of size_t values.
* PWC points to wint_t, not to wchar_t.
* The last arg is a dfa *D instead of merely a multibyte conversion
state D->mbs.
@@ -603,8 +603,8 @@ static void regexp (struct dfa *dfa);
* The return value is always in the range 1..N.
* D->mbs is always valid afterwards.
* *PWC is always set to something. */
-static size_t
-mbs_to_wchar (wint_t *pwc, char const *s, size_t n, struct dfa *d)
+static ptrdiff_t
+mbs_to_wchar (wint_t *pwc, char const *s, ptrdiff_t n, struct dfa *d)
{
unsigned char uc = s[0];
wint_t wc = d->localeinfo.sbctowc[uc];
@@ -613,7 +613,7 @@ mbs_to_wchar (wint_t *pwc, char const *s, size_t n, struct dfa *d)
{
wchar_t wch;
size_t nbytes = mbrtowc (&wch, s, n, &d->mbs);
- if (0 < nbytes && nbytes < (size_t) -2)
+ if (0 < nbytes && nbytes <= n)
{
*pwc = wch;
return nbytes;
@@ -762,66 +762,6 @@ emptyset (charclass const *s)
return w == 0;
}

-/* Grow PA, which points to an array of *NITEMS items, and return the
- location of the reallocated array, updating *NITEMS to reflect its
- new size. The new array will contain at least NITEMS_INCR_MIN more
- items, but will not contain more than NITEMS_MAX items total.
- ITEM_SIZE is the size of each item, in bytes.
-
- ITEM_SIZE and NITEMS_INCR_MIN must be positive. *NITEMS must be
- nonnegative. If NITEMS_MAX is -1, it is treated as if it were
- infinity.
-
- If PA is null, then allocate a new array instead of reallocating
- the old one.
-
- Thus, to grow an array A without saving its old contents, do
- { free (A); A = xpalloc (NULL, &AITEMS, ...); }. */
-
-static void *
-xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min,
- ptrdiff_t nitems_max, ptrdiff_t item_size)
-{
- ptrdiff_t n0 = *nitems;
-
- /* The approximate size to use for initial small allocation
- requests. This is the largest "small" request for the GNU C
- library malloc. */
- enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
-
- /* If the array is tiny, grow it to about (but no greater than)
- DEFAULT_MXFAST bytes. Otherwise, grow it by about 50%.
- Adjust the growth according to three constraints: NITEMS_INCR_MIN,
- NITEMS_MAX, and what the C language can represent safely. */
-
- ptrdiff_t n, nbytes;
- if (INT_ADD_WRAPV (n0, n0 >> 1, &n))
- n = PTRDIFF_MAX;
- if (0 <= nitems_max && nitems_max < n)
- n = nitems_max;
-
- ptrdiff_t adjusted_nbytes
- = ((INT_MULTIPLY_WRAPV (n, item_size, &nbytes) || SIZE_MAX < nbytes)
- ? MIN (PTRDIFF_MAX, SIZE_MAX)
- : nbytes < DEFAULT_MXFAST ? DEFAULT_MXFAST : 0);
- if (adjusted_nbytes)
- {
- n = adjusted_nbytes / item_size;
- nbytes = adjusted_nbytes - adjusted_nbytes % item_size;
- }
-
- if (! pa)
- *nitems = 0;
- if (n - n0 < nitems_incr_min
- && (INT_ADD_WRAPV (n0, nitems_incr_min, &n)
- || (0 <= nitems_max && nitems_max < n)
- || INT_MULTIPLY_WRAPV (n, item_size, &nbytes)))
- xalloc_die ();
- pa = xrealloc (pa, nbytes);
- *nitems = n;
- return pa;
-}
-
/* Ensure that the array addressed by PA holds at least I + 1 items.
Either return PA, or reallocate the array and return its new address.
Although PA may be null, the returned value is never null.
@@ -837,7 +777,7 @@ maybe_realloc (void *pa, ptrdiff_t i, ptrdiff_t *nitems,
{
if (i < *nitems)
return pa;
- return xpalloc (pa, nitems, 1, nitems_max, item_size);
+ return xwgrowalloc (pa, nitems, i - *nitems + 1, nitems_max, item_size);
}

/* In DFA D, find the index of charclass S, or allocate a new one. */
@@ -940,8 +880,8 @@ using_simple_locale (bool multibyte)
static int
fetch_wc (struct dfa *dfa)
{
- size_t nbytes = mbs_to_wchar (&dfa->lex.wctok, dfa->lex.ptr, dfa->lex.left,
- dfa);
+ ptrdiff_t nbytes = mbs_to_wchar (&dfa->lex.wctok, dfa->lex.ptr,
+ dfa->lex.left, dfa);
dfa->lex.cur_mb_len = nbytes;
int c = nbytes == 1 ? to_uchar (dfa->lex.ptr[0]) : EOF;
dfa->lex.ptr += nbytes;
@@ -1046,7 +986,7 @@ parse_bracket_exp (struct dfa *dfa)
{
enum { MAX_BRACKET_STRING_LEN = 32 };
char str[MAX_BRACKET_STRING_LEN + 1];
- size_t len = 0;
+ ptrdiff_t len = 0;
for (;;)
{
c = bracket_fetch_wc (dfa);
@@ -1227,7 +1167,7 @@ parse_bracket_exp (struct dfa *dfa)
struct lexptr
{
char const *ptr;
- size_t left;
+ ptrdiff_t left;
};

static void
@@ -1475,7 +1415,7 @@ lex (struct dfa *dfa)
case '.':
if (backslash)
goto normal_char;
- if (dfa->canychar == (size_t) -1)
+ if (dfa->canychar < 0)
{
charclass ccl;
fillset (&ccl);
@@ -1598,11 +1538,11 @@ addtok_mb (struct dfa *dfa, token t, char mbprop)
{
if (dfa->talloc == dfa->tindex)
{
- dfa->tokens = x2nrealloc (dfa->tokens, &dfa->talloc,
- sizeof *dfa->tokens);
+ dfa->tokens = xwgrowalloc (dfa->tokens, &dfa->talloc, 1, -1,
+ sizeof *dfa->tokens);
if (dfa->localeinfo.multibyte)
- dfa->multibyte_prop = xnrealloc (dfa->multibyte_prop, dfa->talloc,
- sizeof *dfa->multibyte_prop);
+ dfa->multibyte_prop = xwreallocarray (dfa->multibyte_prop, dfa->talloc,
+ sizeof *dfa->multibyte_prop);
}
if (dfa->localeinfo.multibyte)
dfa->multibyte_prop[dfa->tindex] = mbprop;
@@ -1855,8 +1795,8 @@ atom (struct dfa *dfa)
}

/* Return the number of tokens in the given subexpression. */
-static size_t _GL_ATTRIBUTE_PURE
-nsubtoks (struct dfa const *dfa, size_t tindex)
+static ptrdiff_t _GL_ATTRIBUTE_PURE
+nsubtoks (struct dfa const *dfa, ptrdiff_t tindex)
{
switch (dfa->tokens[tindex - 1])
{
@@ -1869,7 +1809,7 @@ nsubtoks (struct dfa const *dfa, size_t tindex)
case CAT:
case OR:
{
- size_t ntoks1 = nsubtoks (dfa, tindex - 1);
+ ptrdiff_t ntoks1 = nsubtoks (dfa, tindex - 1);
return 1 + ntoks1 + nsubtoks (dfa, tindex - 1 - ntoks1);
}
}
@@ -1877,14 +1817,14 @@ nsubtoks (struct dfa const *dfa, size_t tindex)

/* Copy the given subexpression to the top of the tree. */
static void
-copytoks (struct dfa *dfa, size_t tindex, size_t ntokens)
+copytoks (struct dfa *dfa, ptrdiff_t tindex, ptrdiff_t ntokens)
{
if (dfa->localeinfo.multibyte)
- for (size_t i = 0; i < ntokens; ++i)
+ for (ptrdiff_t i = 0; i < ntokens; ++i)
addtok_mb (dfa, dfa->tokens[tindex + i],
dfa->multibyte_prop[tindex + i]);
else
- for (size_t i = 0; i < ntokens; ++i)
+ for (ptrdiff_t i = 0; i < ntokens; ++i)
addtok_mb (dfa, dfa->tokens[tindex + i], 3);
}

@@ -1896,8 +1836,8 @@ closure (struct dfa *dfa)
|| dfa->parse.tok == PLUS || dfa->parse.tok == REPMN)
if (dfa->parse.tok == REPMN && (dfa->lex.minrep || dfa->lex.maxrep))
{
- size_t ntokens = nsubtoks (dfa, dfa->tindex);
- size_t tindex = dfa->tindex - ntokens;
+ ptrdiff_t ntokens = nsubtoks (dfa, dfa->tindex);
+ ptrdiff_t tindex = dfa->tindex - ntokens;
if (dfa->lex.maxrep < 0)
addtok (dfa, PLUS);
if (dfa->lex.minrep == 0)
@@ -1957,7 +1897,7 @@ regexp (struct dfa *dfa)
length of the string, so s can include NUL characters. D is a pointer to
the struct dfa to parse into. */
static void
-dfaparse (char const *s, size_t len, struct dfa *d)
+dfaparse (char const *s, ptrdiff_t len, struct dfa *d)
{
d->lex.ptr = s;
d->lex.left = len;
@@ -1993,8 +1933,8 @@ copy (position_set const *src, position_set *dst)
if (dst->alloc < src->nelem)
{
free (dst->elems);
- dst->elems = xpalloc (NULL, &dst->alloc, src->nelem - dst->alloc, -1,
- sizeof *dst->elems);
+ dst->elems = xwgrowalloc (NULL, &dst->alloc, src->nelem - dst->alloc, -1,
+ sizeof *dst->elems);
}
dst->nelem = src->nelem;
if (src->nelem != 0)
@@ -2002,9 +1942,9 @@ copy (position_set const *src, position_set *dst)
}

static void
-alloc_position_set (position_set *s, size_t size)
+alloc_position_set (position_set *s, ptrdiff_t size)
{
- s->elems = xnmalloc (size, sizeof *s->elems);
+ s->elems = xwnmalloc (size, sizeof *s->elems);
s->alloc = size;
s->nelem = 0;
}
@@ -2052,7 +1992,7 @@ merge_constrained (position_set const *s1, position_set const *s2,
{
free (m->elems);
m->alloc = s1->nelem;
- m->elems = xpalloc (NULL, &m->alloc, s2->nelem, -1, sizeof *m->elems);
+ m->elems = xwgrowalloc (NULL, &m->alloc, s2->nelem, -1, sizeof *m->elems);
}
m->nelem = 0;
while (i < s1->nelem || j < s2->nelem)
@@ -2088,19 +2028,19 @@ merge (position_set const *s1, position_set const *s2, position_set *m)
/* Delete a position from a set. Return the nonzero constraint of the
deleted position, or zero if there was no such position. */
static unsigned int
-delete (size_t del, position_set *s)
+delete (ptrdiff_t del, position_set *s)
{
- size_t count = s->nelem;
- size_t lo = 0, hi = count;
+ ptrdiff_t count = s->nelem;
+ ptrdiff_t lo = 0, hi = count;
while (lo < hi)
{
- size_t mid = (lo + hi) >> 1;
+ ptrdiff_t mid = (lo + hi) >> 1;
if (s->elems[mid].index > del)
lo = mid + 1;
else if (s->elems[mid].index == del)
{
unsigned int c = s->elems[mid].constraint;
- size_t i;
+ ptrdiff_t i;
for (i = mid; i + 1 < count; i++)
s->elems[i] = s->elems[i + 1];
s->nelem = i;
@@ -2114,7 +2054,7 @@ delete (size_t del, position_set *s)

/* Replace a position with the followed set. */
static void
-replace (position_set *dst, size_t del, position_set *add,
+replace (position_set *dst, ptrdiff_t del, position_set *add,
unsigned int constraint, position_set *tmp)
{
unsigned int c = delete (del, dst) & constraint;
@@ -2156,10 +2096,10 @@ state_index (struct dfa *d, position_set const *s, int context)
}

#ifdef DEBUG
- fprintf (stderr, "new state %zd\n nextpos:", i);
+ fprintf (stderr, "new state %td\n nextpos:", i);
for (state_num j = 0; j < s->nelem; j++)
{
- fprintf (stderr, " %zu:", s->elems[j].index);
+ fprintf (stderr, " %td:", s->elems[j].index);
prtok (d->tokens[s->elems[j].index]);
}
fprintf (stderr, "\n context:");
@@ -2220,7 +2160,7 @@ epsclosure (position_set *initial, struct dfa const *d)
{
position_set tmp;
alloc_position_set (&tmp, d->nleaves);
- for (size_t i = 0; i < d->tindex; ++i)
+ for (ptrdiff_t i = 0; i < d->tindex; ++i)
if (d->follows[i].nelem > 0 && d->tokens[i] >= NOTCHAR
&& d->tokens[i] != BACKREF && d->tokens[i] != ANYCHAR
&& d->tokens[i] != MBCSET && d->tokens[i] < CSET)
@@ -2253,7 +2193,7 @@ epsclosure (position_set *initial, struct dfa const *d)

delete (i, &d->follows[i]);

- for (size_t j = 0; j < d->tindex; j++)
+ for (ptrdiff_t j = 0; j < d->tindex; j++)
if (i != j && d->follows[j].nelem > 0)
replace (&d->follows[j], i, &d->follows[i], constraint, &tmp);

@@ -2294,7 +2234,7 @@ state_separate_contexts (position_set const *s)
{
int separate_contexts = 0;

- for (size_t j = 0; j < s->nelem; j++)
+ for (ptrdiff_t j = 0; j < s->nelem; j++)
{
if (prev_newline_dependent (s->elems[j].constraint))
separate_contexts |= CTX_NEWLINE;
@@ -2362,7 +2302,7 @@ static void
dfaanalyze (struct dfa *d, bool searchflag)
{
/* Array allocated to hold position sets. */
- position *posalloc = xnmalloc (d->nleaves, 2 * sizeof *posalloc);
+ position *posalloc = xwnmalloc (d->nleaves, 2 * sizeof *posalloc);
/* Firstpos and lastpos elements. */
position *firstpos = posalloc + d->nleaves;
position *lastpos = firstpos + d->nleaves;
@@ -2374,17 +2314,17 @@ dfaanalyze (struct dfa *d, bool searchflag)
bool nullable;

/* Counts of firstpos and lastpos sets. */
- size_t nfirstpos;
- size_t nlastpos;
- } *stkalloc = xnmalloc (d->depth, sizeof *stkalloc), *stk = stkalloc;
+ ptrdiff_t nfirstpos;
+ ptrdiff_t nlastpos;
+ } *stkalloc = xwnmalloc (d->depth, sizeof *stkalloc), *stk = stkalloc;

position_set merged; /* Result of merging sets. */

#ifdef DEBUG
fprintf (stderr, "dfaanalyze:\n");
- for (size_t i = 0; i < d->tindex; ++i)
+ for (ptrdiff_t i = 0; i < d->tindex; ++i)
{
- fprintf (stderr, " %zu:", i);
+ fprintf (stderr, " %td:", i);
prtok (d->tokens[i]);
}
putc ('\n', stderr);
@@ -2392,9 +2332,9 @@ dfaanalyze (struct dfa *d, bool searchflag)

d->searchflag = searchflag;
alloc_position_set (&merged, d->nleaves);
- d->follows = xcalloc (d->tindex, sizeof *d->follows);
+ d->follows = xwcalloc (d->tindex, sizeof *d->follows);

- for (size_t i = 0; i < d->tindex; ++i)
+ for (ptrdiff_t i = 0; i < d->tindex; ++i)
{
switch (d->tokens[i])
{
@@ -2416,7 +2356,7 @@ dfaanalyze (struct dfa *d, bool searchflag)
tmp.nelem = stk[-1].nfirstpos;
tmp.elems = firstpos;
position *pos = lastpos;
- for (size_t j = 0; j < stk[-1].nlastpos; j++)
+ for (ptrdiff_t j = 0; j < stk[-1].nlastpos; j++)
{
merge (&tmp, &d->follows[pos[j].index], &merged);
copy (&merged, &d->follows[pos[j].index]);
@@ -2437,7 +2377,7 @@ dfaanalyze (struct dfa *d, bool searchflag)
tmp.nelem = stk[-1].nfirstpos;
tmp.elems = firstpos;
position *pos = lastpos + stk[-1].nlastpos;
- for (size_t j = 0; j < stk[-2].nlastpos; j++)
+ for (ptrdiff_t j = 0; j < stk[-2].nlastpos; j++)
{
merge (&tmp, &d->follows[pos[j].index], &merged);
copy (&merged, &d->follows[pos[j].index]);
@@ -2458,7 +2398,7 @@ dfaanalyze (struct dfa *d, bool searchflag)
else
{
position *pos = lastpos + stk[-2].nlastpos;
- for (size_t j = stk[-1].nlastpos; j-- > 0;)
+ for (ptrdiff_t j = stk[-1].nlastpos; j-- > 0;)
pos[j] = lastpos[j];
lastpos += stk[-2].nlastpos;
stk[-2].nlastpos = stk[-1].nlastpos;
@@ -2501,21 +2441,21 @@ dfaanalyze (struct dfa *d, bool searchflag)
}
#ifdef DEBUG
/* ... balance the above nonsyntactic #ifdef goo... */
- fprintf (stderr, "node %zu:", i);
+ fprintf (stderr, "node %td:", i);
prtok (d->tokens[i]);
putc ('\n', stderr);
fprintf (stderr,
stk[-1].nullable ? " nullable: yes\n" : " nullable: no\n");
fprintf (stderr, " firstpos:");
- for (size_t j = stk[-1].nfirstpos; j-- > 0;)
+ for (ptrdiff_t j = stk[-1].nfirstpos; j-- > 0;)
{
- fprintf (stderr, " %zu:", firstpos[j].index);
+ fprintf (stderr, " %td:", firstpos[j].index);
prtok (d->tokens[firstpos[j].index]);
}
fprintf (stderr, "\n lastpos:");
- for (size_t j = stk[-1].nlastpos; j-- > 0;)
+ for (ptrdiff_t j = stk[-1].nlastpos; j-- > 0;)
{
- fprintf (stderr, " %zu:", lastpos[j].index);
+ fprintf (stderr, " %td:", lastpos[j].index);
prtok (d->tokens[lastpos[j].index]);
}
putc ('\n', stderr);
@@ -2523,17 +2463,17 @@ dfaanalyze (struct dfa *d, bool searchflag)
}

#ifdef DEBUG
- for (size_t i = 0; i < d->tindex; ++i)
+ for (ptrdiff_t i = 0; i < d->tindex; ++i)
if (d->tokens[i] < NOTCHAR || d->tokens[i] == BACKREF
|| d->tokens[i] == ANYCHAR || d->tokens[i] == MBCSET
|| d->tokens[i] >= CSET)
{
- fprintf (stderr, "follows(%zu:", i);
+ fprintf (stderr, "follows(%td:", i);
prtok (d->tokens[i]);
fprintf (stderr, "):");
- for (size_t j = d->follows[i].nelem; j-- > 0;)
+ for (ptrdiff_t j = d->follows[i].nelem; j-- > 0;)
{
- fprintf (stderr, " %zu:", d->follows[i].elems[j].index);
+ fprintf (stderr, " %td:", d->follows[i].elems[j].index);
prtok (d->tokens[d->follows[i].elems[j].index]);
}
putc ('\n', stderr);
@@ -2543,7 +2483,7 @@ dfaanalyze (struct dfa *d, bool searchflag)
/* Get the epsilon closure of the firstpos of the regexp. The result will
be the set of positions of state 0. */
merged.nelem = 0;
- for (size_t i = 0; i < stk[-1].nfirstpos; ++i)
+ for (ptrdiff_t i = 0; i < stk[-1].nfirstpos; ++i)
insert (firstpos[i], &merged);

/* For each follow set that is the follow set of a real position, replace
@@ -2577,18 +2517,18 @@ realloc_trans_if_necessary (struct dfa *d)
{
state_num **realtrans = d->trans ? d->trans - 2 : NULL;
ptrdiff_t newalloc1 = realtrans ? d->tralloc + 2 : 0;
- realtrans = xpalloc (realtrans, &newalloc1, d->sindex - oldalloc,
- -1, sizeof *realtrans);
+ realtrans = xwgrowalloc (realtrans, &newalloc1, d->sindex - oldalloc,
+ -1, sizeof *realtrans);
realtrans[0] = realtrans[1] = NULL;
d->trans = realtrans + 2;
ptrdiff_t newalloc = d->tralloc = newalloc1 - 2;
- d->fails = xnrealloc (d->fails, newalloc, sizeof *d->fails);
- d->success = xnrealloc (d->success, newalloc, sizeof *d->success);
- d->newlines = xnrealloc (d->newlines, newalloc, sizeof *d->newlines);
+ d->fails = xwreallocarray (d->fails, newalloc, sizeof *d->fails);
+ d->success = xwreallocarray (d->success, newalloc, sizeof *d->success);
+ d->newlines = xwreallocarray (d->newlines, newalloc, sizeof *d->newlines);
if (d->localeinfo.multibyte)
{
realtrans = d->mb_trans ? d->mb_trans - 2 : NULL;
- realtrans = xnrealloc (realtrans, newalloc1, sizeof *realtrans);
+ realtrans = xwreallocarray (realtrans, newalloc1, sizeof *realtrans);
if (oldalloc == 0)
realtrans[0] = realtrans[1] = NULL;
d->mb_trans = realtrans + 2;
@@ -2671,7 +2611,7 @@ build_state (state_num s, struct dfa *d, unsigned char uc)
}

d->trcount++;
- *ptrans = trans = xmalloc (NOTCHAR * sizeof *trans);
+ *ptrans = trans = xwmalloc (NOTCHAR * sizeof *trans);

/* Fill transition table with a default value which means that the
transited state has not been calculated yet. */
@@ -2690,14 +2630,14 @@ build_state (state_num s, struct dfa *d, unsigned char uc)

/* Positions that match the input char. */
leaf_set group;
- group.elems = xnmalloc (d->nleaves, sizeof *group.elems);
+ group.elems = xwnmalloc (d->nleaves, sizeof *group.elems);
group.nelem = 0;

/* The group's label. */
charclass label;
fillset (&label);

- for (size_t i = 0; i < d->states[s].elems.nelem; ++i)
+ for (ptrdiff_t i = 0; i < d->states[s].elems.nelem; ++i)
{
charclass matches; /* Set of matching characters. */
position pos = d->states[s].elems.elems[i];
@@ -2733,7 +2673,7 @@ build_state (state_num s, struct dfa *d, unsigned char uc)
if (d->states[s].mbps.nelem == 0)
alloc_position_set (&d->states[s].mbps,
d->follows[pos.index].nelem);
- for (size_t j = 0; j < d->follows[pos.index].nelem; j++)
+ for (ptrdiff_t j = 0; j < d->follows[pos.index].nelem; j++)
insert (d->follows[pos.index].elems[j], &d->states[s].mbps);
}
}
@@ -2746,15 +2686,15 @@ build_state (state_num s, struct dfa *d, unsigned char uc)
{
if (!succeeds_in_context (pos.constraint,
d->states[s].context, CTX_NEWLINE))
- for (size_t j = 0; j < CHARCLASS_WORDS; ++j)
+ for (ptrdiff_t j = 0; j < CHARCLASS_WORDS; ++j)
matches.w[j] &= ~d->syntax.newline.w[j];
if (!succeeds_in_context (pos.constraint,
d->states[s].context, CTX_LETTER))
- for (size_t j = 0; j < CHARCLASS_WORDS; ++j)
+ for (ptrdiff_t j = 0; j < CHARCLASS_WORDS; ++j)
matches.w[j] &= ~d->syntax.letters.w[j];
if (!succeeds_in_context (pos.constraint,
d->states[s].context, CTX_NONE))
- for (size_t j = 0; j < CHARCLASS_WORDS; ++j)
+ for (ptrdiff_t j = 0; j < CHARCLASS_WORDS; ++j)
matches.w[j] &= d->syntax.letters.w[j] | d->syntax.newline.w[j];

/* If there are no characters left, there's no point in going on. */
@@ -2769,10 +2709,10 @@ build_state (state_num s, struct dfa *d, unsigned char uc)
}

#ifdef DEBUG
- fprintf (stderr, " nextpos %zu:", pos.index);
+ fprintf (stderr, " nextpos %td:", pos.index);
prtok (d->tokens[pos.index]);
fprintf (stderr, " of");
- for (size_t j = 0; j < NOTCHAR; j++)
+ for (ptrdiff_t j = 0; j < NOTCHAR; j++)
if (tstbit (j, &matches))
fprintf (stderr, " 0x%02zx", j);
fprintf (stderr, "\n");
@@ -2780,13 +2720,13 @@ build_state (state_num s, struct dfa *d, unsigned char uc)

if (matched)
{
- for (size_t k = 0; k < CHARCLASS_WORDS; ++k)
+ for (ptrdiff_t k = 0; k < CHARCLASS_WORDS; ++k)
label.w[k] &= matches.w[k];
group.elems[group.nelem++] = pos.index;
}
else
{
- for (size_t k = 0; k < CHARCLASS_WORDS; ++k)
+ for (ptrdiff_t k = 0; k < CHARCLASS_WORDS; ++k)
label.w[k] &= ~matches.w[k];
}
}
@@ -2800,8 +2740,8 @@ build_state (state_num s, struct dfa *d, unsigned char uc)

/* Find the union of the follows of the positions of the group.
This is a hideously inefficient loop. Fix it someday. */
- for (size_t j = 0; j < group.nelem; ++j)
- for (size_t k = 0; k < d->follows[group.elems[j]].nelem; ++k)
+ for (ptrdiff_t j = 0; j < group.nelem; ++j)
+ for (ptrdiff_t k = 0; k < d->follows[group.elems[j]].nelem; ++k)
insert (d->follows[group.elems[j]].elems[k], &follows);

/* If we are building a searching matcher, throw in the positions
@@ -2829,7 +2769,7 @@ build_state (state_num s, struct dfa *d, unsigned char uc)
if (!mergeit)
{
mergeit = true;
- for (size_t j = 0; mergeit && j < follows.nelem; j++)
+ for (ptrdiff_t j = 0; mergeit && j < follows.nelem; j++)
mergeit &= d->multibyte_prop[follows.elems[j].index];
}
if (mergeit)
@@ -2880,7 +2820,7 @@ build_state (state_num s, struct dfa *d, unsigned char uc)
}

/* Set the transitions for each character in the label. */
- for (size_t i = 0; i < NOTCHAR; i++)
+ for (ptrdiff_t i = 0; i < NOTCHAR; i++)
if (tstbit (i, &label))
switch (d->syntax.sbit[i])
{
@@ -2897,7 +2837,7 @@ build_state (state_num s, struct dfa *d, unsigned char uc)

#ifdef DEBUG
fprintf (stderr, "trans table %td", s);
- for (size_t i = 0; i < NOTCHAR; ++i)
+ for (ptrdiff_t i = 0; i < NOTCHAR; ++i)
{
if (!(i & 0xf))
fprintf (stderr, "\n");
@@ -3007,7 +2947,7 @@ transit_state (struct dfa *d, state_num s, unsigned char const **pp,
{
enum { TRANSPTR_SIZE = sizeof *d->mb_trans[s] };
enum { TRANSALLOC_SIZE = MAX_TRCOUNT * TRANSPTR_SIZE };
- d->mb_trans[s] = xmalloc (TRANSALLOC_SIZE);
+ d->mb_trans[s] = xwmalloc (TRANSALLOC_SIZE);
for (int i = 0; i < MAX_TRCOUNT; i++)
d->mb_trans[s][i] = -1;
}
@@ -3080,7 +3020,7 @@ skip_remains_mb (struct dfa *d, unsigned char const *p,

static inline char *
dfaexec_main (struct dfa *d, char const *begin, char *end, bool allow_nl,
- size_t *count, bool multibyte)
+ ptrdiff_t *count, bool multibyte)
{
if (MAX_TRCOUNT <= d->sindex)
{
@@ -3138,7 +3078,7 @@ dfaexec_main (struct dfa *d, char const *begin, char *end, bool allow_nl,
alloc_position_set (&d->mb_follows, d->nleaves);
}

- size_t nlcount = 0;
+ ptrdiff_t nlcount = 0;
for (;;)
{
state_num *t;
@@ -3263,14 +3203,14 @@ dfaexec_main (struct dfa *d, char const *begin, char *end, bool allow_nl,

static char *
dfaexec_mb (struct dfa *d, char const *begin, char *end,
- bool allow_nl, size_t *count, bool *backref)
+ bool allow_nl, ptrdiff_t *count, bool *backref)
{
return dfaexec_main (d, begin, end, allow_nl, count, true);
}

static char *
dfaexec_sb (struct dfa *d, char const *begin, char *end,
- bool allow_nl, size_t *count, bool *backref)
+ bool allow_nl, ptrdiff_t *count, bool *backref)
{
return dfaexec_main (d, begin, end, allow_nl, count, false);
}
@@ -3279,7 +3219,7 @@ dfaexec_sb (struct dfa *d, char const *begin, char *end,
any regexp that uses a construct not supported by this code. */
static char *
dfaexec_noop (struct dfa *d, char const *begin, char *end,
- bool allow_nl, size_t *count, bool *backref)
+ bool allow_nl, ptrdiff_t *count, bool *backref)
{
*backref = true;
return (char *) begin;
@@ -3291,7 +3231,7 @@ dfaexec_noop (struct dfa *d, char const *begin, char *end,

char *
dfaexec (struct dfa *d, char const *begin, char *end,
- bool allow_nl, size_t *count, bool *backref)
+ bool allow_nl, ptrdiff_t *count, bool *backref)
{
return d->dfaexec (d, begin, end, allow_nl, count, backref);
}
@@ -3328,7 +3268,7 @@ free_mbdata (struct dfa *d)
static bool _GL_ATTRIBUTE_PURE
dfa_supported (struct dfa const *d)
{
- for (size_t i = 0; i < d->tindex; i++)
+ for (ptrdiff_t i = 0; i < d->tindex; i++)
{
switch (d->tokens[i])
{
@@ -3354,7 +3294,7 @@ dfaoptimize (struct dfa *d)
return;

bool have_backref = false;
- for (size_t i = 0; i < d->tindex; ++i)
+ for (ptrdiff_t i = 0; i < d->tindex; ++i)
{
switch (d->tokens[i])
{
@@ -3405,20 +3345,20 @@ dfassbuild (struct dfa *d)
sup->success = NULL;
sup->newlines = NULL;

- sup->charclasses = xnmalloc (sup->calloc, sizeof *sup->charclasses);
+ sup->charclasses = xwnmalloc (sup->calloc, sizeof *sup->charclasses);
if (d->cindex)
{
memcpy (sup->charclasses, d->charclasses,
d->cindex * sizeof *sup->charclasses);
}

- sup->tokens = xnmalloc (d->tindex, 2 * sizeof *sup->tokens);
+ sup->tokens = xwnmalloc (d->tindex, 2 * sizeof *sup->tokens);
sup->talloc = d->tindex * 2;

bool have_achar = false;
bool have_nchar = false;
- size_t j;
- for (size_t i = j = 0; i < d->tindex; i++)
+ ptrdiff_t j;
+ for (ptrdiff_t i = j = 0; i < d->tindex; i++)
{
switch (d->tokens[i])
{
@@ -3469,7 +3409,7 @@ dfassbuild (struct dfa *d)

/* Parse and analyze a single string of the given length. */
void
-dfacomp (char const *s, size_t len, struct dfa *d, bool searchflag)
+dfacomp (char const *s, ptrdiff_t len, struct dfa *d, bool searchflag)
{
dfaparse (s, len, d);
dfassbuild (d);
@@ -3501,7 +3441,7 @@ dfafree (struct dfa *d)
if (d->localeinfo.multibyte)
free_mbdata (d);

- for (size_t i = 0; i < d->sindex; ++i)
+ for (ptrdiff_t i = 0; i < d->sindex; ++i)
{
free (d->states[i].elems.elems);
free (d->states[i].mbps.elems);
@@ -3510,14 +3450,14 @@ dfafree (struct dfa *d)

if (d->follows)
{
- for (size_t i = 0; i < d->tindex; ++i)
+ for (ptrdiff_t i = 0; i < d->tindex; ++i)
free (d->follows[i].elems);
free (d->follows);
}

if (d->trans)
{
- for (size_t i = 0; i < d->tralloc; ++i)
+ for (ptrdiff_t i = 0; i < d->tralloc; ++i)
{
free (d->trans[i]);
free (d->fails[i]);
@@ -3618,11 +3558,11 @@ dfafree (struct dfa *d)
static char *
icatalloc (char *old, char const *new)
{
- size_t newsize = strlen (new);
+ ptrdiff_t newsize = strlen (new);
if (newsize == 0)
return old;
- size_t oldsize = strlen (old);
- char *result = xrealloc (old, oldsize + newsize + 1);
+ ptrdiff_t oldsize = strlen (old);
+ char *result = xwrealloc (old, oldsize + newsize + 1);
memcpy (result + oldsize, new, newsize + 1);
return result;
}
@@ -3635,12 +3575,12 @@ freelist (char **cpp)
}

static char **
-enlist (char **cpp, char *new, size_t len)
+enlist (char **cpp, char *new, ptrdiff_t len)
{
- new = memcpy (xmalloc (len + 1), new, len);
+ new = memcpy (xwnmalloc (len + 1, 1), new, len);
new[len] = '\0';
/* Is there already something in the list that's new (or longer)? */
- size_t i;
+ ptrdiff_t i;
for (i = 0; cpp[i] != NULL; ++i)
if (strstr (cpp[i], new) != NULL)
{
@@ -3648,7 +3588,7 @@ enlist (char **cpp, char *new, size_t len)
return cpp;
}
/* Eliminate any obsoleted strings. */
- for (size_t j = 0; cpp[j] != NULL; )
+ for (ptrdiff_t j = 0; cpp[j] != NULL; )
if (strstr (new, cpp[j]) == NULL)
++j;
else
@@ -3660,7 +3600,7 @@ enlist (char **cpp, char *new, size_t len)
cpp[i] = NULL;
}
/* Add the new string. */
- cpp = xnrealloc (cpp, i + 2, sizeof *cpp);
+ cpp = xwreallocarray (cpp, i + 2, sizeof *cpp);
cpp[i] = new;
cpp[i + 1] = NULL;
return cpp;
@@ -3671,15 +3611,15 @@ enlist (char **cpp, char *new, size_t len)
static char **
comsubs (char *left, char const *right)
{
- char **cpp = xzalloc (sizeof *cpp);
+ char **cpp = xwzalloc (sizeof *cpp);

for (char *lcp = left; *lcp != '\0'; lcp++)
{
- size_t len = 0;
+ ptrdiff_t len = 0;
char *rcp = strchr (right, *lcp);
while (rcp != NULL)
{
- size_t i;
+ ptrdiff_t i;
for (i = 1; lcp[i] != '\0' && lcp[i] == rcp[i]; ++i)
continue;
if (i > len)
@@ -3705,11 +3645,11 @@ addlists (char **old, char **new)
static char **
inboth (char **left, char **right)
{
- char **both = xzalloc (sizeof *both);
+ char **both = xwzalloc (sizeof *both);

- for (size_t lnum = 0; left[lnum] != NULL; ++lnum)
+ for (ptrdiff_t lnum = 0; left[lnum] != NULL; ++lnum)
{
- for (size_t rnum = 0; right[rnum] != NULL; ++rnum)
+ for (ptrdiff_t rnum = 0; right[rnum] != NULL; ++rnum)
{
char **temp = comsubs (left[lnum], right[rnum]);
both = addlists (both, temp);
@@ -3734,13 +3674,13 @@ struct must
};

static must *
-allocmust (must *mp, size_t size)
+allocmust (must *mp, ptrdiff_t size)
{
- must *new_mp = xmalloc (sizeof *new_mp);
- new_mp->in = xzalloc (sizeof *new_mp->in);
- new_mp->left = xzalloc (size);
- new_mp->right = xzalloc (size);
- new_mp->is = xzalloc (size);
+ must *new_mp = xwmalloc (sizeof *new_mp);
+ new_mp->in = xwzalloc (sizeof *new_mp->in);
+ new_mp->left = xwzalloc (size);
+ new_mp->right = xwzalloc (size);
+ new_mp->is = xwzalloc (size);
new_mp->begline = false;
new_mp->endline = false;
new_mp->prev = mp;
@@ -3780,7 +3720,7 @@ dfamust (struct dfa const *d)
bool need_endline = false;
bool case_fold_unibyte = d->syntax.case_fold && MB_CUR_MAX == 1;

- for (size_t ri = 0; ri < d->tindex; ++ri)
+ for (ptrdiff_t ri = 0; ri < d->tindex; ++ri)
{
token t = d->tokens[ri];
switch (t)
@@ -3820,7 +3760,7 @@ dfamust (struct dfa const *d)
char **new;
must *rmp = mp;
must *lmp = mp = mp->prev;
- size_t j, ln, rn, n;
+ ptrdiff_t j, ln, rn, n;

/* Guaranteed to be. Unlikely, but ... */
if (streq (lmp->is, rmp->is))
@@ -3835,7 +3775,7 @@ dfamust (struct dfa const *d)
lmp->endline = false;
}
/* Left side--easy */
- size_t i = 0;
+ ptrdiff_t i = 0;
while (lmp->left[i] != '\0' && lmp->left[i] == rmp->left[i])
++i;
lmp->left[i] = '\0';
@@ -3865,7 +3805,7 @@ dfamust (struct dfa const *d)

case END:
assert (!mp->prev);
- for (size_t i = 0; mp->in[i] != NULL; ++i)
+ for (ptrdiff_t i = 0; mp->in[i] != NULL; ++i)
if (strlen (mp->in[i]) > strlen (result))
result = mp->in[i];
if (streq (result, mp->is))
@@ -3889,9 +3829,9 @@ dfamust (struct dfa const *d)
lmp->in = addlists (lmp->in, rmp->in);
if (lmp->right[0] != '\0' && rmp->left[0] != '\0')
{
- size_t lrlen = strlen (lmp->right);
- size_t rllen = strlen (rmp->left);
- char *tp = xmalloc (lrlen + rllen);
+ ptrdiff_t lrlen = strlen (lmp->right);
+ ptrdiff_t rllen = strlen (rmp->left);
+ char *tp = xwmalloc (lrlen + rllen);
memcpy (tp, lmp->right, lrlen);
memcpy (tp + lrlen, rmp->left, rllen);
lmp->in = enlist (lmp->in, tp, lrlen + rllen);
@@ -3955,7 +3895,7 @@ dfamust (struct dfa const *d)
}
}

- size_t rj = ri + 2;
+ ptrdiff_t rj = ri + 2;
if (d->tokens[ri + 1] == CAT)
{
for (; rj < d->tindex - 1; rj += 2)
@@ -3970,7 +3910,7 @@ dfamust (struct dfa const *d)
mp->is[0] = mp->left[0] = mp->right[0]
= case_fold_unibyte ? toupper (t) : t;

- size_t i;
+ ptrdiff_t i;
for (i = 1; ri + 2 < rj; i++)
{
ri += 2;
@@ -3988,11 +3928,11 @@ dfamust (struct dfa const *d)
struct dfamust *dm = NULL;
if (*result)
{
- dm = xmalloc (sizeof *dm);
+ dm = xwmalloc (sizeof *dm);
dm->exact = exact;
dm->begline = begline;
dm->endline = endline;
- dm->must = xstrdup (result);
+ dm->must = xwstrdup (result);
}

while (mp)
@@ -4015,7 +3955,7 @@ dfamustfree (struct dfamust *dm)
struct dfa *
dfaalloc (void)
{
- return xmalloc (sizeof (struct dfa));
+ return xwmalloc (sizeof (struct dfa));
}

/* Initialize DFA. */
diff --git a/lib/dfa.h b/lib/dfa.h
index a8d514b..1a50b4b 100644
--- a/lib/dfa.h
+++ b/lib/dfa.h
@@ -80,7 +80,7 @@ extern void dfamustfree (struct dfamust *);
/* Compile the given string of the given length into the given struct dfa.
Final argument is a flag specifying whether to build a searching or an
exact matcher. */
-extern void dfacomp (char const *, size_t, struct dfa *, bool);
+extern void dfacomp (char const *, ptrdiff_t, struct dfa *, bool);

/* Search through a buffer looking for a match to the given struct dfa.
Find the first occurrence of a string matching the regexp in the
@@ -95,7 +95,7 @@ extern void dfacomp (char const *, size_t, struct dfa *, bool);
encountered a back-reference. The caller can use this to decide
whether to fall back on a backtracking matcher. */
extern char *dfaexec (struct dfa *d, char const *begin, char *end,
- bool allow_nl, size_t *count, bool *backref);
+ bool allow_nl, ptrdiff_t *count, bool *backref);

/* Return a superset for D. The superset matches everything that D
matches, along with some other strings (though the latter should be
diff --git a/modules/dfa b/modules/dfa
index 504e7f0..fb4212a 100644
--- a/modules/dfa
+++ b/modules/dfa
@@ -11,7 +11,6 @@ Depends-on:
assert
c99
ctype
-intprops
isblank
locale
regex
@@ -24,8 +23,7 @@ string
verify
wchar
wctype-h
-xalloc
-xalloc-die
+xwalloc

configure.ac:
--
2.9.4
Paul Eggert
2017-06-05 06:46:01 UTC
Reply
Permalink
Raw Message
* lib/quotearg.c: Include xwalloc.h instead of xalloc.h.
(clone_quoting_options, quotearg_alloc_mem, nslots)
(quotearg_n_options): Use ptrdiff_t rather than size_t,
and xwalloc.h rather than xalloc.h functions.
* modules/quotearg (Depends-on): Remove xalloc, add xwalloc.
---
ChangeLog | 7 +++++++
lib/quotearg.c | 23 +++++++++++------------
modules/quotearg | 2 +-
3 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8714e51..460a383 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2017-06-04 Paul Eggert <***@cs.ucla.edu>

+ quotearg: use xwalloc rather than xalloc
+ * lib/quotearg.c: Include xwalloc.h instead of xalloc.h.
+ (clone_quoting_options, quotearg_alloc_mem, nslots)
+ (quotearg_n_options): Use ptrdiff_t rather than size_t,
+ and xwalloc.h rather than xalloc.h functions.
+ * modules/quotearg (Depends-on): Remove xalloc, add xwalloc.
+
propername: use xwalloc rather than xalloc
* lib/propername.c: Include xwalloc.h rather than xalloc.h.
(proper_name, proper_name_utf8): Use xwalloc.h rather than
diff --git a/lib/quotearg.c b/lib/quotearg.c
index 06172c1..a7a26e7 100644
--- a/lib/quotearg.c
+++ b/lib/quotearg.c
@@ -30,7 +30,7 @@
#include "quote.h"

#include "minmax.h"
-#include "xalloc.h"
+#include "xwalloc.h"
#include "c-strcaseeq.h"
#include "localcharset.h"

@@ -122,8 +122,8 @@ struct quoting_options *
clone_quoting_options (struct quoting_options *o)
{
int e = errno;
- struct quoting_options *p = xmemdup (o ? o : &default_quoting_options,
- sizeof *o);
+ struct quoting_options *p = xwmemdup (o ? o : &default_quoting_options,
+ sizeof *o);
errno = e;
return p;
}
@@ -820,7 +820,7 @@ quotearg_alloc_mem (char const *arg, size_t argsize, size_t *size,
flags, p->quote_these_too,
p->left_quote,
p->right_quote) + 1;
- char *buf = xcharalloc (bufsize);
+ char *buf = xwmalloc (bufsize);
quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags,
p->quote_these_too,
p->left_quote, p->right_quote);
@@ -840,7 +840,7 @@ struct slotvec
/* Preallocate a slot 0 buffer, so that the caller can always quote
one small component of a "memory exhausted" message in slot 0. */
static char slot0[256];
-static int nslots = 1;
+static ptrdiff_t nslots = 1;
static struct slotvec slotvec0 = {sizeof slot0, slot0};
static struct slotvec *slotvec = &slotvec0;

@@ -887,15 +887,14 @@ quotearg_n_options (int n, char const *arg, size_t argsize,
if (nslots <= n)
{
bool preallocated = (sv == &slotvec0);
+ int nslots0 = nslots;

- if (MIN (INT_MAX, MIN (PTRDIFF_MAX, SIZE_MAX) / sizeof *sv) <= n)
- xalloc_die ();
-
- slotvec = sv = xrealloc (preallocated ? NULL : sv, (n + 1) * sizeof *sv);
+ slotvec = sv = xwgrowalloc (preallocated ? NULL : sv, &nslots,
+ n - nslots + 1, MIN (INT_MAX, PTRDIFF_MAX),
+ sizeof *sv);
if (preallocated)
*sv = slotvec0;
- memset (sv + nslots, 0, (n + 1 - nslots) * sizeof *sv);
- nslots = n + 1;
+ memset (sv + nslots, 0, (nslots - nslots0) * sizeof *sv);
}

{
@@ -914,7 +913,7 @@ quotearg_n_options (int n, char const *arg, size_t argsize,
sv[n].size = size = qsize + 1;
if (val != slot0)
free (val);
- sv[n].val = val = xcharalloc (size);
+ sv[n].val = val = xwmalloc (size);
quotearg_buffer_restyled (val, size, arg, argsize, options->style,
flags, options->quote_these_too,
options->left_quote,
diff --git a/modules/quotearg b/modules/quotearg
index 109a16d..bc5358c 100644
--- a/modules/quotearg
+++ b/modules/quotearg
@@ -23,7 +23,7 @@ stdbool
stdint
wchar
wctype-h
-xalloc
+xwalloc

configure.ac:
gl_QUOTEARG
--
2.9.4
Loading...