mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Add reallocarray
implementation.
In a similar model as _safe_*alloc api but for the `userland` it guards against overflow before (re)allocation, usage concealed in fpm for now. Modern Linux and most of BSD already have it. Closes #8871.
This commit is contained in:
parent
3b92a96610
commit
bf29ee6917
4 changed files with 54 additions and 3 deletions
|
@ -689,7 +689,7 @@ if test "$ac_cv_func_getaddrinfo" = yes; then
|
||||||
AC_DEFINE(HAVE_GETADDRINFO,1,[Define if you have the getaddrinfo function])
|
AC_DEFINE(HAVE_GETADDRINFO,1,[Define if you have the getaddrinfo function])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_REPLACE_FUNCS(strlcat strlcpy explicit_bzero getopt)
|
AC_REPLACE_FUNCS(strlcat strlcpy explicit_bzero getopt reallocarray)
|
||||||
AC_FUNC_ALLOCA
|
AC_FUNC_ALLOCA
|
||||||
PHP_TIME_R_TYPE
|
PHP_TIME_R_TYPE
|
||||||
PHP_CHECK_IN_ADDR_T
|
PHP_CHECK_IN_ADDR_T
|
||||||
|
@ -1616,7 +1616,7 @@ PHP_ADD_SOURCES(main, main.c snprintf.c spprintf.c \
|
||||||
php_ini_builder.c \
|
php_ini_builder.c \
|
||||||
php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
|
php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
|
||||||
strlcat.c explicit_bzero.c reentrancy.c php_variables.c php_ticks.c \
|
strlcat.c explicit_bzero.c reentrancy.c php_variables.c php_ticks.c \
|
||||||
network.c php_open_temporary_file.c php_odbc_utils.c safe_bcmp.c \
|
network.c php_open_temporary_file.c php_odbc_utils.c safe_bcmp.c reallocarray.c \
|
||||||
output.c getopt.c php_syslog.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
|
output.c getopt.c php_syslog.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
|
||||||
|
|
||||||
PHP_ADD_SOURCES_X(main, fastcgi.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, PHP_FASTCGI_OBJS, no)
|
PHP_ADD_SOURCES_X(main, fastcgi.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1, PHP_FASTCGI_OBJS, no)
|
||||||
|
|
|
@ -179,6 +179,14 @@ END_EXTERN_C()
|
||||||
#define explicit_bzero php_explicit_bzero
|
#define explicit_bzero php_explicit_bzero
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_REALLOCARRAY
|
||||||
|
BEGIN_EXTERN_C()
|
||||||
|
PHPAPI void* php_reallocarray(void *p, size_t nmb, size_t siz);
|
||||||
|
END_EXTERN_C()
|
||||||
|
#undef reallocarray
|
||||||
|
#define reallocarray php_reallocarray
|
||||||
|
#endif
|
||||||
|
|
||||||
BEGIN_EXTERN_C()
|
BEGIN_EXTERN_C()
|
||||||
PHPAPI int php_safe_bcmp(const zend_string *a, const zend_string *b);
|
PHPAPI int php_safe_bcmp(const zend_string *a, const zend_string *b);
|
||||||
END_EXTERN_C()
|
END_EXTERN_C()
|
||||||
|
|
41
main/reallocarray.c
Normal file
41
main/reallocarray.c
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| Copyright (c) The PHP Group |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| This source file is subject to version 3.01 of the PHP license, |
|
||||||
|
| that is bundled with this package in the file LICENSE, and is |
|
||||||
|
| available through the world-wide-web at the following url: |
|
||||||
|
| https://www.php.net/license/3_01.txt |
|
||||||
|
| If you did not receive a copy of the PHP license and are unable to |
|
||||||
|
| obtain it through the world-wide-web, please send a note to |
|
||||||
|
| license@php.net so we can mail you a copy immediately. |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| Author: David Carlier <devnexen@gmail.com> |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "php.h"
|
||||||
|
|
||||||
|
#ifndef HAVE_REALLOCARRAY
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
PHPAPI void* php_reallocarray(void *p, size_t nmb, size_t siz)
|
||||||
|
{
|
||||||
|
size_t r;
|
||||||
|
#ifndef _WIN32
|
||||||
|
if (__builtin_mul_overflow(nmb, siz, &r)) {
|
||||||
|
#else
|
||||||
|
|
||||||
|
r = siz * nmb;
|
||||||
|
if (siz != 0 && r / siz != nmb) {
|
||||||
|
#endif
|
||||||
|
// EOVERFLOW may have been, arguably, more appropriate
|
||||||
|
// but this is what other implementations set
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return realloc(p, r);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -6,6 +6,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "php.h"
|
||||||
|
|
||||||
struct fpm_array_s {
|
struct fpm_array_s {
|
||||||
void *data;
|
void *data;
|
||||||
size_t sz;
|
size_t sz;
|
||||||
|
@ -84,7 +86,7 @@ static inline void *fpm_array_push(struct fpm_array_s *a) /* {{{ */
|
||||||
|
|
||||||
if (a->used == a->allocated) {
|
if (a->used == a->allocated) {
|
||||||
size_t new_allocated = a->allocated ? a->allocated * 2 : 20;
|
size_t new_allocated = a->allocated ? a->allocated * 2 : 20;
|
||||||
void *new_ptr = realloc(a->data, a->sz * new_allocated);
|
void *new_ptr = reallocarray(a->data, a->sz, new_allocated);
|
||||||
|
|
||||||
if (!new_ptr) {
|
if (!new_ptr) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue