Index: src/OFBlock.m ================================================================== --- src/OFBlock.m +++ src/OFBlock.m @@ -437,39 +437,10 @@ - (instancetype)init { OF_INVALID_INIT_METHOD } -- (void *)allocMemoryWithSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)allocMemoryWithSize: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)ptr - size: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)ptr - size: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void)freeMemory: (void *)ptr -{ - OF_UNRECOGNIZED_SELECTOR -} - - (instancetype)retain { if ([self isMemberOfClass: (Class)&_NSConcreteMallocBlock]) return Block_copy(self); Index: src/OFConstantString.m ================================================================== --- src/OFConstantString.m +++ src/OFConstantString.m @@ -52,39 +52,10 @@ + (instancetype)alloc { OF_UNRECOGNIZED_SELECTOR } -- (void *)allocMemoryWithSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)allocMemoryWithSize: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)pointer - size: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)pointer - size: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void)freeMemory: (void *)pointer -{ - OF_UNRECOGNIZED_SELECTOR -} - - (instancetype)retain { return self; } @@ -140,64 +111,31 @@ struct of_string_utf8_ivars *ivars; if ([self isMemberOfClass: [OFConstantUTF8String class]]) return; - if ((ivars = calloc(1, sizeof(*ivars))) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: sizeof(*ivars)]; - + ivars = of_calloc(1, sizeof(*ivars)); ivars->cString = _cString; ivars->cStringLength = _cStringLength; switch (of_string_utf8_check(ivars->cString, - ivars->cStringLength, - &ivars->length)) { - case 1: - ivars->isUTF8 = true; - break; - case -1: - free(ivars); - @throw [OFInvalidEncodingException exception]; + ivars->cStringLength, &ivars->length)) { + case 1: + ivars->isUTF8 = true; + break; + case -1: + free(ivars); + @throw [OFInvalidEncodingException exception]; } _cString = (char *)ivars; object_setClass(self, [OFConstantUTF8String class]); } } + (instancetype)alloc { - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)allocMemoryWithSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)allocMemoryWithSize: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)pointer - size: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)pointer - size: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void)freeMemory: (void *)pointer -{ OF_UNRECOGNIZED_SELECTOR } - (instancetype)retain { Index: src/OFMutableUTF8String.m ================================================================== --- src/OFMutableUTF8String.m +++ src/OFMutableUTF8String.m @@ -43,31 +43,27 @@ } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String freeWhenDone: (bool)freeWhenDone { - @try { - self = [self initWithUTF8String: UTF8String]; - } @finally { - if (freeWhenDone) - free(UTF8String); - } + self = [self initWithUTF8String: UTF8String]; + + if (freeWhenDone) + free(UTF8String); return self; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone { - @try { - self = [self initWithUTF8String: UTF8String - length: UTF8StringLength]; - } @finally { - if (freeWhenDone) - free(UTF8String); - } + self = [self initWithUTF8String: UTF8String + length: UTF8StringLength]; + + if (freeWhenDone) + free(UTF8String); return self; } - (void)of_convertWithWordStartTable: (const of_unichar_t *const[])startTable @@ -157,11 +153,11 @@ i += cLen; } @try { - newCString = [self allocMemoryWithSize: newCStringLength + 1]; + newCString = of_malloc(newCStringLength + 1, 1); } @catch (id e) { free(unicodeString); @throw e; } @@ -171,21 +167,21 @@ size_t d; if ((d = of_string_utf8_encode(unicodeString[i], newCString + j)) == 0) { free(unicodeString); - [self freeMemory: newCString]; + free(newCString); @throw [OFInvalidEncodingException exception]; } j += d; } assert(j == newCStringLength); newCString[j] = 0; free(unicodeString); - [self freeMemory: _s->cString]; + free(_s->cString); _s->hashed = false; _s->cString = newCString; _s->cStringLength = newCStringLength; /* @@ -226,13 +222,12 @@ _s->hashed = false; if (lenNew == (size_t)lenOld) memcpy(_s->cString + idx, buffer, lenNew); else if (lenNew > (size_t)lenOld) { - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength - - lenOld + lenNew + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength - lenOld + lenNew + 1, 1); memmove(_s->cString + idx + lenNew, _s->cString + idx + lenOld, _s->cStringLength - idx - lenOld); memcpy(_s->cString + idx, buffer, lenNew); @@ -253,13 +248,12 @@ if (character >= 0x80) _s->isUTF8 = true; @try { - _s->cString = [self - resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } } @@ -282,13 +276,12 @@ case -1: @throw [OFInvalidEncodingException exception]; } _s->hashed = false; - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + - UTF8StringLength + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + UTF8StringLength + 1, 1); memcpy(_s->cString + _s->cStringLength, UTF8String, UTF8StringLength + 1); _s->cStringLength += UTF8StringLength; _s->length += length; @@ -312,13 +305,12 @@ case -1: @throw [OFInvalidEncodingException exception]; } _s->hashed = false; - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + - UTF8StringLength + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + UTF8StringLength + 1, 1); memcpy(_s->cString + _s->cStringLength, UTF8String, UTF8StringLength); _s->cStringLength += UTF8StringLength; _s->length += length; @@ -360,13 +352,12 @@ @throw [OFInvalidArgumentException exception]; UTF8StringLength = string.UTF8StringLength; _s->hashed = false; - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + - UTF8StringLength + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + UTF8StringLength + 1, 1); memcpy(_s->cString + _s->cStringLength, string.UTF8String, UTF8StringLength); _s->cStringLength += UTF8StringLength; _s->length += string.length; @@ -404,12 +395,12 @@ } tmp[j] = '\0'; _s->hashed = false; - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + j + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + j + 1, 1); memcpy(_s->cString + _s->cStringLength, tmp, j + 1); _s->cStringLength += j; _s->length += length; @@ -533,12 +524,11 @@ idx = of_string_utf8_get_position(_s->cString, idx, _s->cStringLength); newCStringLength = _s->cStringLength + string.UTF8StringLength; _s->hashed = false; - _s->cString = [self resizeMemory: _s->cString - size: newCStringLength + 1]; + _s->cString = of_realloc(_s->cString, newCStringLength + 1, 1); memmove(_s->cString + idx + string.UTF8StringLength, _s->cString + idx, _s->cStringLength - idx); memcpy(_s->cString + idx, string.UTF8String, string.UTF8StringLength); @@ -576,12 +566,11 @@ _s->length -= range.length; _s->cStringLength -= end - start; _s->cString[_s->cStringLength] = 0; @try { - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } @@ -618,12 +607,11 @@ * We must not resize the string if the new string is smaller, because * then we can't memmove() the rest of the string forward as the rest is * lost due to the resize! */ if (newCStringLength > _s->cStringLength) - _s->cString = [self resizeMemory: _s->cString - size: newCStringLength + 1]; + _s->cString = of_realloc(_s->cString, newCStringLength + 1, 1); memmove(_s->cString + start + replacement.UTF8StringLength, _s->cString + end, _s->cStringLength - end); memcpy(_s->cString + start, replacement.UTF8String, replacement.UTF8StringLength); @@ -632,12 +620,11 @@ /* * If the new string is smaller, we can safely resize it now as we're * done with memmove(). */ if (newCStringLength < _s->cStringLength) - _s->cString = [self resizeMemory: _s->cString - size: newCStringLength + 1]; + _s->cString = of_realloc(_s->cString, newCStringLength + 1, 1); _s->cStringLength = newCStringLength; _s->length = newLength; if ([replacement isKindOfClass: [OFUTF8String class]] || @@ -686,16 +673,15 @@ for (size_t i = range.location; i <= range.length - searchLength; i++) { if (memcmp(_s->cString + i, searchString, searchLength) != 0) continue; @try { - newCString = [self resizeMemory: newCString - size: newCStringLength + - i - last + - replacementLength + 1]; + newCString = of_realloc(newCString, + newCStringLength + i - last + replacementLength + 1, + 1); } @catch (id e) { - [self freeMemory: newCString]; + free(newCString); @throw e; } memcpy(newCString + newCStringLength, _s->cString + last, i - last); memcpy(newCString + newCStringLength + i - last, @@ -707,23 +693,22 @@ i += searchLength - 1; last = i + 1; } @try { - newCString = [self resizeMemory: newCString - size: newCStringLength + - _s->cStringLength - last + 1]; + newCString = of_realloc(newCString, + newCStringLength + _s->cStringLength - last + 1, 1); } @catch (id e) { - [self freeMemory: newCString]; + free(newCString); @throw e; } memcpy(newCString + newCStringLength, _s->cString + last, _s->cStringLength - last); newCStringLength += _s->cStringLength - last; newCString[newCStringLength] = 0; - [self freeMemory: _s->cString]; + free(_s->cString); _s->hashed = false; _s->cString = newCString; _s->cStringLength = newCStringLength; _s->length = newLength; @@ -749,12 +734,11 @@ memmove(_s->cString, _s->cString + i, _s->cStringLength); _s->cString[_s->cStringLength] = '\0'; @try { - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } @@ -776,12 +760,11 @@ _s->cStringLength -= d; _s->length -= d; @try { - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } @@ -813,12 +796,11 @@ memmove(_s->cString, _s->cString + i, _s->cStringLength); _s->cString[_s->cStringLength] = '\0'; @try { - _s->cString = [self resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -804,73 +804,10 @@ * returned * @return The method signature for the specified selector */ - (nullable OFMethodSignature *)methodSignatureForSelector: (SEL)selector; -/** - * @brief Allocates memory 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 *)allocMemoryWithSize: (size_t)size OF_WARN_UNUSED_RESULT; - -/** - * @brief Allocates memory for the specified number of items 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 *)allocMemoryWithSize: (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. - * - * @param pointer A pointer to the already allocated memory - * @param size The new size for the memory chunk - * @return A pointer to the resized memory chunk - */ -- (nullable void *)resizeMemory: (nullable void *)pointer - size: (size_t)size OF_WARN_UNUSED_RESULT; - -/** - * @brief Resizes memory in the object's memory pool to the specific number of - * items of the specified size. - * - * If the pointer is NULL, this is equivalent to allocating memory. - * If the size or number of items is 0, this is equivalent to freeing memory. - * - * @param pointer A pointer to the already allocated memory - * @param size The size of each item to resize to - * @param count The number of items to resize to - * @return A pointer to the resized memory chunk - */ -- (nullable void *)resizeMemory: (nullable void *)pointer - size: (size_t)size - count: (size_t)count OF_WARN_UNUSED_RESULT; - -/** - * @brief Frees allocated memory and removes it from the object's memory pool. - * - * Does nothing if the pointer is NULL. - * - * @param pointer A pointer to the allocated memory - */ -- (void)freeMemory: (nullable void *)pointer; - /** * @brief Deallocates the object. * * It is automatically called when the retain count reaches zero. * Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -84,26 +84,16 @@ struct pre_ivar { int retainCount; #if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS) of_spinlock_t retainCountSpinlock; #endif - struct pre_mem *firstMem, *lastMem; -}; - -struct pre_mem { - struct pre_mem *prev, *next; - id owner; }; #define PRE_IVARS_ALIGN ((sizeof(struct pre_ivar) + \ (OF_BIGGEST_ALIGNMENT - 1)) & ~(OF_BIGGEST_ALIGNMENT - 1)) #define PRE_IVARS ((struct pre_ivar *)(void *)((char *)self - PRE_IVARS_ALIGN)) -#define PRE_MEM_ALIGN ((sizeof(struct pre_mem) + \ - (OF_BIGGEST_ALIGNMENT - 1)) & ~(OF_BIGGEST_ALIGNMENT - 1)) -#define PRE_MEM(mem) ((struct pre_mem *)(void *)((char *)mem - PRE_MEM_ALIGN)) - static struct { Class isa; } allocFailedException; uint32_t of_hash_seed; @@ -1100,136 +1090,10 @@ /* Classes containing data should reimplement this! */ return [OFString stringWithFormat: @"<%@>", self.className]; } -- (void *)allocMemoryWithSize: (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 = 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; -} - -- (void *)allocMemoryWithSize: (size_t)size - count: (size_t)count -{ - if OF_UNLIKELY (count > SIZE_MAX / size) - @throw [OFOutOfRangeException exception]; - - return [self allocMemoryWithSize: size * count]; -} - -- (void *)resizeMemory: (void *)pointer - size: (size_t)size -{ - void *new; - struct pre_mem *preMem; - - if OF_UNLIKELY (pointer == NULL) - return [self allocMemoryWithSize: size]; - - if OF_UNLIKELY (size == 0) { - [self freeMemory: pointer]; - return NULL; - } - - if OF_UNLIKELY (PRE_MEM(pointer)->owner != self) - @throw [OFMemoryNotPartOfObjectException - exceptionWithPointer: pointer - object: self]; - - if OF_UNLIKELY ((new = realloc(PRE_MEM(pointer), - PRE_MEM_ALIGN + size)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: size]; - preMem = new; - - if OF_UNLIKELY (preMem != PRE_MEM(pointer)) { - if OF_LIKELY (preMem->prev != NULL) - preMem->prev->next = preMem; - if OF_LIKELY (preMem->next != NULL) - preMem->next->prev = preMem; - - if OF_UNLIKELY (PRE_IVARS->firstMem == PRE_MEM(pointer)) - PRE_IVARS->firstMem = preMem; - if OF_UNLIKELY (PRE_IVARS->lastMem == PRE_MEM(pointer)) - PRE_IVARS->lastMem = preMem; - } - - return (char *)new + PRE_MEM_ALIGN; -} - -- (void *)resizeMemory: (void *)pointer - size: (size_t)size - count: (size_t)count -{ - if OF_UNLIKELY (pointer == NULL) - return [self allocMemoryWithSize: size - count: count]; - - if OF_UNLIKELY (size == 0 || count == 0) { - [self freeMemory: pointer]; - return NULL; - } - - if OF_UNLIKELY (count > SIZE_MAX / size) - @throw [OFOutOfRangeException exception]; - - return [self resizeMemory: pointer - size: size * count]; -} - -- (void)freeMemory: (void *)pointer -{ - if OF_UNLIKELY (pointer == NULL) - return; - - if OF_UNLIKELY (PRE_MEM(pointer)->owner != self) - @throw [OFMemoryNotPartOfObjectException - exceptionWithPointer: pointer - object: self]; - - if OF_LIKELY (PRE_MEM(pointer)->prev != NULL) - PRE_MEM(pointer)->prev->next = PRE_MEM(pointer)->next; - if OF_LIKELY (PRE_MEM(pointer)->next != NULL) - PRE_MEM(pointer)->next->prev = PRE_MEM(pointer)->prev; - - if OF_UNLIKELY (PRE_IVARS->firstMem == PRE_MEM(pointer)) - PRE_IVARS->firstMem = PRE_MEM(pointer)->next; - if OF_UNLIKELY (PRE_IVARS->lastMem == PRE_MEM(pointer)) - PRE_IVARS->lastMem = PRE_MEM(pointer)->prev; - - /* To detect double-free */ - PRE_MEM(pointer)->owner = nil; - - free(PRE_MEM(pointer)); -} - - (id)forwardingTargetForSelector: (SEL)selector { return nil; } @@ -1329,29 +1193,12 @@ return true; } - (void)dealloc { - struct pre_mem *iter; - objc_destructInstance(self); - iter = PRE_IVARS->firstMem; - while (iter != NULL) { - struct pre_mem *next = iter->next; - - /* - * We can use owner as a sentinel to prevent exploitation in - * case there is a buffer underflow somewhere. - */ - OF_ENSURE(iter->owner == self); - - free(iter); - - iter = next; - } - free((char *)self - PRE_IVARS_ALIGN); } /* Required to use properties with the Apple runtime */ - (id)copyWithZone: (void *)zone @@ -1373,41 +1220,14 @@ return [(id)self mutableCopy]; } /* - * Those are needed as the root class is the superclass of the root class's - * metaclass and thus instance methods can be sent to class objects as well. + * The following are needed as the root class is the superclass of the root + * class's metaclass and thus instance methods can be sent to class objects as + * well. */ -+ (void *)allocMemoryWithSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -+ (void *)allocMemoryWithSize: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -+ (void *)resizeMemory: (void *)pointer - size: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -+ (void *)resizeMemory: (void *)pointer - size: (size_t)size - count: (size_t)count -{ - OF_UNRECOGNIZED_SELECTOR -} - -+ (void)freeMemory: (void *)pointer -{ - OF_UNRECOGNIZED_SELECTOR -} + (id)retain { return self; } Index: src/OFUTF8String.h ================================================================== --- src/OFUTF8String.h +++ src/OFUTF8String.h @@ -33,11 +33,11 @@ size_t cStringLength; bool isUTF8; size_t length; bool hashed; unsigned long hash; - char *_Nullable freeWhenDone; + bool freeWhenDone; } *restrict _s; struct of_string_utf8_ivars _storage; } @end Index: src/OFUTF8String.m ================================================================== --- src/OFUTF8String.m +++ src/OFUTF8String.m @@ -26,10 +26,11 @@ #endif #import "OFUTF8String.h" #import "OFUTF8String+Private.h" #import "OFArray.h" +#import "OFData.h" #import "OFMutableUTF8String.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" @@ -178,12 +179,12 @@ self = [super init]; @try { _s = &_storage; - _s->cString = [self allocMemoryWithSize: 1]; - _s->cString[0] = '\0'; + _s->cString = of_calloc(1, 1); + _s->freeWhenDone = true; } @catch (id e) { [self release]; @throw e; } @@ -244,12 +245,13 @@ cStringLength -= 3; } _s = &_storage; - _s->cString = [self allocMemoryWithSize: cStringLength + 1]; + _s->cString = of_malloc(cStringLength + 1, 1); _s->cStringLength = cStringLength; + _s->freeWhenDone = true; if (encoding == OF_STRING_ENCODING_UTF_8 || encoding == OF_STRING_ENCODING_ASCII) { switch (of_string_utf8_check(cString, cStringLength, &_s->length)) { @@ -291,13 +293,12 @@ if (bytes == 0) @throw [OFInvalidEncodingException exception]; _s->cStringLength += bytes - 1; - _s->cString = [self - resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + 1, 1); memcpy(_s->cString + j, buffer, bytes); j += bytes; } @@ -305,15 +306,15 @@ return self; } switch (encoding) { -#define CASE(encoding, var) \ - case encoding: \ - table = var; \ - tableOffset = var##_offset; \ - break; +#define CASE(encoding, var) \ + case encoding: \ + table = var; \ + tableOffset = var##_offset; \ + break; #ifdef HAVE_ISO_8859_2 CASE(OF_STRING_ENCODING_ISO_8859_2, of_iso_8859_2_table) #endif #ifdef HAVE_ISO_8859_3 CASE(OF_STRING_ENCODING_ISO_8859_3, of_iso_8859_3_table) @@ -372,13 +373,12 @@ if (byteLength == 0) @throw [OFInvalidEncodingException exception]; _s->cStringLength += byteLength - 1; - _s->cString = [self - resizeMemory: _s->cString - size: _s->cStringLength + 1]; + _s->cString = of_realloc(_s->cString, + _s->cStringLength + 1, 1); memcpy(_s->cString + j, buffer, byteLength); j += byteLength; } @@ -424,13 +424,11 @@ @throw [OFInvalidEncodingException exception]; } _s->cString = (char *)UTF8String; _s->cStringLength = UTF8StringLength; - - if (freeWhenDone) - _s->freeWhenDone = UTF8String; + _s->freeWhenDone = freeWhenDone; } @catch (id e) { [self release]; @throw e; } @@ -452,12 +450,13 @@ else _s->isUTF8 = true; _s->length = string.length; - _s->cString = [self allocMemoryWithSize: _s->cStringLength + 1]; + _s->cString = of_malloc(_s->cStringLength + 1, 1); memcpy(_s->cString, string.UTF8String, _s->cStringLength + 1); + _s->freeWhenDone = true; } @catch (id e) { [self release]; @throw e; } @@ -472,12 +471,13 @@ @try { size_t j; _s = &_storage; - _s->cString = [self allocMemoryWithSize: (length * 4) + 1]; + _s->cString = of_malloc((length * 4) + 1, 1); _s->length = length; + _s->freeWhenDone = true; j = 0; for (size_t i = 0; i < length; i++) { size_t len = of_string_utf8_encode(characters[i], _s->cString + j); @@ -493,12 +493,11 @@ _s->cString[j] = '\0'; _s->cStringLength = j; @try { - _s->cString = [self resizeMemory: _s->cString - size: j + 1]; + _s->cString = of_realloc(_s->cString, j + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @@ -528,12 +527,13 @@ } else if (byteOrder != OF_BYTE_ORDER_NATIVE) swap = true; _s = &_storage; - _s->cString = [self allocMemoryWithSize: (length * 4) + 1]; + _s->cString = of_malloc((length * 4) + 1, 1); _s->length = length; + _s->freeWhenDone = true; j = 0; for (size_t i = 0; i < length; i++) { of_unichar_t character = (swap ? OF_BSWAP16(string[i]) : string[i]); @@ -578,12 +578,11 @@ _s->cString[j] = '\0'; _s->cStringLength = j; @try { - _s->cString = [self resizeMemory: _s->cString - size: j + 1]; + _s->cString = of_realloc(_s->cString, j + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @@ -613,12 +612,13 @@ } else if (byteOrder != OF_BYTE_ORDER_NATIVE) swap = true; _s = &_storage; - _s->cString = [self allocMemoryWithSize: (length * 4) + 1]; + _s->cString = of_malloc((length * 4) + 1, 1); _s->length = length; + _s->freeWhenDone = true; j = 0; for (size_t i = 0; i < length; i++) { char buffer[4]; size_t len = of_string_utf8_encode( @@ -645,12 +645,11 @@ _s->cString[j] = '\0'; _s->cStringLength = j; @try { - _s->cString = [self resizeMemory: _s->cString - size: j + 1]; + _s->cString = of_realloc(_s->cString, j + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @@ -688,13 +687,13 @@ break; case -1: @throw [OFInvalidEncodingException exception]; } - _s->cString = [self - allocMemoryWithSize: cStringLength + 1]; + _s->cString = of_malloc(cStringLength + 1, 1); memcpy(_s->cString, tmp, cStringLength + 1); + _s->freeWhenDone = true; } @finally { free(tmp); } } @catch (id e) { [self release]; @@ -704,12 +703,12 @@ return self; } - (void)dealloc { - if (_s != NULL && _s->freeWhenDone != NULL) - free(_s->freeWhenDone); + if (_s != NULL && _s->freeWhenDone) + free(_s->cString); [super dealloc]; } - (size_t)getCString: (char *)cString @@ -1154,67 +1153,65 @@ return array; } - (const of_unichar_t *)characters { - OFObject *object = [[[OFObject alloc] init] autorelease]; - of_unichar_t *ret; - size_t i, j; - - ret = [object allocMemoryWithSize: sizeof(of_unichar_t) - count: _s->length]; - - i = j = 0; + of_unichar_t *buffer = of_malloc(_s->length, sizeof(of_unichar_t)); + size_t i = 0, j = 0; while (i < _s->cStringLength) { of_unichar_t c; ssize_t cLen; cLen = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c); - if (cLen <= 0 || c > 0x10FFFF) + if (cLen <= 0 || c > 0x10FFFF) { + free(buffer); @throw [OFInvalidEncodingException exception]; + } - ret[j++] = c; + buffer[j++] = c; i += cLen; } - return ret; + return [[OFData dataWithItemsNoCopy: buffer + count: _s->length + itemSize: sizeof(of_unichar_t) + freeWhenDone: true] items]; } - (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder { - OFObject *object = [[[OFObject alloc] init] autorelease]; - of_char32_t *ret; - size_t i, j; - - ret = [object allocMemoryWithSize: sizeof(of_unichar_t) - count: _s->length + 1]; - - i = j = 0; + of_char32_t *buffer = of_malloc(_s->length + 1, sizeof(of_char32_t)); + size_t i = 0, j = 0; while (i < _s->cStringLength) { - of_unichar_t c; + of_char32_t c; ssize_t cLen; cLen = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c); - if (cLen <= 0 || c > 0x10FFFF) + if (cLen <= 0 || c > 0x10FFFF) { + free(buffer); @throw [OFInvalidEncodingException exception]; + } if (byteOrder != OF_BYTE_ORDER_NATIVE) - ret[j++] = OF_BSWAP32(c); + buffer[j++] = OF_BSWAP32(c); else - ret[j++] = c; + buffer[j++] = c; i += cLen; } - ret[j] = 0; + buffer[j] = 0; - return ret; + return [[OFData dataWithItemsNoCopy: buffer + count: _s->length + 1 + itemSize: sizeof(of_char32_t) + freeWhenDone: true] items]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block { Index: src/exceptions/OFAllocFailedException.m ================================================================== --- src/exceptions/OFAllocFailedException.m +++ src/exceptions/OFAllocFailedException.m @@ -34,39 +34,10 @@ - (instancetype)init { OF_INVALID_INIT_METHOD } -- (void *)allocMemoryWithSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)allocMemoryForNItems: (size_t)nitems - withSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)ptr - toSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void *)resizeMemory: (void *)ptr - toNItems: (size_t)nitems - withSize: (size_t)size -{ - OF_UNRECOGNIZED_SELECTOR -} - -- (void)freeMemory: (void *)ptr -{ - OF_UNRECOGNIZED_SELECTOR -} - - (instancetype)retain { return self; } Index: src/platform/posix/OFProcess.m ================================================================== --- src/platform/posix/OFProcess.m +++ src/platform/posix/OFProcess.m @@ -127,11 +127,11 @@ self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); const char *path; - char **argv; + char **argv, **env = NULL; _pid = -1; _readPipe[0] = _writePipe[1] = -1; if (pipe(_readPipe) != 0 || pipe(_writePipe) != 0) @@ -142,12 +142,11 @@ [self of_getArgv: &argv forProgramName: programName andArguments: arguments]; @try { - char **env = [self - of_environmentForDictionary: environment]; + env = [self of_environmentForDictionary: environment]; #ifdef HAVE_POSIX_SPAWNP posix_spawn_file_actions_t actions; posix_spawnattr_t attr; if (posix_spawn_file_actions_init(&actions) != 0) @@ -204,13 +203,20 @@ if (_pid == -1) @throw [OFInitializationFailedException exceptionWithClass: self.class]; #endif } @finally { + char **iter; + close(_readPipe[1]); close(_writePipe[0]); - [self freeMemory: argv]; + free(argv); + + for (iter = env; *iter != NULL; iter++) + free(*iter); + + free(env); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @@ -234,12 +240,11 @@ { OFString *const *objects = arguments.objects; size_t i, count = arguments.count; of_string_encoding_t encoding; - *argv = [self allocMemoryWithSize: sizeof(char *) - count: count + 2]; + *argv = of_malloc(count + 2, sizeof(char *)); encoding = [OFLocale encoding]; (*argv)[0] = (char *)[programName cStringWithEncoding: encoding]; @@ -250,48 +255,55 @@ (*argv)[i + 1] = NULL; } - (char **)of_environmentForDictionary: (OFDictionary *)environment { - OFEnumerator *keyEnumerator, *objectEnumerator; char **envp; - size_t i, count; + size_t count; of_string_encoding_t encoding; if (environment == nil) return NULL; encoding = [OFLocale encoding]; count = environment.count; - envp = [self allocMemoryWithSize: sizeof(char *) - count: count + 1]; - - keyEnumerator = [environment keyEnumerator]; - objectEnumerator = [environment objectEnumerator]; - - for (i = 0; i < count; i++) { - OFString *key; - OFString *object; - size_t keyLen, objectLen; - - key = [keyEnumerator nextObject]; - object = [objectEnumerator nextObject]; - - keyLen = [key cStringLengthWithEncoding: encoding]; - objectLen = [object cStringLengthWithEncoding: encoding]; - - envp[i] = [self allocMemoryWithSize: keyLen + objectLen + 2]; - - memcpy(envp[i], [key cStringWithEncoding: encoding], keyLen); - envp[i][keyLen] = '='; - memcpy(envp[i] + keyLen + 1, - [object cStringWithEncoding: encoding], objectLen); - envp[i][keyLen + objectLen + 1] = '\0'; - } - - envp[i] = NULL; + envp = of_calloc(count + 1, sizeof(char *)); + + @try { + OFEnumerator *keyEnumerator = [environment keyEnumerator]; + OFEnumerator *objectEnumerator = [environment objectEnumerator]; + + for (size_t i = 0; i < count; i++) { + OFString *key; + OFString *object; + size_t keyLen, objectLen; + + key = [keyEnumerator nextObject]; + object = [objectEnumerator nextObject]; + + keyLen = [key cStringLengthWithEncoding: encoding]; + objectLen = [object + cStringLengthWithEncoding: encoding]; + + envp[i] = of_malloc(keyLen + objectLen + 2, 1); + + memcpy(envp[i], + [key cStringWithEncoding: encoding], keyLen); + envp[i][keyLen] = '='; + memcpy(envp[i] + keyLen + 1, + [object cStringWithEncoding: encoding], objectLen); + envp[i][keyLen + objectLen + 1] = '\0'; + } + } @catch (id e) { + for (size_t i = 0; i < count; i++) + free(envp[i]); + + free(envp); + + @throw e; + } return envp; } - (bool)lowlevelIsAtEndOfStream Index: tests/OFDataTests.m ================================================================== --- tests/OFDataTests.m +++ tests/OFDataTests.m @@ -34,13 +34,12 @@ of_range_t range; TEST(@"+[dataWithItemSize:]", (mutable = [OFMutableData dataWithItemSize: 4096])) - OFObject *tmp = [[[OFObject alloc] init] autorelease]; - raw[0] = [tmp allocMemoryWithSize: 4096]; - raw[1] = [tmp allocMemoryWithSize: 4096]; + raw[0] = of_malloc(1, 4096); + raw[1] = of_malloc(1, 4096); memset(raw[0], 0xFF, 4096); memset(raw[1], 0x42, 4096); TEST(@"-[addItem:]", R([mutable addItem: raw[0]]) && R([mutable addItem: raw[1]])) @@ -205,9 +204,12 @@ count: SIZE_MAX]) EXPECT_EXCEPTION(@"Detect out of range in -[removeItemsInRange:]", OFOutOfRangeException, [mutable removeItemsInRange: of_range(mutable.count, 1)]) + + free(raw[0]); + free(raw[1]); objc_autoreleasePoolPop(pool); } @end Index: tests/OFObjectTests.m ================================================================== --- tests/OFObjectTests.m +++ tests/OFObjectTests.m @@ -85,53 +85,12 @@ @implementation TestsAppDelegate (OFObjectTests) - (void)objectTests { void *pool = objc_autoreleasePoolPush(); - OFObject *obj = [[[OFObject alloc] init] autorelease]; - void *p, *q, *r; OFObject *o; MyObj *m; - char *tmp; - - TEST(@"Allocating 4096 bytes", - (p = [obj allocMemoryWithSize: 4096]) != NULL) - - TEST(@"Freeing memory", R([obj freeMemory: p])) - - TEST(@"Allocating and freeing 4096 bytes 3 times", - (p = [obj allocMemoryWithSize: 4096]) != NULL && - (q = [obj allocMemoryWithSize: 4096]) != NULL && - (r = [obj allocMemoryWithSize: 4096]) != NULL && - R([obj freeMemory: p]) && R([obj freeMemory: q]) && - R([obj freeMemory: r])) - - tmp = [self allocMemoryWithSize: 1024]; - EXPECT_EXCEPTION(@"Detect freeing of memory not allocated by object", - OFMemoryNotPartOfObjectException, [obj freeMemory: tmp]) - - EXPECT_EXCEPTION(@"Detect out of memory on alloc", - OFOutOfMemoryException, tmp = [obj allocMemoryWithSize: TOO_BIG]) - - EXPECT_EXCEPTION(@"Detect out of memory on resize", - OFOutOfMemoryException, - { - p = [obj allocMemoryWithSize: 1]; - p = [obj resizeMemory: p - size: TOO_BIG]; - }) - [obj freeMemory: p]; - - TEST(@"Allocate when trying to resize NULL", - (p = [obj resizeMemory: NULL - size: 1024]) != NULL) - [obj freeMemory: p]; - - EXPECT_EXCEPTION(@"Detect resizing of memory not allocated by object", - OFMemoryNotPartOfObjectException, tmp = [obj resizeMemory: tmp - size: 2048]) - [self freeMemory: tmp]; TEST(@"+[description]", [[OFObject description] isEqual: @"OFObject"] && [[MyObj description] isEqual: @"MyObj"]) Index: tests/OFStreamTests.m ================================================================== --- tests/OFStreamTests.m +++ tests/OFStreamTests.m @@ -69,16 +69,18 @@ size_t pageSize = [OFSystemInfo pageSize]; StreamTester *t = [[[StreamTester alloc] init] autorelease]; OFString *str; char *cstr; - cstr = [t allocMemoryWithSize: pageSize - 2]; + cstr = of_malloc(pageSize - 2, 1); memset(cstr, 'X', pageSize - 3); cstr[pageSize - 3] = '\0'; TEST(@"-[readLine]", [[t readLine] isEqual: @"foo"] && [(str = [t readLine]) length] == pageSize - 3 && !strcmp(str.UTF8String, cstr)) + + free(cstr); objc_autoreleasePoolPop(pool); } @end