* Paul Eggert <egg...@cs.ucla.edu> [170810 16:51]:
Thanks, a few more things (hopefully we're getting to the end now).

"missing on many platforms" lists reallocarray as missing in FreeBSD 11.1, NetBSD 8.0, and OpenBSD 5.6. But it's not missing in those versions: those are the versions it was first introduced.

I'm a little confused here. The manpage for NetBSD[1] states:
"     The reallocarray() function first appeared in OpenBSD 5.6.
    reallocarray() was redesigned in NetBSD 8 as reallocarr(3).  For compati-
    bility reasons it's available since NetBSD 8 in the _OPENBSD_SOURCE
         namespace."

This page was written in 2015. However, on netbsd.org, NetBSD 7.1 is the current latest release. Also, when exactly do we consider reallocarray being available in NetBSD since the page only states that the redesigned version, reallocarr (note the missing 'ay') is available from 8.0. I am not very familiar with the different BSDs and am unable to make much sense out of this.

Also, I've changed the line for Mac OSX to version 10.13 which is the latest version since I can't find any evidence of the function being ever available on that platform

Please fit ChangeLog entries to 79 columns if possible.

When talking about a function FOO, say just "FOO", not "FOO()". Use the latter form only when talking about calls to FOO with zero arguments.

Done

The test could be easier to read and more useful if we got rid of the 'eight' function and tried realloc_array with several different sizes. Also, there's no need to free the array. E.g.,

  size_t n;
  for (n = 2; n != 0; n <<= 1)
    if (reallocarray (NULL, (size_t) -1 / n + 1, n))
      return 1;
  return 0;


I had originally copied the test from test-calloc-gnu.c. I've updated it with the sample you provided and added another test to ensure that the correct errno is set as well.

--
Thanking You,
Darshit Shah
PGP Fingerprint: 7845 120B 07CB D8D6 ECE5 FF2B 2A17 43ED A91A 35B6
From 2b618ad315124e302d74affd1fd3a95135339799 Mon Sep 17 00:00:00 2001
From: Darshit Shah <dar...@gnu.org>
Date: Thu, 10 Aug 2017 17:34:26 +0200
Subject: [PATCH] Add new module reallocarray

---
 ChangeLog                             | 16 ++++++++++++++
 MODULES.html.sh                       |  1 +
 doc/glibc-functions/reallocarray.texi | 22 +++++++++++++++++++
 lib/reallocarray.c                    | 37 +++++++++++++++++++++++++++++++
 lib/stdlib.in.h                       | 17 +++++++++++++++
 m4/reallocarray.m4                    | 20 +++++++++++++++++
 m4/stdlib_h.m4                        |  8 ++++---
 modules/reallocarray                  | 32 +++++++++++++++++++++++++++
 modules/reallocarray-tests            | 11 ++++++++++
 modules/stdlib                        |  2 ++
 tests/test-reallocarray.c             | 41 +++++++++++++++++++++++++++++++++++
 11 files changed, 204 insertions(+), 3 deletions(-)
 create mode 100644 doc/glibc-functions/reallocarray.texi
 create mode 100644 lib/reallocarray.c
 create mode 100644 m4/reallocarray.m4
 create mode 100644 modules/reallocarray
 create mode 100644 modules/reallocarray-tests
 create mode 100644 tests/test-reallocarray.c

diff --git a/ChangeLog b/ChangeLog
index 9f8dca5d8..2343f1743 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2017-08-09  Darshit Shah  <dar...@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-10  Paul Eggert  <egg...@cs.ucla.edu>
 
 	fts: port recent changes to CentOS 6
diff --git a/MODULES.html.sh b/MODULES.html.sh
index a64b9997e..1a258b632 100755
--- a/MODULES.html.sh
+++ b/MODULES.html.sh
@@ -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
index 000000000..a11f2bae6
--- /dev/null
+++ b/doc/glibc-functions/reallocarray.texi
@@ -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, Mac OS X 10.13, FreeBSD 11.0, NetBSD 8.0, 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
index 000000000..05357a443
--- /dev/null
+++ b/lib/reallocarray.c
@@ -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);
+}
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index b5cf9d369..c6e68fddc 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -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
index 000000000..261df7a90
--- /dev/null
+++ b/m4/reallocarray.m4
@@ -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], [:])
diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4
index 110fe2d1a..ec4a05815 100644
--- a/m4/stdlib_h.m4
+++ b/m4/stdlib_h.m4
@@ -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
index 000000000..f833d46dc
--- /dev/null
+++ b/modules/reallocarray
@@ -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
index 000000000..3943d7295
--- /dev/null
+++ b/modules/reallocarray-tests
@@ -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
diff --git a/modules/stdlib b/modules/stdlib
index 27b1caa3b..257b5dbd6 100644
--- a/modules/stdlib
+++ b/modules/stdlib
@@ -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
index 000000000..587c70001
--- /dev/null
+++ b/tests/test-reallocarray.c
@@ -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;
+}
-- 
2.14.0

Attachment: signature.asc
Description: PGP signature

Reply via email to