]> Savannah Git Hosting - gnulib.git/commitdiff
reallocarray: New module
authorDarshit Shah <darnir@gnu.org>
Sun, 13 Aug 2017 17:13:33 +0000 (10:13 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 13 Aug 2017 18:02:40 +0000 (11:02 -0700)
reallocarray is a new function in glibc 2.26 to safely allocate an array
of memory locations with integer overflow protection.
* MODULES.html.sh: Add reallocarray.
* doc/glibc-functions/reallocarray.texi: Documentation for reallocarray.
* lib/reallocarray.c: New file to implement module reallocarray.
* lib/stdlib.in.h: Add function declarations for reallocarray.
* m4/reallocarray.m4: New file.
* m4/stdlib_h.m4: Declare reallocarray.
* modules/reallocarray: New file.
* modules/reallocarray-test: New file.
* modules/stdlib: Coerce stdlib.h to export reallocarray.
* tests/test-reallocarray.c: New test.

ChangeLog
MODULES.html.sh
doc/glibc-functions/reallocarray.texi [new file with mode: 0644]
lib/reallocarray.c [new file with mode: 0644]
lib/stdlib.in.h
m4/reallocarray.m4 [new file with mode: 0644]
m4/stdlib_h.m4
modules/reallocarray [new file with mode: 0644]
modules/reallocarray-tests [new file with mode: 0644]
modules/stdlib
tests/test-reallocarray.c [new file with mode: 0644]

index 514b503e5fafeb2c48eeef0999145bebd81896f6..a46d4c2e1143ec7d9a5063d30bb4ed15ea0a4ba3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2017-08-13  Darshit Shah  <darnir@gnu.org>
+
+       reallocarray: New module
+       reallocarray is a new function in glibc 2.26 to safely allocate an array
+       of memory locations with integer overflow protection.
+       * MODULES.html.sh: Add reallocarray.
+       * doc/glibc-functions/reallocarray.texi: Documentation for reallocarray.
+       * lib/reallocarray.c: New file to implement module reallocarray.
+       * lib/stdlib.in.h: Add function declarations for reallocarray.
+       * m4/reallocarray.m4: New file.
+       * m4/stdlib_h.m4: Declare reallocarray.
+       * modules/reallocarray: New file.
+       * modules/reallocarray-test: New file.
+       * modules/stdlib: Coerce stdlib.h to export reallocarray.
+       * tests/test-reallocarray.c: New test.
+
 2017-08-12  Paul Eggert  <eggert@cs.ucla.edu>
 
        dirent-safer: fix cloexec race
index a64b9997e05a9ccdb7216a8b570cac7cbe269d48..1a258b632e0f4dd8417400e688be0a23fe4301e7 100755 (executable)
@@ -1703,6 +1703,7 @@ func_all_modules ()
   func_module free
   func_module malloc-gnu
   func_module realloc-gnu
+  func_module reallocarray
   func_module pagealign_alloc
   func_end_table
 
diff --git a/doc/glibc-functions/reallocarray.texi b/doc/glibc-functions/reallocarray.texi
new file mode 100644 (file)
index 0000000..6ce4a93
--- /dev/null
@@ -0,0 +1,22 @@
+@node reallocarray
+@subsection @code{reallocarray}
+@findex reallocarray
+
+Gnulib module: reallocarray
+
+Allocate multiple memory locations of a fixed size with integer overflow
+protection.
+Glibc Manual: @url{https://www.gnu.org/software/libc/manual/html_node/Changing-Block-Size.html#Changing-Block-Size}
+
+Portability problems fixed by Gnulib:
+@itemize
+@item
+This function is missing on many platforms:
+glibc 2.25, macOS 10.13, FreeBSD 11.0, NetBSD 7.1, OpenBSD 5.5, Minix 3.1.8,
+AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11 2011-11, Cygwin, mingw,
+MSVC 14, Interix 3.5, BeOS.
+@end itemize
+
+Portability problems not fixed by Gnulib:
+@itemize
+@end itemize
diff --git a/lib/reallocarray.c b/lib/reallocarray.c
new file mode 100644 (file)
index 0000000..05357a4
--- /dev/null
@@ -0,0 +1,37 @@
+/* reallocarray() function that is glibc compatible.
+
+   Copyright (C) 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 Darshit Shah */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <errno.h>
+
+#include "xalloc-oversized.h"
+
+void *
+reallocarray(void *ptr, size_t nmemb, size_t size)
+{
+    if (xalloc_oversized (nmemb, size))
+      {
+        errno = ENOMEM;
+        return NULL;
+      }
+    /* We rely on using the semantics of the GNU realloc() function here. */
+    return realloc(ptr, nmemb * size);
+}
index b5cf9d36958f6b0bd99cb3e7c693857d7d4ecbcd..c6e68fddc481fa63b0d67f10af9b7654b408a74b 100644 (file)
@@ -765,6 +765,23 @@ _GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - "
                  "use gnulib module realloc-posix for portability");
 #endif
 
+
+#if @GNULIB_REALLOCARRAY@
+# if ! @HAVE_REALLOCARRAY@
+_GL_FUNCDECL_SYS (reallocarray, void *,
+                  (void *ptr, size_t nmemb, size_t size));
+# endif
+_GL_CXXALIAS_SYS (reallocarray, void *,
+                  (void *ptr, size_t nmemb, size_t size));
+_GL_CXXALIASWARN (reallocarray);
+#elif defined GNULIB_POSIXCHECK
+# undef reallocarray
+# if HAVE_RAW_DECL_REALLOCARRAY
+_GL_WARN_ON_USE (reallocarray, "reallocarray is not portable - "
+                 "use gnulib module reallocarray for portability");
+# endif
+#endif
+
 #if @GNULIB_REALPATH@
 # if @REPLACE_REALPATH@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
diff --git a/m4/reallocarray.m4 b/m4/reallocarray.m4
new file mode 100644 (file)
index 0000000..261df7a
--- /dev/null
@@ -0,0 +1,20 @@
+# reallocarray.m4 serial 1
+dnl Copyright (C) 2017 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_REALLOCARRAY],
+[
+  dnl Persuade glibc <stdlib.h> to declare reallocarray().
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+
+  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  AC_CHECK_FUNCS([reallocarray])
+  if test $ac_cv_func_reallocarray = no; then
+    HAVE_REALLOCARRAY=0
+  fi
+])
+
+# Prerequisites of lib/reallocarray.c.
+AC_DEFUN([gl_PREREQ_REALLOCARRAY], [:])
index 110fe2d1a9f19bb831ff2d43047a2ea439390ec3..ec4a058154bbbdcd94a9229994b50c719fcba641 100644 (file)
@@ -21,9 +21,9 @@ AC_DEFUN([gl_STDLIB_H],
 #endif
     ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt
     initstate initstate_r mkdtemp mkostemp mkostemps mkstemp mkstemps
-    posix_openpt ptsname ptsname_r qsort_r random random_r realpath rpmatch
-    secure_getenv setenv setstate setstate_r srandom srandom_r
-    strtod strtoll strtoull unlockpt unsetenv])
+    posix_openpt ptsname ptsname_r qsort_r random random_r reallocarray
+    realpath rpmatch secure_getenv setenv setstate setstate_r srandom
+    srandom_r strtod strtoll strtoull unlockpt unsetenv])
 ])
 
 AC_DEFUN([gl_STDLIB_MODULE_INDICATOR],
@@ -58,6 +58,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
   GNULIB_QSORT_R=0;       AC_SUBST([GNULIB_QSORT_R])
   GNULIB_RANDOM=0;        AC_SUBST([GNULIB_RANDOM])
   GNULIB_RANDOM_R=0;      AC_SUBST([GNULIB_RANDOM_R])
+  GNULIB_REALLOCARRAY=0;  AC_SUBST([GNULIB_REALLOCARRAY])
   GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX])
   GNULIB_REALPATH=0;      AC_SUBST([GNULIB_REALPATH])
   GNULIB_RPMATCH=0;       AC_SUBST([GNULIB_RPMATCH])
@@ -89,6 +90,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
   HAVE_RANDOM=1;             AC_SUBST([HAVE_RANDOM])
   HAVE_RANDOM_H=1;           AC_SUBST([HAVE_RANDOM_H])
   HAVE_RANDOM_R=1;           AC_SUBST([HAVE_RANDOM_R])
+  HAVE_REALLOCARRAY=1;       AC_SUBST([HAVE_REALLOCARRAY])
   HAVE_REALPATH=1;           AC_SUBST([HAVE_REALPATH])
   HAVE_RPMATCH=1;            AC_SUBST([HAVE_RPMATCH])
   HAVE_SECURE_GETENV=1;      AC_SUBST([HAVE_SECURE_GETENV])
diff --git a/modules/reallocarray b/modules/reallocarray
new file mode 100644 (file)
index 0000000..f833d46
--- /dev/null
@@ -0,0 +1,32 @@
+Description:
+reallocarray() function that is glibc compatible.
+
+Files:
+lib/reallocarray.c
+m4/reallocarray.m4
+
+Depends-on:
+extensions
+xalloc-oversized
+realloc-gnu
+stdlib
+
+configure.ac:
+gl_FUNC_REALLOCARRAY
+if test $HAVE_REALLOCARRAY = 0; then
+  AC_LIBOBJ([reallocarray])
+  gl_PREREQ_REALLOCARRAY
+fi
+gl_MODULE_INDICATOR([reallocarray])
+gl_STDLIB_MODULE_INDICATOR([reallocarray])
+
+Makefile.am:
+
+Include:
+<stdlib.h>
+
+License:
+GPLv3+
+
+Maintainer:
+all
diff --git a/modules/reallocarray-tests b/modules/reallocarray-tests
new file mode 100644 (file)
index 0000000..3943d72
--- /dev/null
@@ -0,0 +1,11 @@
+Files:
+tests/test-reallocarray.c
+tests/signature.h
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-reallocarray
+check_PROGRAMS += test-reallocarray
index 27b1caa3bbc8f9aa7f59b93b4d2ea79860d142ed..257b5dbd697f8aa56824cc4b372594f2d4fd17af 100644 (file)
@@ -53,6 +53,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
              -e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \
              -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \
              -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \
+             -e 's/@''GNULIB_REALLOCARRAY''@/$(GNULIB_REALLOCARRAY)/g' \
              -e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \
              -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \
              -e 's/@''GNULIB_SECURE_GETENV''@/$(GNULIB_SECURE_GETENV)/g' \
@@ -83,6 +84,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
              -e 's|@''HAVE_RANDOM''@|$(HAVE_RANDOM)|g' \
              -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \
              -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \
+             -e 's|@''HAVE_REALLOCARRAY''@|$(HAVE_REALLOCARRAY)|g' \
              -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \
              -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \
              -e 's|@''HAVE_SECURE_GETENV''@|$(HAVE_SECURE_GETENV)|g' \
diff --git a/tests/test-reallocarray.c b/tests/test-reallocarray.c
new file mode 100644 (file)
index 0000000..587c700
--- /dev/null
@@ -0,0 +1,41 @@
+/* Test of reallocarray function.
+   Copyright (C) 2010-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 <stdlib.h>
+#include <errno.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (reallocarray, void *, (void *, size_t, size_t));
+
+int
+main ()
+{
+   size_t n;
+  /* Check that reallocarray fails when requested to allocate a block of memory
+     larger than SIZE_MAX bytes. */
+   for (n = 2; n != 0; n <<= 1)
+       {
+         if (reallocarray (NULL, (size_t) -1 / n + 1, n))
+        return 1;
+
+         /* Ensure that errno is correctly set */
+         if (!errno == ENOMEM)
+               return 1;
+       }
+   return 0;
+}