diff --git a/src/libc/allocator.src b/src/libc/allocator.src index 20edd7567..1636b5cc6 100644 --- a/src/libc/allocator.src +++ b/src/libc/allocator.src @@ -4,27 +4,35 @@ public _malloc, _free, _realloc public _calloc +; void *calloc(size_t nmemb, size_t size) _calloc: pop de pop bc - ex (sp),hl + ex (sp), hl push bc push de call __imulu push hl push hl call _malloc - pop de - add hl,de - xor a,a - sbc hl,de - ld e,a - push de + pop bc ; reset SP + ; test for NULL + add hl, bc + xor a, a + sbc hl, bc + pop bc ; BC = size + ret z ; return NULL + ; inlined bzero/memset + cpi + add hl, bc + ret c ; size is zero + dec hl + ld (hl), a + ret po ; size is one push hl - call nz,_memset - pop de - pop de pop de + dec de + lddr ret if defined ALLOCATOR_SIMPLE diff --git a/test/standalone/asprintf_fprintf/src/main.c b/test/standalone/asprintf_fprintf/src/main.c index 40dc17595..7eb2248b2 100644 --- a/test/standalone/asprintf_fprintf/src/main.c +++ b/test/standalone/asprintf_fprintf/src/main.c @@ -415,6 +415,12 @@ int memccpy_tests(void) { return __LINE__; } + /* check that no crashes occur with small calloc sizes */ + buf = (char*)calloc(1, sizeof(char)); + free(buf); + buf = (char*)calloc(0, sizeof(char)); + free(buf); + buf = (char*)calloc(file_size + 1, sizeof(char)); if (buf == NULL) { perror("calloc failure");