Skip to content

(p)ereallocarray introduction. #8882

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Zend/zend_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2632,6 +2632,19 @@ ZEND_API void* ZEND_FASTCALL _ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_D
return p;
}

ZEND_API void* ZEND_FASTCALL _ereallocarray(void* ptr, size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
void *p;

size = zend_safe_address_guarded(nmemb, size, 0);

if (!size) {
return NULL;
}
p = _erealloc(ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is essentially exactly the same as safe_erealloc(ptr, nmemb, size, 0), no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But wasn't the point of reallocarray that in case of an overflow for m * n we don't touch the memory? I'm not completely sure what erealloc does with size 0.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed, zend_safe_address_guarded triggers a zend_error_noreturn on overflow, so checking for 0 doesn't make sense. I wonder if this PR makes sense at all, if we can essentially just do safe_erealloc(ptr, nmemb, size, 0).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes you re right

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could still switch the few cases form erealloc to erealloc_safe 🙂

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure I prefer a new fresh PR ;-)

return p;
}

ZEND_API char* ZEND_FASTCALL _estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
size_t length;
Expand Down Expand Up @@ -3111,6 +3124,15 @@ ZEND_API void * __zend_realloc(void *p, size_t len)
zend_out_of_memory();
}

ZEND_API void * __zend_reallocarray(void *p, size_t nmemb, size_t len)
{
void *tmp;

len = zend_safe_address_guarded(nmemb, len, 0);
tmp = __zend_realloc(p, len);
return tmp;
}

#ifdef ZTS
size_t zend_mm_globals_size(void)
{
Expand Down
4 changes: 4 additions & 0 deletions Zend/zend_alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ ZEND_API void ZEND_FASTCALL _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_
ZEND_API void* ZEND_FASTCALL _ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE2(1,2);
ZEND_API void* ZEND_FASTCALL _erealloc(void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_ALLOC_SIZE(2);
ZEND_API void* ZEND_FASTCALL _erealloc2(void *ptr, size_t size, size_t copy_size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_ALLOC_SIZE(2);
ZEND_API void* ZEND_FASTCALL _ereallocarray(void *ptr, size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE2(2,3);
ZEND_API void* ZEND_FASTCALL _safe_erealloc(void *ptr, size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API void* ZEND_FASTCALL _safe_realloc(void *ptr, size_t nmemb, size_t size, size_t offset);
ZEND_API char* ZEND_FASTCALL _estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
Expand Down Expand Up @@ -158,6 +159,7 @@ ZEND_API void ZEND_FASTCALL _efree_huge(void *, size_t size);
#define ecalloc(nmemb, size) _ecalloc((nmemb), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define erealloc(ptr, size) _erealloc((ptr), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define erealloc2(ptr, size, copy_size) _erealloc2((ptr), (size), (copy_size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define ereallocarray(ptr, nmemb, size) _ereallocarray((ptr), (nmemb), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define safe_erealloc(ptr, nmemb, size, offset) _safe_erealloc((ptr), (nmemb), (size), (offset) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define erealloc_recoverable(ptr, size) _erealloc((ptr), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define erealloc2_recoverable(ptr, size, copy_size) _erealloc2((ptr), (size), (copy_size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
Expand All @@ -182,6 +184,7 @@ ZEND_API void ZEND_FASTCALL _efree_huge(void *, size_t size);
ZEND_API void * __zend_malloc(size_t len) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE(1);
ZEND_API void * __zend_calloc(size_t nmemb, size_t len) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE2(1,2);
ZEND_API void * __zend_realloc(void *p, size_t len) ZEND_ATTRIBUTE_ALLOC_SIZE(2);
ZEND_API void * __zend_reallocarray(void *p, size_t nmemb, size_t len) ZEND_ATTRIBUTE_ALLOC_SIZE2(2,3);

/* Selective persistent/non persistent allocation macros */
#define pemalloc(size, persistent) ((persistent)?__zend_malloc(size):emalloc(size))
Expand All @@ -198,6 +201,7 @@ ZEND_API void * __zend_realloc(void *p, size_t len) ZEND_ATTRIBUTE_ALLOC_SIZE(2)
#define pecalloc(nmemb, size, persistent) ((persistent)?__zend_calloc((nmemb), (size)):ecalloc((nmemb), (size)))
#define perealloc(ptr, size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc((ptr), (size)))
#define perealloc2(ptr, size, copy_size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc2((ptr), (size), (copy_size)))
#define pereallocarray(ptr, nmemb, size, persistent) ((persistent)?__zend_reallocarray((ptr), (nmemb), (size)):ereallocarray((ptr), (nmemb), (size)))
#define safe_perealloc(ptr, nmemb, size, offset, persistent) ((persistent)?_safe_realloc((ptr), (nmemb), (size), (offset)):safe_erealloc((ptr), (nmemb), (size), (offset)))
#define perealloc_recoverable(ptr, size, persistent) ((persistent)?realloc((ptr), (size)):erealloc_recoverable((ptr), (size)))
#define perealloc2_recoverable(ptr, size, persistent) ((persistent)?realloc((ptr), (size)):erealloc2_recoverable((ptr), (size), (copy_size)))
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_ptr_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ END_EXTERN_C()
do { \
stack->max += PTR_STACK_BLOCK_SIZE; \
} while (stack->top+count > stack->max); \
stack->elements = (void **) perealloc(stack->elements, (sizeof(void *) * (stack->max)), stack->persistent); \
stack->elements = (void **) pereallocarray(stack->elements, sizeof(void *), stack->max, stack->persistent); \
stack->top_element = stack->elements+stack->top; \
}

Expand Down
2 changes: 1 addition & 1 deletion ext/spl/spl_heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ static void spl_ptr_heap_insert(spl_ptr_heap *heap, void *elem, void *cmp_userda
if (heap->count+1 > heap->max_size) {
size_t alloc_size = heap->max_size * heap->elem_size;
/* we need to allocate more memory */
heap->elements = erealloc(heap->elements, 2 * alloc_size);
heap->elements = ereallocarray(heap->elements, 2, alloc_size);
memset((char *) heap->elements + alloc_size, 0, alloc_size);
heap->max_size *= 2;
}
Expand Down
2 changes: 1 addition & 1 deletion ext/standard/basic_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,7 @@ PHP_FUNCTION(getopt)

/* the first <len> slots are filled by the one short ops
* we now extend our array and jump to the new added structs */
opts = (opt_struct *) erealloc(opts, sizeof(opt_struct) * (len + count + 1));
opts = (opt_struct *) ereallocarray(opts, sizeof(opt_struct), (len + count + 1));
orig_opts = opts;
opts += len;

Expand Down