Hi Bruno,

Thanks for all your help. I've attached an updated version of the patch which should now be (almost) complete. I've taken into account everything that Paul and you mentioned in the last mail.

* Bruno Haible <br...@clisp.org> [170809 10:59]:
Hi Darshit,

Looks quite complete now. Other than what Paul mentioned:

* You appear to be using tabs of widths 4. Therefore use "expand -t 4" to
 untabify the files you modified.

* The documentation:
 - Could you add an URL to the documentation of this function? (glibc
   manual or, if not available, manpage from the LTP)
 - The function is not present on any other system, I checked. Therefore the
   text should read:

   This function is missing on all non-glibc platforms:
   glibc 2.25, Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, 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.

* In the tests, you could add a check for the declaration of the function.
 Look in test-strchrnul.c how we do it.

However, it does not work and fails the test. It seems to me that I have
not managed to correctly coerce stdlib.h into defining a prototype for
reallocarray(). Where did I go wrong / what did I miss?

I don't see a problem. IMO
 $ ./gnulib-tool --test reallocarray
should work fine. Let's debug it when you've resubmitted once more.

Bruno



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

---
 ChangeLog                             | 16 +++++++++++
 MODULES.html.sh                       |  1 +
 doc/glibc-functions/reallocarray.texi | 21 ++++++++++++++
 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             | 52 +++++++++++++++++++++++++++++++++++
 11 files changed, 214 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 6c418dfe1..dd943b428 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-08  Paul Eggert  <egg...@cs.ucla.edu>
 
 	extensions: add _OPENBSD_SOURCE
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..3d42f0667
--- /dev/null
+++ b/doc/glibc-functions/reallocarray.texi
@@ -0,0 +1,21 @@
+@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 all non-glibc platforms: glibc 2.25, Mac OS X 10.5,
+FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, 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..d81ab3ec0
--- /dev/null
+++ b/tests/test-reallocarray.c
@@ -0,0 +1,52 @@
+/* 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 "signature.h"
+SIGNATURE_CHECK (reallocarray, void *, (void *, size_t, size_t));
+
+/* Return 8.
+   Usual compilers are not able to infer something about the return value.  */
+static unsigned int
+eight (void)
+{
+  unsigned int x = rand ();
+  unsigned int y = x * x * x * x;
+  x++; y |= x * x * x * x;
+  x++; y |= x * x * x * x;
+  x++; y |= x * x * x * x;
+  y = y >> 1;
+  return y & -y;
+}
+
+int
+main ()
+{
+  /* Check that reallocarray fails when requested to allocate a block of memory
+     larger than SIZE_MAX bytes.
+     We use eight (), not 8, to avoid a compiler warning from GCC 7.  */
+  char *p = reallocarray (NULL, (size_t) -1 / 8 + 1, eight ());
+  if (p != NULL)
+    {
+      free (p);
+      return 1;
+    }
+
+  return 0;
+}
-- 
2.14.0

Attachment: signature.asc
Description: PGP signature

Reply via email to