msvcrt: Handle overflow in calloc().

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2016-04-27 11:11:49 +03:00 committed by Alexandre Julliard
parent f3465ecbae
commit 50dd4b8928
2 changed files with 32 additions and 1 deletions

View File

@ -394,7 +394,15 @@ size_t CDECL _aligned_msize(void *p, MSVCRT_size_t alignment, MSVCRT_size_t offs
*/
void* CDECL MSVCRT_calloc(MSVCRT_size_t count, MSVCRT_size_t size)
{
return msvcrt_heap_alloc(HEAP_ZERO_MEMORY, count*size);
MSVCRT_size_t bytes = count*size;
if (size && bytes / size != count)
{
*MSVCRT__errno() = MSVCRT_ENOMEM;
return NULL;
}
return msvcrt_heap_alloc(HEAP_ZERO_MEMORY, bytes);
}
/*********************************************************************

View File

@ -456,6 +456,28 @@ static void test_sbheap(void)
free(mem);
}
static void test_calloc(void)
{
void *ptr;
ptr = calloc(1, 0);
ok(ptr != NULL, "got %p\n", ptr);
free(ptr);
ptr = calloc(0, 0);
ok(ptr != NULL, "got %p\n", ptr);
free(ptr);
ptr = calloc(0, 1);
ok(ptr != NULL, "got %p\n", ptr);
free(ptr);
errno = 0;
ptr = calloc(~(size_t)0 / 2, ~(size_t)0 / 2);
ok(ptr == NULL, "got %p\n", ptr);
ok(errno == ENOMEM || broken(errno == 0) /* winxp, win2k3 */, "got errno %d\n", errno);
}
START_TEST(heap)
{
void *mem;
@ -480,4 +502,5 @@ START_TEST(heap)
test_aligned();
test_sbheap();
test_calloc();
}