Index: src/OFInflateStream.m ================================================================== --- src/OFInflateStream.m +++ src/OFInflateStream.m @@ -192,14 +192,12 @@ #ifdef INFLATE64 _slidingWindowMask = 0xFFFF; #else _slidingWindowMask = 0x7FFF; #endif - _slidingWindow = [self allocMemoryWithSize: + _slidingWindow = [self allocZeroedMemoryWithSize: _slidingWindowMask + 1]; - /* Avoid leaking data */ - memset(_slidingWindow, 0, _slidingWindowMask + 1); } @catch (id e) { [self release]; @throw e; } @@ -372,14 +370,13 @@ return bytesWritten; CTX.codeLenCodesCount = bits; } - if OF_LIKELY (CTX.lengths == NULL) { - CTX.lengths = [self allocMemoryWithSize: 19]; - memset(CTX.lengths, 0, 19); - } + if OF_LIKELY (CTX.lengths == NULL) + CTX.lengths = [self + allocZeroedMemoryWithSize: 19]; for (uint16_t i = CTX.receivedCount; i < CTX.codeLenCodesCount + 4; i++) { if OF_UNLIKELY (!tryReadBits(self, &bits, 3)) { CTX.receivedCount = i; Index: src/OFLHAArchive.m ================================================================== --- src/OFLHAArchive.m +++ src/OFLHAArchive.m @@ -294,14 +294,12 @@ _distanceBits = distanceBits; _dictionaryBits = dictionaryBits; _slidingWindowMask = (1 << dictionaryBits) - 1; - _slidingWindow = [self allocMemoryWithSize: + _slidingWindow = [self allocZeroedMemoryWithSize: _slidingWindowMask + 1]; - /* Avoid leaking data */ - memset(_slidingWindow, 0, _slidingWindowMask + 1); } @catch (id e) { [self release]; @throw e; } @@ -358,12 +356,11 @@ goto start; } _codesCount = bits; _codesReceived = 0; - _codesLengths = [self allocMemoryWithSize: bits]; - memset(_codesLengths, 0, bits); + _codesLengths = [self allocZeroedMemoryWithSize: bits]; _skip = true; _state = STATE_CODE_LEN_TREE; goto start; case STATE_CODE_LEN_TREE: @@ -439,12 +436,11 @@ goto start; } _codesCount = bits; _codesReceived = 0; - _codesLengths = [self allocMemoryWithSize: bits]; - memset(_codesLengths, 0, bits); + _codesLengths = [self allocZeroedMemoryWithSize: bits]; _skip = false; _treeIter = _codeLenTree; _state = STATE_LITLEN_TREE; goto start; @@ -529,12 +525,11 @@ goto start; } _codesCount = bits; _codesReceived = 0; - _codesLengths = [self allocMemoryWithSize: bits]; - memset(_codesLengths, 0, bits); + _codesLengths = [self allocZeroedMemoryWithSize: bits]; _treeIter = _codeLenTree; _state = STATE_DIST_TREE; goto start; case STATE_DIST_TREE: Index: src/OFMapTable.m ================================================================== --- src/OFMapTable.m +++ src/OFMapTable.m @@ -159,14 +159,12 @@ _capacity *= 2; if (_capacity < MIN_CAPACITY) _capacity = MIN_CAPACITY; - _buckets = [self allocMemoryWithSize: sizeof(*_buckets) - count: _capacity]; - - memset(_buckets, 0, _capacity * sizeof(*_buckets)); + _buckets = [self allocZeroedMemoryWithSize: sizeof(*_buckets) + count: _capacity]; if (of_hash_seed != 0) #if defined(HAVE_ARC4RANDOM) _rotate = arc4random() & 31; #elif defined(HAVE_RANDOM) @@ -326,14 +324,12 @@ * below the minimum capacity. */ if ((capacity < _capacity && count > _count) || capacity < MIN_CAPACITY) return; - buckets = [self allocMemoryWithSize: sizeof(*buckets) - count: capacity]; - - memset(buckets, 0, capacity * sizeof(*buckets)); + buckets = [self allocZeroedMemoryWithSize: sizeof(*buckets) + count: capacity]; for (uint32_t i = 0; i < _capacity; i++) { if (_buckets[i] != NULL && _buckets[i] != &deleted) { uint32_t j, last; Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -747,11 +747,11 @@ - (nullable OFMethodSignature *)methodSignatureForSelector: (SEL)selector; /*! * @brief Allocates memory and stores it in the object's memory pool. * - * It will be freed automatically when the object is deallocated. + * It will be free'd automatically when the object is deallocated. * * @param size The size of the memory to allocate * @return A pointer to the allocated memory. May return NULL if the specified * size is 0. */ @@ -759,20 +759,48 @@ /*! * @brief Allocates memory for the specified number of items and stores it in * the object's memory pool. * - * It will be freed automatically when the object is deallocated. + * It will be free'd automatically when the object is deallocated. * * @param size The size of each item to allocate * @param count The number of items to allocate * @return A pointer to the allocated memory. May return NULL if the specified * size or count is 0. */ - (nullable void *)allocMemoryWithSize: (size_t)size count: (size_t)count OF_WARN_UNUSED_RESULT; +/*! + * @brief Allocates memory, initializes it with zeros and stores it in the + * object's memory pool. + * + * It will be free'd automatically when the object is deallocated. + * + * @param size The size of the memory to allocate + * @return A pointer to the allocated memory. May return NULL if the specified + * size is 0. + */ +- (nullable void *)allocZeroedMemoryWithSize: (size_t)size + OF_WARN_UNUSED_RESULT; + +/*! + * @brief Allocates memory for the specified number of items, initializes it + * with zeros and stores it in the object's memory pool. + * + * It will be free'd automatically when the object is deallocated. + * + * @param size The size of each item to allocate + * @param count The number of items to allocate + * @return A pointer to the allocated memory. May return NULL if the specified + * size or count is 0. + */ +- (nullable void *)allocZeroedMemoryWithSize: (size_t)size + count: (size_t)count + OF_WARN_UNUSED_RESULT; + /*! * @brief Resizes memory in the object's memory pool to the specified size. * * If the pointer is NULL, this is equivalent to allocating memory. * If the size is 0, this is equivalent to freeing memory. Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -176,21 +176,19 @@ if OF_UNLIKELY (extraAlignment > 1) extraAlignment = ((instanceSize + extraAlignment - 1) & ~(extraAlignment - 1)) - extraAlignment; - instance = malloc(PRE_IVARS_ALIGN + instanceSize + + instance = calloc(1, PRE_IVARS_ALIGN + instanceSize + extraAlignment + extraSize); if OF_UNLIKELY (instance == nil) { allocFailedException.isa = [OFAllocFailedException class]; @throw (id)&allocFailedException; } ((struct pre_ivar *)instance)->retainCount = 1; - ((struct pre_ivar *)instance)->firstMem = NULL; - ((struct pre_ivar *)instance)->lastMem = NULL; #if !defined(OF_HAVE_ATOMIC_OPS) && defined(OF_HAVE_THREADS) if OF_UNLIKELY (!of_spinlock_new( &((struct pre_ivar *)instance)->retainCountSpinlock)) { free(instance); @@ -199,12 +197,10 @@ } #endif instance = (OFObject *)(void *)((char *)instance + PRE_IVARS_ALIGN); - memset(instance, 0, instanceSize); - if (!objc_constructInstance(class, instance)) { free((char *)instance - PRE_IVARS_ALIGN); @throw [OFInitializationFailedException exceptionWithClass: class]; } @@ -1036,21 +1032,22 @@ @throw [OFOutOfRangeException exception]; if OF_UNLIKELY ((pointer = malloc(PRE_MEM_ALIGN + size)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: size]; + preMem = pointer; - preMem->owner = self; preMem->prev = PRE_IVARS->lastMem; preMem->next = NULL; if OF_LIKELY (PRE_IVARS->lastMem != NULL) PRE_IVARS->lastMem->next = preMem; if OF_UNLIKELY (PRE_IVARS->firstMem == NULL) PRE_IVARS->firstMem = preMem; + PRE_IVARS->lastMem = preMem; return (char *)pointer + PRE_MEM_ALIGN; } @@ -1060,10 +1057,49 @@ if OF_UNLIKELY (count > SIZE_MAX / size) @throw [OFOutOfRangeException exception]; return [self allocMemoryWithSize: size * count]; } + +- (void *)allocZeroedMemoryWithSize: (size_t)size +{ + void *pointer; + struct pre_mem *preMem; + + if OF_UNLIKELY (size == 0) + return NULL; + + if OF_UNLIKELY (size > SIZE_MAX - PRE_IVARS_ALIGN) + @throw [OFOutOfRangeException exception]; + + if OF_UNLIKELY ((pointer = calloc(1, PRE_MEM_ALIGN + size)) == NULL) + @throw [OFOutOfMemoryException + exceptionWithRequestedSize: size]; + + preMem = pointer; + preMem->owner = self; + preMem->prev = PRE_IVARS->lastMem; + + if OF_LIKELY (PRE_IVARS->lastMem != NULL) + PRE_IVARS->lastMem->next = preMem; + + if OF_UNLIKELY (PRE_IVARS->firstMem == NULL) + PRE_IVARS->firstMem = preMem; + + PRE_IVARS->lastMem = preMem; + + return (char *)pointer + PRE_MEM_ALIGN; +} + +- (void *)allocZeroedMemoryWithSize: (size_t)size + count: (size_t)count +{ + if OF_UNLIKELY (count > SIZE_MAX / size) + @throw [OFOutOfRangeException exception]; + + return [self allocZeroedMemoryWithSize: size * count]; +} - (void *)resizeMemory: (void *)pointer size: (size_t)size { void *new; Index: src/OFSecureData.m ================================================================== --- src/OFSecureData.m +++ src/OFSecureData.m @@ -110,16 +110,14 @@ if ((page = malloc(sizeof(*page))) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: sizeof(*page)]; - if ((page->map = malloc(mapSize)) == NULL) + if ((page->map = calloc(1, mapSize)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: mapSize]; - of_explicit_memset(page->map, 0, mapSize); - page->page = mapPages(1); of_explicit_memset(page->page, 0, pageSize); #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) lastPage = of_tlskey_get(lastPageKey); Index: src/runtime/exception.m ================================================================== --- src/runtime/exception.m +++ src/runtime/exception.m @@ -718,11 +718,11 @@ } void objc_exception_throw(id object) { - struct objc_exception *e = malloc(sizeof(*e)); + struct objc_exception *e = calloc(1, sizeof(*e)); bool emergency = false; if (e == NULL) { #ifdef OF_HAVE_THREADS if (!of_spinlock_lock(&emergency_exceptions_spinlock)) @@ -746,11 +746,10 @@ } if (e == NULL) OBJC_ERROR("Not enough memory to allocate exception!") - memset(e, 0, sizeof(*e)); e->exception.class = GNUCOBJC_EXCEPTION_CLASS; e->exception.cleanup = (emergency ? cleanup_emergency : cleanup); e->object = object; if (_Unwind_RaiseException(&e->exception) == _URC_END_OF_STACK &&