summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Schleifer <js@heap.zone>2018-02-25 18:16:23 +0100
committerJonathan Schleifer <js@heap.zone>2018-02-25 18:16:23 +0100
commit202321e08bcf804082b494743d7408a5f5601c55 (patch)
treeee523fa01d4a0f5602914b9faa589bc1b92afe0d
parentec62b5dee7c3f78e50c03ca9c0fb40e200ac4ea9 (diff)
No self = [self init…] with self-releasing @catch
When using self = [self init…], this already releases self on an exception, so using it inside of a @try / @catch block that releases self would lead to a double-release.
-rw-r--r--src/OFData.m57
-rw-r--r--src/OFFile.m15
-rw-r--r--src/OFString.m78
-rw-r--r--src/OFURL.m21
4 files changed, 106 insertions, 65 deletions
diff --git a/src/OFData.m b/src/OFData.m
index 4aa77655..6535752b 100644
--- a/src/OFData.m
+++ b/src/OFData.m
@@ -182,40 +182,45 @@ _references_to_categories_of_OFData(void)
#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];
+ file = [[OFFile alloc] initWithPath: path
+ mode: @"r"];
@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;
+ [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;
}
@@ -353,24 +358,24 @@ _references_to_categories_of_OFData(void)
- (instancetype)initWithSerialization: (OFXMLElement *)element
{
- @try {
- void *pool = objc_autoreleasePoolPush();
- OFString *stringValue;
+ void *pool = objc_autoreleasePoolPush();
+ OFString *stringValue;
+ @try {
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;
}
diff --git a/src/OFFile.m b/src/OFFile.m
index a94978dc..54af26bb 100644
--- a/src/OFFile.m
+++ b/src/OFFile.m
@@ -314,18 +314,21 @@ parseMode(const char *mode, bool *append)
- (instancetype)initWithURL: (OFURL *)URL
mode: (OFString *)mode
{
- @try {
- void *pool = objc_autoreleasePoolPush();
+ void *pool = objc_autoreleasePoolPush();
+ OFString *fileSystemRepresentation;
- self = [self initWithPath: [URL fileSystemRepresentation]
- mode: mode];
-
- objc_autoreleasePoolPop(pool);
+ @try {
+ fileSystemRepresentation = [URL fileSystemRepresentation];
} @catch (id e) {
[self release];
@throw e;
}
+ self = [self initWithPath: fileSystemRepresentation
+ mode: mode];
+
+ objc_autoreleasePoolPop(pool);
+
return self;
}
diff --git a/src/OFString.m b/src/OFString.m
index c92f9d82..410c460b 100644
--- a/src/OFString.m
+++ b/src/OFString.m
@@ -905,15 +905,15 @@ decomposedString(OFString *self, const char *const *const *table, size_t size)
@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;
}
@@ -1022,7 +1022,7 @@ decomposedString(OFString *self, const char *const *const *table, size_t size)
@try {
void *pool = objc_autoreleasePoolPush();
- OFFile *file;
+ OFFile *file = nil;
@try {
fileSize = [[[OFFileManager defaultManager]
@@ -1041,26 +1041,49 @@ decomposedString(OFString *self, const char *const *const *table, size_t size)
@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;
}
@@ -1075,28 +1098,31 @@ decomposedString(OFString *self, const char *const *const *table, size_t size)
- (instancetype)initWithContentsOfURL: (OFURL *)URL
encoding: (of_string_encoding_t)encoding
{
- @try {
- void *pool = objc_autoreleasePoolPush();
- OFData *data = [OFData dataWithContentsOfURL: URL];
-
- self = [self initWithCString: [data items]
- encoding: encoding
- length: [data count]];
+ void *pool = objc_autoreleasePoolPush();
+ OFData *data;
- objc_autoreleasePoolPop(pool);
+ @try {
+ 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
{
- @try {
- void *pool = objc_autoreleasePoolPush();
+ void *pool = objc_autoreleasePoolPush();
+ OFString *stringValue;
+ @try {
if (![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException exception];
@@ -1108,14 +1134,16 @@ decomposedString(OFString *self, const char *const *const *table, size_t size)
@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;
}
diff --git a/src/OFURL.m b/src/OFURL.m
index 1f398b5a..38b6c29b 100644
--- a/src/OFURL.m
+++ b/src/OFURL.m
@@ -600,14 +600,13 @@ of_url_verify_escaped(OFString *string, OFCharacterSet *characterSet)
#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) {
@@ -615,6 +614,9 @@ of_url_verify_escaped(OFString *string, OFCharacterSet *characterSet)
@throw e;
}
+ self = [self initFileURLWithPath: path
+ isDirectory: isDirectory];
+
return self;
}
@@ -678,21 +680,24 @@ of_url_verify_escaped(OFString *string, OFCharacterSet *characterSet)
- (instancetype)initWithSerialization: (OFXMLElement *)element
{
- @try {
- void *pool = objc_autoreleasePoolPush();
+ void *pool = objc_autoreleasePoolPush();
+ OFString *stringValue;
+ @try {
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;
}