common: New function xreallocarray

* common/miscellaneous.c (gnupg_reallocarray): New.
(xreallocarray): New.
--

Taken from libgpg-error so that we can build with older versions of
libgpg-error.
This commit is contained in:
Werner Koch 2020-03-05 16:23:52 +01:00
parent 449b331952
commit f0d034ebf4
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
2 changed files with 63 additions and 0 deletions

View File

@ -117,6 +117,65 @@ xoutofcore (void)
}
/* This is safe version of realloc useful for reallocing a calloced
* array. There are two ways to call it: The first example
* reallocates the array A to N elements each of SIZE but does not
* clear the newly allocated elements:
*
* p = gpgrt_reallocarray (a, n, n, nsize);
*
* Note that when NOLD is larger than N no cleaning is needed anyway.
* The second example reallocates an array of size NOLD to N elements
* each of SIZE but clear the newly allocated elements:
*
* p = gpgrt_reallocarray (a, nold, n, nsize);
*
* Note that gnupg_reallocarray (NULL, 0, n, nsize) is equivalent to
* gcry_calloc (n, nsize).
*/
void *
gnupg_reallocarray (void *a, size_t oldnmemb, size_t nmemb, size_t size)
{
size_t oldbytes, bytes;
char *p;
bytes = nmemb * size; /* size_t is unsigned so the behavior on overflow
* is defined. */
if (size && bytes / size != nmemb)
{
gpg_err_set_errno (ENOMEM);
return NULL;
}
p = gcry_realloc (a, bytes);
if (p && oldnmemb < nmemb)
{
/* OLDNMEMBS is lower than NMEMB thus the user asked for a
calloc. Clear all newly allocated members. */
oldbytes = oldnmemb * size;
if (size && oldbytes / size != oldnmemb)
{
xfree (p);
gpg_err_set_errno (ENOMEM);
return NULL;
}
memset (p + oldbytes, 0, bytes - oldbytes);
}
return p;
}
/* Die-on-error version of gnupg_reallocarray. */
void *
xreallocarray (void *a, size_t oldnmemb, size_t nmemb, size_t size)
{
void *p = gnupg_reallocarray (a, oldnmemb, nmemb, size);
if (!p)
xoutofcore ();
return p;
}
/* A wrapper around gcry_cipher_algo_name to return the string
"AES-128" instead of "AES". Given that we have an alias in
libgcrypt for it, it does not harm to too much to return this other

View File

@ -314,6 +314,10 @@ void setup_libgcrypt_logging (void);
/* Print an out of core message and die. */
void xoutofcore (void);
/* Array allocation. */
void *gnupg_reallocarray (void *a, size_t oldnmemb, size_t nmemb, size_t size);
void *xreallocarray (void *a, size_t oldnmemb, size_t nmemb, size_t size);
/* Same as estream_asprintf but die on memory failure. */
char *xasprintf (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2);
/* This is now an alias to estream_asprintf. */