Skip to content
This repository has been archived by the owner on Jan 17, 2023. It is now read-only.

Commit

Permalink
Fix dangerous usage of error pointer
Browse files Browse the repository at this point in the history
error ISN'T a NSError* with __block storage.
error IS a pointer to an NSError __autoreleasing* with automatic storage.

So capturing error in a block does capture a pointer to an object with automatic storage duration (on the stack). As the block will be executed asynchronously, dereferencing error would refer to an object outside of its lifetime, which is undefined behavior.
  • Loading branch information
baarde committed Jun 21, 2013
1 parent 6370cf5 commit 6ee54b1
Showing 1 changed file with 13 additions and 16 deletions.
29 changes: 13 additions & 16 deletions AFIncrementalStore/AFIncrementalStore.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,10 @@
return [string hasPrefix:kAFReferenceObjectPrefix] ? [string substringFromIndex:[kAFReferenceObjectPrefix length]] : string;
}

static inline void AFSaveManagedObjectContextOrThrowInternalConsistencyException(NSManagedObjectContext *managedObjectContext, NSError * __autoreleasing *error) {
if (![managedObjectContext save:error]) {
if (!error) {
*error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSCoreDataError userInfo:nil];
}

@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:[*error localizedFailureReason] userInfo:[NSDictionary dictionaryWithObject:*error forKey:NSUnderlyingErrorKey]];
static inline void AFSaveManagedObjectContextOrThrowInternalConsistencyException(NSManagedObjectContext *managedObjectContext) {
NSError *error = nil;
if (![managedObjectContext save:&error]) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:[error localizedFailureReason] userInfo:[NSDictionary dictionaryWithObject:error forKey:NSUnderlyingErrorKey]];
}
}

Expand Down Expand Up @@ -413,13 +410,13 @@ - (id)executeFetchRequest:(NSFetchRequest *)fetchRequest
childContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;

[childContext performBlockAndWait:^{
[self insertOrUpdateObjectsFromRepresentations:representationOrArrayOfRepresentations ofEntity:fetchRequest.entity fromResponse:operation.response withContext:childContext error:error completionBlock:^(NSArray *managedObjects, NSArray *backingObjects) {
[self insertOrUpdateObjectsFromRepresentations:representationOrArrayOfRepresentations ofEntity:fetchRequest.entity fromResponse:operation.response withContext:childContext error:nil completionBlock:^(NSArray *managedObjects, NSArray *backingObjects) {
NSSet *childObjects = [childContext registeredObjects];
AFSaveManagedObjectContextOrThrowInternalConsistencyException(childContext, error);
AFSaveManagedObjectContextOrThrowInternalConsistencyException(childContext);

NSManagedObjectContext *backingContext = [self backingManagedObjectContext];
[backingContext performBlockAndWait:^{
AFSaveManagedObjectContextOrThrowInternalConsistencyException(backingContext, error);
AFSaveManagedObjectContextOrThrowInternalConsistencyException(backingContext);
}];

[context performBlockAndWait:^{
Expand Down Expand Up @@ -747,7 +744,7 @@ - (NSIncrementalStoreNode *)newValuesForObjectWithID:(NSManagedObjectID *)object

AFHTTPRequestOperation *operation = [self.HTTPClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, NSDictionary *representation) {
[childContext performBlock:^{
NSManagedObject *managedObject = [childContext existingObjectWithID:objectID error:error];
NSManagedObject *managedObject = [childContext existingObjectWithID:objectID error:nil];

NSMutableDictionary *mutableAttributeValues = [attributeValues mutableCopy];
[mutableAttributeValues addEntriesFromDictionary:[self.HTTPClient attributesForRepresentation:representation ofEntity:managedObject.entity fromResponse:operation.response]];
Expand All @@ -768,11 +765,11 @@ - (NSIncrementalStoreNode *)newValuesForObjectWithID:(NSManagedObjectID *)object
}];

[childContext performBlockAndWait:^{
AFSaveManagedObjectContextOrThrowInternalConsistencyException(childContext, error);
AFSaveManagedObjectContextOrThrowInternalConsistencyException(childContext);

NSManagedObjectContext *backingContext = [self backingManagedObjectContext];
[backingContext performBlockAndWait:^{
AFSaveManagedObjectContextOrThrowInternalConsistencyException(backingContext, error);
AFSaveManagedObjectContextOrThrowInternalConsistencyException(backingContext);
}];
}];

Expand Down Expand Up @@ -812,7 +809,7 @@ - (id)newValueForRelationship:(NSRelationshipDescription *)relationship
[childContext performBlock:^{
id representationOrArrayOfRepresentations = [self.HTTPClient representationOrArrayOfRepresentationsOfEntity:relationship.destinationEntity fromResponseObject:responseObject];

[self insertOrUpdateObjectsFromRepresentations:representationOrArrayOfRepresentations ofEntity:relationship.destinationEntity fromResponse:operation.response withContext:childContext error:error completionBlock:^(NSArray *managedObjects, NSArray *backingObjects) {
[self insertOrUpdateObjectsFromRepresentations:representationOrArrayOfRepresentations ofEntity:relationship.destinationEntity fromResponse:operation.response withContext:childContext error:nil completionBlock:^(NSArray *managedObjects, NSArray *backingObjects) {
NSManagedObject *managedObject = [childContext objectWithID:objectID];

NSManagedObjectID *backingObjectID = [self objectIDForBackingObjectForEntity:[objectID entity] withResourceIdentifier:AFResourceIdentifierFromReferenceObject([self referenceObjectForObjectID:objectID])];
Expand All @@ -836,11 +833,11 @@ - (id)newValueForRelationship:(NSRelationshipDescription *)relationship
}];

[childContext performBlockAndWait:^{
AFSaveManagedObjectContextOrThrowInternalConsistencyException(childContext, error);
AFSaveManagedObjectContextOrThrowInternalConsistencyException(childContext);

NSManagedObjectContext *backingContext = [self backingManagedObjectContext];
[backingContext performBlockAndWait:^{
AFSaveManagedObjectContextOrThrowInternalConsistencyException(backingContext, error);
AFSaveManagedObjectContextOrThrowInternalConsistencyException(backingContext);
}];
}];

Expand Down

0 comments on commit 6ee54b1

Please sign in to comment.