Index: src/OFData.m ================================================================== --- src/OFData.m +++ src/OFData.m @@ -180,44 +180,49 @@ } #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path { + char *buffer = NULL; + uintmax_t size; + @try { - uintmax_t size = [[[OFFileManager defaultManager] + OFFile *file; + + size = [[[OFFileManager defaultManager] attributesOfItemAtPath: path] fileSize]; - char *buffer; # if UINTMAX_MAX > SIZE_MAX if (size > SIZE_MAX) @throw [OFOutOfRangeException exception]; # endif - buffer = malloc((size_t)size); - if (buffer == NULL) + if ((buffer = malloc((size_t)size)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: (size_t)size]; - @try { - OFFile *file = [[OFFile alloc] initWithPath: path - mode: @"r"]; - @try { - [file readIntoBuffer: buffer - exactLength: (size_t)size]; - } @finally { - [file release]; - } - - self = [self initWithItemsNoCopy: buffer - count: (size_t)size - freeWhenDone: true]; - } @catch (id e) { - free(buffer); - @throw e; - } - } @catch (id e) { - [self release]; + file = [[OFFile alloc] initWithPath: path + mode: @"r"]; + @try { + [file readIntoBuffer: buffer + exactLength: (size_t)size]; + } @finally { + [file release]; + } + } @catch (id e) { + free(buffer); + [self release]; + + @throw e; + } + + @try { + self = [self initWithItemsNoCopy: buffer + count: (size_t)size + freeWhenDone: true]; + } @catch (id e) { + free(buffer); @throw e; } return self; } @@ -351,27 +356,27 @@ return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { + void *pool = objc_autoreleasePoolPush(); + OFString *stringValue; + @try { - void *pool = objc_autoreleasePoolPush(); - OFString *stringValue; - if (![[element name] isEqual: [self className]] || ![[element namespace] isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; stringValue = [element stringValue]; - - self = [self initWithBase64EncodedString: stringValue]; - - objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } + + self = [self initWithBase64EncodedString: stringValue]; + + objc_autoreleasePoolPop(pool); return self; } - (void)dealloc Index: src/OFFile.m ================================================================== --- src/OFFile.m +++ src/OFFile.m @@ -312,21 +312,24 @@ } - (instancetype)initWithURL: (OFURL *)URL mode: (OFString *)mode { + void *pool = objc_autoreleasePoolPush(); + OFString *fileSystemRepresentation; + @try { - void *pool = objc_autoreleasePoolPush(); - - self = [self initWithPath: [URL fileSystemRepresentation] - mode: mode]; - - objc_autoreleasePoolPop(pool); + fileSystemRepresentation = [URL fileSystemRepresentation]; } @catch (id e) { [self release]; @throw e; } + + self = [self initWithPath: fileSystemRepresentation + mode: mode]; + + objc_autoreleasePoolPop(pool); return self; } - (instancetype)initWithHandle: (of_file_handle_t)handle Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -903,18 +903,18 @@ encoding: (of_string_encoding_t)encoding { @try { if ([data itemSize] != 1) @throw [OFInvalidArgumentException exception]; - - self = [self initWithCString: [data items] - encoding: encoding - length: [data count]]; } @catch (id e) { [self release]; @throw e; } + + self = [self initWithCString: [data items] + encoding: encoding + length: [data count]]; return self; } - (instancetype)initWithString: (OFString *)string @@ -1020,11 +1020,11 @@ char *tmp; uintmax_t fileSize; @try { void *pool = objc_autoreleasePoolPush(); - OFFile *file; + OFFile *file = nil; @try { fileSize = [[[OFFileManager defaultManager] attributesOfItemAtPath: path] fileSize]; } @catch (OFRetrieveItemAttributesFailedException *e) { @@ -1039,30 +1039,53 @@ # if UINTMAX_MAX > SIZE_MAX if (fileSize > SIZE_MAX) @throw [OFOutOfRangeException exception]; #endif - file = [[OFFile alloc] initWithPath: path - mode: @"r"]; + /* + * We need one extra byte for the terminating zero if we want + * to use -[initWithUTF8StringNoCopy:length:freeWhenDone:]. + */ + if (SIZE_MAX - (size_t)fileSize < 1) + @throw [OFOutOfRangeException exception]; + + if ((tmp = malloc((size_t)fileSize + 1)) == NULL) + @throw [OFOutOfMemoryException + exceptionWithRequestedSize: (size_t)fileSize]; @try { - tmp = [self allocMemoryWithSize: (size_t)fileSize]; + file = [[OFFile alloc] initWithPath: path + mode: @"r"]; [file readIntoBuffer: tmp exactLength: (size_t)fileSize]; + } @catch (id e) { + free(tmp); + @throw e; } @finally { [file release]; } + + tmp[(size_t)fileSize] = '\0'; } @catch (id e) { [self release]; @throw e; } - self = [self initWithCString: tmp - encoding: encoding - length: (size_t)fileSize]; - [self freeMemory: tmp]; + if (encoding == OF_STRING_ENCODING_UTF_8) + self = [self initWithUTF8StringNoCopy: tmp + length: (size_t)fileSize + freeWhenDone: true]; + else { + @try { + self = [self initWithCString: tmp + encoding: encoding + length: (size_t)fileSize]; + } @finally { + free(tmp); + } + } return self; } #endif @@ -1073,32 +1096,35 @@ } - (instancetype)initWithContentsOfURL: (OFURL *)URL encoding: (of_string_encoding_t)encoding { + void *pool = objc_autoreleasePoolPush(); + OFData *data; + @try { - void *pool = objc_autoreleasePoolPush(); - OFData *data = [OFData dataWithContentsOfURL: URL]; - - self = [self initWithCString: [data items] - encoding: encoding - length: [data count]]; - - objc_autoreleasePoolPop(pool); + data = [OFData dataWithContentsOfURL: URL]; } @catch (id e) { [self release]; @throw e; } + + self = [self initWithCString: [data items] + encoding: encoding + length: [data count]]; + + objc_autoreleasePoolPop(pool); return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { + void *pool = objc_autoreleasePoolPush(); + OFString *stringValue; + @try { - void *pool = objc_autoreleasePoolPush(); - if (![[element namespace] isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; if ([self isKindOfClass: [OFMutableString class]]) { if (![[element name] isEqual: @"OFMutableString"]) @@ -1106,17 +1132,19 @@ } else { if (![[element name] isEqual: @"OFString"]) @throw [OFInvalidArgumentException exception]; } - self = [self initWithString: [element stringValue]]; - - objc_autoreleasePoolPop(pool); + stringValue = [element stringValue]; } @catch (id e) { [self release]; @throw e; } + + self = [self initWithString: stringValue]; + + objc_autoreleasePoolPop(pool); return self; } - (size_t)of_getCString: (char *)cString Index: src/OFURL.m ================================================================== --- src/OFURL.m +++ src/OFURL.m @@ -598,24 +598,26 @@ } #ifdef OF_HAVE_FILES - (instancetype)initFileURLWithPath: (OFString *)path { + bool isDirectory; + @try { void *pool = objc_autoreleasePoolPush(); - bool isDirectory; isDirectory = ([path hasSuffix: OF_PATH_DELIMITER_STRING] || [OFURLHandler_file of_directoryExistsAtPath: path]); - self = [self initFileURLWithPath: path - isDirectory: isDirectory]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } + + self = [self initFileURLWithPath: path + isDirectory: isDirectory]; return self; } - (instancetype)initFileURLWithPath: (OFString *)path @@ -676,24 +678,27 @@ } #endif - (instancetype)initWithSerialization: (OFXMLElement *)element { + void *pool = objc_autoreleasePoolPush(); + OFString *stringValue; + @try { - void *pool = objc_autoreleasePoolPush(); - if (![[element name] isEqual: [self className]] || ![[element namespace] isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; - self = [self initWithString: [element stringValue]]; - - objc_autoreleasePoolPop(pool); + stringValue = [element stringValue]; } @catch (id e) { [self release]; @throw e; } + + self = [self initWithString: stringValue]; + + objc_autoreleasePoolPop(pool); return self; } - (void)dealloc