diff --git a/infer/tests/codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m b/infer/tests/codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m new file mode 100644 index 000000000..153fb4dac --- /dev/null +++ b/infer/tests/codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m @@ -0,0 +1,290 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +void addNilInDictBad(NSMutableDictionary* mDict) { + id value = nil; + [mDict setObject:value forKey:@"somestring"]; +} + +void addNSNullInDictOk(NSMutableDictionary* mDict) { + [mDict setObject:[NSNull null] forKey:@"somestring"]; +} + +void addObjectInDictOk(NSMutableDictionary* mDict) { + NSString* o = [NSString new]; + [mDict setObject:o forKey:@"somestring"]; +} + +void addObjectKeyNilInDictBad(NSMutableDictionary* mDict) { + NSString* o = [NSString new]; + [mDict setObject:o forKey:nil]; +} + +void addObjectInDict(NSMutableDictionary* mDict, id value) { + [mDict setObject:value forKey:@"somestring"]; +} + +void addNilInDictBracketsOk(NSMutableDictionary* mDict) { + mDict[@"key2"] = nil; // Passing nil will cause any object corresponding + // to a key to be removed from the dictionary. +} + +void addNilKeyInDictBracketsBad(NSMutableDictionary* mDict) { + id key = nil; + mDict[key] = @"somestring"; +} + +void addInDictBracketsOk(NSMutableDictionary* mDict) { + mDict[@"key"] = @"somestring"; +} + +void removeObjectFromDict(NSMutableDictionary* mDict, id key) { + [mDict removeObjectForKey:key]; +} + +void removeObjectFromDictKeyNilBad(NSMutableDictionary* mDict) { + removeObjectFromDict(mDict, nil); +} + +void removeObjectFromDictKeyNotNilOK(NSMutableDictionary* mDict) { + removeObjectFromDict(mDict, @"somestring"); +} + +void dictionaryWithSharedKeySetOk() { + id sharedKeySet = [NSDictionary sharedKeySetForKeys:@[ @"key1", @"key2" ]]; + NSMutableDictionary* mDict = + [NSMutableDictionary dictionaryWithSharedKeySet:sharedKeySet]; +} + +void dictionaryWithSharedKeySetBad() { + NSMutableDictionary* mDict = + [NSMutableDictionary dictionaryWithSharedKeySet:nil]; +} + +void testNilMessagingForModelNilNilOK_FP() { addObjectInDict(nil, nil); } + +void testNilMessagingForModelNilStringOK() { + addObjectInDict(nil, @"somestring"); +} + +void testNilMessagingForModelNotNilDictBad(NSMutableDictionary* mDict) { + addObjectInDict(mDict, nil); +} + +void addNilInArrayBad(NSMutableArray* mArray) { [mArray addObject:nil]; } + +void addObjectInArrayOk(NSMutableArray* mArray) { + [mArray addObject:[NSString new]]; +} + +void insertNilInArrayBad(NSMutableArray* mArray) { + [mArray insertObject:nil atIndex:0]; +} + +void insertObjectInArrayOk(NSMutableArray* mArray) { + [mArray insertObject:[NSString new] atIndex:0]; +} + +void replaceNilInArrayBad(NSMutableArray* mArray) { + [mArray replaceObjectAtIndex:0 withObject:nil]; +} + +void replaceObjectInArrayOk(NSMutableArray* mArray) { + [mArray replaceObjectAtIndex:0 withObject:[NSString new]]; +} + +void removeObjectsAtIndexesFromArray(NSMutableArray* mArray, id indexset) { + [mArray removeObjectsAtIndexes:indexset]; +} + +void removeObjectsAtIndexesFromArrayOK(NSMutableArray* mArray) { + NSIndexSet* indexset = [NSIndexSet indexSetWithIndex:1]; + removeObjectsAtIndexesFromArray(mArray, indexset); +} + +void removeObjectsAtIndexesFromArrayBad(NSMutableArray* mArray) { + removeObjectsAtIndexesFromArray(mArray, nil); +} + +void replaceObjectsAtIndexesWithObjectsInArray(NSMutableArray* mArray, + id indexset, + id objects) { + [mArray replaceObjectsAtIndexes:indexset withObjects:objects]; +} + +void replaceObjectsAtIndexesWithObjectsInArrayOk(NSMutableArray* mArray) { + NSIndexSet* indexset = [NSIndexSet indexSetWithIndex:0]; + replaceObjectsAtIndexesWithObjectsInArray( + mArray, indexset, @[ [NSString new] ]); +} + +void replaceObjectsAtNilIndexesWithObjectsInArrayBad(NSMutableArray* mArray) { + replaceObjectsAtIndexesWithObjectsInArray(mArray, nil, @[ [NSString new] ]); +} + +void replaceObjectsAtIndexesWithNilObjectsInArrayBad(NSMutableArray* mArray) { + NSIndexSet* indexset = [NSIndexSet indexSetWithIndex:0]; + replaceObjectsAtIndexesWithObjectsInArray(mArray, indexset, nil); +} + +void addInDictBracketsDefault(NSMutableDictionary* mDict, + NSString* key) { + mDict[key] = @"default"; +} + +void accessZeroElementOk(NSMutableDictionary* mDict) { + NSArray* array = + [[NSUserDefaults standardUserDefaults] arrayForKey:@"key"]; + NSString* key = array[0]; + addInDictBracketsDefault(mDict, key); +} + +void addObjectInMSet(NSMutableSet* mSet, id object) { [mSet addObject:object]; } + +void addObjectInMSetOk(NSMutableSet* mSet) { + addObjectInMSet(mSet, @"somestring"); +} + +void addObjectInMSetBad(NSMutableSet* mSet) { addObjectInMSet(mSet, nil); } + +void removeObjectFromMSet(NSMutableSet* mSet, id object) { + [mSet removeObject:object]; +} + +void removeObjectFromMSetOk(NSMutableSet* mSet) { + removeObjectFromMSet(mSet, @"somestring"); +} + +void removeObjectFromMSetBad(NSMutableSet* mSet) { + removeObjectFromMSet(mSet, nil); +} + +void dictionaryLiteral(id key, id object) { + NSDictionary* dict = @{key : object}; +} + +void dictionaryLiteralOk() { dictionaryLiteral(@"key", @"obj"); } + +void dictionaryLiteralKeyNilBad() { dictionaryLiteral(nil, @"obj"); } + +void dictionaryLiteralObjectNilBad() { dictionaryLiteral(@"key", nil); } + +void dictionaryWithObjectsForKeysCount(id key, id object) { + NSString* values[1]; + values[0] = object; + + NSString* keys[1]; + keys[0] = key; + + NSDictionary* dict = [NSDictionary dictionaryWithObjects:values + forKeys:keys + count:1]; +} + +void dictionaryWithObjectsForKeysCountOk() { + dictionaryWithObjectsForKeysCount(@"key", @"somestring"); +} + +void FN_dictionaryWithObjectsForKeysCountKeyNilBad() { + dictionaryWithObjectsForKeysCount(nil, @"somestring"); +} + +void FN_dictionaryWithObjectsForKeysCountObjectNilBad() { + dictionaryWithObjectsForKeysCount(@"key", nil); +} + +void dictionaryWithObjectForKey(id key, id object) { + NSDictionary* dict = [NSDictionary dictionaryWithObject:object forKey:key]; +} + +void dictionaryWithObjectForKeyOk() { + dictionaryWithObjectForKey(@"key", @"somestring"); +} + +void dictionaryWithObjectForKeyNilBad() { + dictionaryWithObjectForKey(nil, @"somestring"); +} + +void dictionaryWithNilObjectForKeyBad() { + dictionaryWithObjectForKey(@"key", nil); +} + +void dictionaryWithSharedKeySetForKeys(id keys) { + id sharedKeySet = [NSDictionary sharedKeySetForKeys:keys]; +} + +void dictionaryWithSharedKeySetForKeysOk() { + dictionaryWithSharedKeySetForKeys(@[ @"key1", @"key2" ]); +} + +void dictionaryWithSharedKeySetForKeysBad() { + dictionaryWithSharedKeySetForKeys(nil); +} + +void setWithObject(id object) { NSSet* set = [NSSet setWithObject:object]; } + +void setWithObjectOk() { setWithObject(@"obj"); } + +void setWithObjectBad() { setWithObject(nil); } + +void setByAddingObject(id object) { + NSSet* set = [NSSet set]; + set = [set setByAddingObject:object]; +} + +void setByAddingObjectOk() { setByAddingObject(@"obj"); } + +void setByAddingObjectBad() { setByAddingObject(nil); } + +void setWithObjectsForCount(id object) { + NSString* values[1]; + values[0] = object; + + NSSet* set = [NSSet setWithObjects:values count:1]; +} + +void setWithObjectsForCountOk() { setWithObjectsForCount(@"obj"); } + +void FN_setWithObjectsForCountBad() { setWithObjectsForCount(nil); } + +void setInitWithObjectsForCount(id object) { + NSString* values[1]; + values[0] = object; + + NSSet* set = [[NSSet alloc] initWithObjects:values count:1]; +} + +void setInitWithObjectsForCountOk() { setInitWithObjectsForCount(@"obj"); } + +void FN_setInitWithObjectsForCountBad() { setInitWithObjectsForCount(nil); } + +void arrayLiteral(id object) { NSArray* array = @[ object ]; } + +void arrayLiteralOk() { arrayLiteral(@"obj"); } + +void arrayLiteralNilBad() { arrayLiteral(nil); } + +void arrayWithObject(id object) { + NSArray* array = [NSArray arrayWithObject:object]; +} + +void arrayWithObjectOK() { arrayWithObject(@"obj"); } + +void arrayWithObjectNilBad() { arrayWithObject(nil); } + +void arrayWithObjects(id object) { + NSString* values[1]; + values[0] = object; + + NSArray* array = [NSArray arrayWithObjects:values count:1]; +} + +void arrayWithObjectsOk() { arrayWithObjects(@"obj"); } + +void FN_arrayWithObjectsNilBad() { arrayWithObjects(nil); } diff --git a/infer/tests/codetoanalyze/objc/pulse/issues.exp b/infer/tests/codetoanalyze/objc/pulse/issues.exp index 4f44be83e..2149f7c24 100644 --- a/infer/tests/codetoanalyze/objc/pulse/issues.exp +++ b/infer/tests/codetoanalyze/objc/pulse/issues.exp @@ -13,6 +13,30 @@ codetoanalyze/objc/pulse/NPENilBlocks.m, BlockA.assignNilBad, 5, NIL_BLOCK_CALL, codetoanalyze/objc/pulse/NPENilBlocks.m, BlockA.paramAssignNilBad:, 3, NIL_BLOCK_CALL, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] codetoanalyze/objc/pulse/NPENilBlocks.m, BlockA.paramReassignNilBad:, 6, NIL_BLOCK_CALL, no_bucket, ERROR, [is the null pointer,assigned,assigned,invalid access occurs here] codetoanalyze/objc/pulse/NPENilBlocks.m, calldoSomethingThenCallbackWithNilBad, 2, NIL_BLOCK_CALL, no_bucket, ERROR, [is the null pointer,when calling `BlockA.doSomethingThenCallback:` here,parameter `my_block` of BlockA.doSomethingThenCallback:,invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, addNilInArrayBad, 0, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,in call to `NSMutableArray.addObject:` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, addNilInDictBad, 2, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,assigned,in call to `NSMutableDictionary.setObject:forKey:` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, addNilKeyInDictBracketsBad, 2, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,assigned,in call to `mutableDictionary[someKey] = value` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, addObjectInMSetBad, 0, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `addObjectInMSet` here,parameter `object` of addObjectInMSet,in call to `NSMutableSet.addObject:` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, addObjectKeyNilInDictBad, 2, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,in call to `NSMutableDictionary.setObject:forKey:` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, arrayLiteralNilBad, 0, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,when calling `arrayLiteral` here,parameter `object` of arrayLiteral,invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, arrayWithObjectNilBad, 0, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `arrayWithObject` here,parameter `object` of arrayWithObject,in call to `NSArray.arrayWithObject` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, dictionaryLiteralKeyNilBad, 0, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,when calling `dictionaryLiteral` here,parameter `key` of dictionaryLiteral,invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, dictionaryLiteralObjectNilBad, 0, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,when calling `dictionaryLiteral` here,parameter `object` of dictionaryLiteral,invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, dictionaryWithNilObjectForKeyBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `dictionaryWithObjectForKey` here,parameter `object` of dictionaryWithObjectForKey,in call to `NSDictionary.dictionaryWithObject:forKey:` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, dictionaryWithObjectForKeyNilBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `dictionaryWithObjectForKey` here,parameter `key` of dictionaryWithObjectForKey,in call to `NSDictionary.dictionaryWithObject:forKey:` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, dictionaryWithSharedKeySetBad, 2, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,in call to `NSMutableDictionary.dictionaryWithSharedKeySet` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, dictionaryWithSharedKeySetForKeysBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `dictionaryWithSharedKeySetForKeys` here,parameter `keys` of dictionaryWithSharedKeySetForKeys,in call to `NSDictionary.sharedKeySetForKeys` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, insertNilInArrayBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,in call to `NSMutableArray.insertObject:atIndex:` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, removeObjectFromDictKeyNilBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `removeObjectFromDict` here,parameter `key` of removeObjectFromDict,in call to `NSMutableDictionary.removeObjectForKey` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, removeObjectFromMSetBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `removeObjectFromMSet` here,parameter `object` of removeObjectFromMSet,in call to `NSMutableSet.removeObject:` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, removeObjectsAtIndexesFromArrayBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `removeObjectsAtIndexesFromArray` here,parameter `indexset` of removeObjectsAtIndexesFromArray,in call to `NSMutableArray.removeObjectsAtIndexes:` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, replaceNilInArrayBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,in call to `NSMutableArray.replaceObjectAtIndex:withObject:` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, replaceObjectsAtIndexesWithNilObjectsInArrayBad, 2, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `replaceObjectsAtIndexesWithObjectsInArray` here,parameter `objects` of replaceObjectsAtIndexesWithObjectsInArray,in call to `NSMutableArray.replaceObjectsAtIndexes:withObjects:` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, replaceObjectsAtNilIndexesWithObjectsInArrayBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `replaceObjectsAtIndexesWithObjectsInArray` here,parameter `indexset` of replaceObjectsAtIndexesWithObjectsInArray,in call to `NSMutableArray.replaceObjectsAtIndexes:withObjects:` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, setByAddingObjectBad, 0, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `setByAddingObject` here,parameter `object` of setByAddingObject,in call to `NSSet.setByAddingObject` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, setWithObjectBad, 0, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `setWithObject` here,parameter `object` of setWithObject,in call to `NSSet.setWithObject` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, testNilMessagingForModelNilNilOK_FP, 0, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `addObjectInDict` here,parameter `value` of addObjectInDict,in call to `NSMutableDictionary.setObject:forKey:` (modelled),invalid access occurs here] +codetoanalyze/objc/pulse/NPENilInsertionIntoCollection.m, testNilMessagingForModelNotNilDictBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `addObjectInDict` here,parameter `value` of addObjectInDict,in call to `NSMutableDictionary.setObject:forKey:` (modelled),invalid access occurs here] codetoanalyze/objc/pulse/uninit.m, Uninit.call_setter_c_struct_bad, 3, PULSE_UNINITIALIZED_VALUE, no_bucket, ERROR, [struct field address `x` created,when calling `Uninit.setS:` here,parameter `s` of Uninit.setS:,read to uninitialized value occurs here] codetoanalyze/objc/pulse/use_after_free.m, PulseTest.use_after_free_simple_in_objc_method_bad:, 2, USE_AFTER_FREE, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `x` of PulseTest.use_after_free_simple_in_objc_method_bad:,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,parameter `x` of PulseTest.use_after_free_simple_in_objc_method_bad:,invalid access occurs here] codetoanalyze/objc/pulse/use_after_free.m, use_after_free_simple_bad, 2, USE_AFTER_FREE, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `x` of use_after_free_simple_bad,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,parameter `x` of use_after_free_simple_bad,invalid access occurs here] diff --git a/infer/tests/codetoanalyze/objcpp/pulse/NPEBasic.mm b/infer/tests/codetoanalyze/objcpp/pulse/NPEBasic.mm index 87df40604..a85b0a945 100644 --- a/infer/tests/codetoanalyze/objcpp/pulse/NPEBasic.mm +++ b/infer/tests/codetoanalyze/objcpp/pulse/NPEBasic.mm @@ -200,288 +200,6 @@ void testUnknownNilSpecOk() { NSDictionary* dict = @{@"helloString" : str}; } -void addNilInDictBad(NSMutableDictionary* mDict) { - id value = nil; - [mDict setObject:value forKey:@"somestring"]; -} - -void addNSNullInDictOk(NSMutableDictionary* mDict) { - [mDict setObject:[NSNull null] forKey:@"somestring"]; -} - -void addObjectInDictOk(NSMutableDictionary* mDict) { - SomeObject* o = [SomeObject new]; - [mDict setObject:o forKey:@"somestring"]; -} - -void addObjectKeyNilInDictBad(NSMutableDictionary* mDict) { - SomeObject* o = [SomeObject new]; - [mDict setObject:o forKey:nil]; -} - -void addObjectInDict(NSMutableDictionary* mDict, id value) { - [mDict setObject:value forKey:@"somestring"]; -} - -void addNilInDictBracketsOk(NSMutableDictionary* mDict) { - mDict[@"key2"] = nil; // Passing nil will cause any object corresponding - // to a key to be removed from the dictionary. -} - -void addNilKeyInDictBracketsBad(NSMutableDictionary* mDict) { - id key = nil; - mDict[key] = @"somestring"; -} - -void addInDictBracketsOk(NSMutableDictionary* mDict) { - mDict[@"key"] = @"somestring"; -} - -void removeObjectFromDict(NSMutableDictionary* mDict, id key) { - [mDict removeObjectForKey:key]; -} - -void removeObjectFromDictKeyNilBad(NSMutableDictionary* mDict) { - removeObjectFromDict(mDict, nil); -} - -void removeObjectFromDictKeyNotNilOK(NSMutableDictionary* mDict) { - removeObjectFromDict(mDict, @"somestring"); -} - -void dictionaryWithSharedKeySetOk() { - id sharedKeySet = [NSDictionary sharedKeySetForKeys:@[ @"key1", @"key2" ]]; - NSMutableDictionary* mDict = - [NSMutableDictionary dictionaryWithSharedKeySet:sharedKeySet]; -} - -void dictionaryWithSharedKeySetBad() { - NSMutableDictionary* mDict = - [NSMutableDictionary dictionaryWithSharedKeySet:nil]; -} - -void testNilMessagingForModelNilNilOK_FP() { addObjectInDict(nil, nil); } - -void testNilMessagingForModelNilStringOK() { - addObjectInDict(nil, @"somestring"); -} - -void testNilMessagingForModelNotNilDictBad(NSMutableDictionary* mDict) { - addObjectInDict(mDict, nil); -} - -void addNilInArrayBad(NSMutableArray* mArray) { [mArray addObject:nil]; } - -void addObjectInArrayOk(NSMutableArray* mArray) { - [mArray addObject:[SomeObject new]]; -} - -void insertNilInArrayBad(NSMutableArray* mArray) { - [mArray insertObject:nil atIndex:0]; -} - -void insertObjectInArrayOk(NSMutableArray* mArray) { - [mArray insertObject:[SomeObject new] atIndex:0]; -} - -void replaceNilInArrayBad(NSMutableArray* mArray) { - [mArray replaceObjectAtIndex:0 withObject:nil]; -} - -void replaceObjectInArrayOk(NSMutableArray* mArray) { - [mArray replaceObjectAtIndex:0 withObject:[SomeObject new]]; -} - -void removeObjectsAtIndexesFromArray(NSMutableArray* mArray, id indexset) { - [mArray removeObjectsAtIndexes:indexset]; -} - -void removeObjectsAtIndexesFromArrayOK(NSMutableArray* mArray) { - NSIndexSet* indexset = [NSIndexSet indexSetWithIndex:1]; - removeObjectsAtIndexesFromArray(mArray, indexset); -} - -void removeObjectsAtIndexesFromArrayBad(NSMutableArray* mArray) { - removeObjectsAtIndexesFromArray(mArray, nil); -} - -void replaceObjectsAtIndexesWithObjectsInArray(NSMutableArray* mArray, - id indexset, - id objects) { - [mArray replaceObjectsAtIndexes:indexset withObjects:objects]; -} - -void replaceObjectsAtIndexesWithObjectsInArrayOk(NSMutableArray* mArray) { - NSIndexSet* indexset = [NSIndexSet indexSetWithIndex:0]; - replaceObjectsAtIndexesWithObjectsInArray( - mArray, indexset, @[ [SomeObject new] ]); -} - -void replaceObjectsAtNilIndexesWithObjectsInArrayBad(NSMutableArray* mArray) { - replaceObjectsAtIndexesWithObjectsInArray(mArray, nil, @[ [SomeObject new] ]); -} - -void replaceObjectsAtIndexesWithNilObjectsInArrayBad(NSMutableArray* mArray) { - NSIndexSet* indexset = [NSIndexSet indexSetWithIndex:0]; - replaceObjectsAtIndexesWithObjectsInArray(mArray, indexset, nil); -} - -void addInDictBracketsDefault(NSMutableDictionary* mDict, - NSString* key) { - mDict[key] = @"default"; -} - -void accessZeroElementOk(NSMutableDictionary* mDict) { - NSArray* array = - [[NSUserDefaults standardUserDefaults] arrayForKey:@"key"]; - NSString* key = array[0]; - addInDictBracketsDefault(mDict, key); -} - -void addObjectInMSet(NSMutableSet* mSet, id object) { [mSet addObject:object]; } - -void addObjectInMSetOk(NSMutableSet* mSet) { - addObjectInMSet(mSet, @"somestring"); -} - -void addObjectInMSetBad(NSMutableSet* mSet) { addObjectInMSet(mSet, nil); } - -void removeObjectFromMSet(NSMutableSet* mSet, id object) { - [mSet removeObject:object]; -} - -void removeObjectFromMSetOk(NSMutableSet* mSet) { - removeObjectFromMSet(mSet, @"somestring"); -} - -void removeObjectFromMSetBad(NSMutableSet* mSet) { - removeObjectFromMSet(mSet, nil); -} - -void dictionaryLiteral(id key, id object) { - NSDictionary* dict = @{key : object}; -} - -void dictionaryLiteralOk() { dictionaryLiteral(@"key", @"obj"); } - -void dictionaryLiteralKeyNilBad() { dictionaryLiteral(nil, @"obj"); } - -void dictionaryLiteralObjectNilBad() { dictionaryLiteral(@"key", nil); } - -void dictionaryWithObjectsForKeysCount(id key, id object) { - NSString* values[1]; - values[0] = object; - - NSString* keys[1]; - keys[0] = key; - - NSDictionary* dict = [NSDictionary dictionaryWithObjects:values - forKeys:keys - count:1]; -} - -void dictionaryWithObjectsForKeysCountOk() { - dictionaryWithObjectsForKeysCount(@"key", @"somestring"); -} - -void FN_dictionaryWithObjectsForKeysCountKeyNilBad() { - dictionaryWithObjectsForKeysCount(nil, @"somestring"); -} - -void FN_dictionaryWithObjectsForKeysCountObjectNilBad() { - dictionaryWithObjectsForKeysCount(@"key", nil); -} - -void dictionaryWithObjectForKey(id key, id object) { - NSDictionary* dict = [NSDictionary dictionaryWithObject:object forKey:key]; -} - -void dictionaryWithObjectForKeyOk() { - dictionaryWithObjectForKey(@"key", @"somestring"); -} - -void dictionaryWithObjectForKeyNilBad() { - dictionaryWithObjectForKey(nil, @"somestring"); -} - -void dictionaryWithNilObjectForKeyBad() { - dictionaryWithObjectForKey(@"key", nil); -} - -void dictionaryWithSharedKeySetForKeys(id keys) { - id sharedKeySet = [NSDictionary sharedKeySetForKeys:keys]; -} - -void dictionaryWithSharedKeySetForKeysOk() { - dictionaryWithSharedKeySetForKeys(@[ @"key1", @"key2" ]); -} - -void dictionaryWithSharedKeySetForKeysBad() { - dictionaryWithSharedKeySetForKeys(nil); -} - -void setWithObject(id object) { NSSet* set = [NSSet setWithObject:object]; } - -void setWithObjectOk() { setWithObject(@"obj"); } - -void setWithObjectBad() { setWithObject(nil); } - -void setByAddingObject(id object) { - NSSet* set = [NSSet set]; - set = [set setByAddingObject:object]; -} - -void setByAddingObjectOk() { setByAddingObject(@"obj"); } - -void setByAddingObjectBad() { setByAddingObject(nil); } - -void setWithObjectsForCount(id object) { - NSString* values[1]; - values[0] = object; - - NSSet* set = [NSSet setWithObjects:values count:1]; -} - -void setWithObjectsForCountOk() { setWithObjectsForCount(@"obj"); } - -void FN_setWithObjectsForCountBad() { setWithObjectsForCount(nil); } - -void setInitWithObjectsForCount(id object) { - NSString* values[1]; - values[0] = object; - - NSSet* set = [[NSSet alloc] initWithObjects:values count:1]; -} - -void setInitWithObjectsForCountOk() { setInitWithObjectsForCount(@"obj"); } - -void FN_setInitWithObjectsForCountBad() { setInitWithObjectsForCount(nil); } - -void arrayLiteral(id object) { NSArray* array = @[ object ]; } - -void arrayLiteralOk() { arrayLiteral(@"obj"); } - -void arrayLiteralNilBad() { arrayLiteral(nil); } - -void arrayWithObject(id object) { - NSArray* array = [NSArray arrayWithObject:object]; -} - -void arrayWithObjectOK() { arrayWithObject(@"obj"); } - -void arrayWithObjectNilBad() { arrayWithObject(nil); } - -void arrayWithObjects(id object) { - NSString* values[1]; - values[0] = object; - - NSArray* array = [NSArray arrayWithObjects:values count:1]; -} - -void arrayWithObjectsOk() { arrayWithObjects(@"obj"); } - -void FN_arrayWithObjectsNilBad() { arrayWithObjects(nil); } - std::shared_ptr unknown_call_twice_FP() { if (![SomeObject sharedInstance]) { return std::make_shared(0); diff --git a/infer/tests/codetoanalyze/objcpp/pulse/issues.exp b/infer/tests/codetoanalyze/objcpp/pulse/issues.exp index cc0b7b21a..fc60bc07e 100644 --- a/infer/tests/codetoanalyze/objcpp/pulse/issues.exp +++ b/infer/tests/codetoanalyze/objcpp/pulse/issues.exp @@ -1,34 +1,10 @@ codetoanalyze/objcpp/pulse/AllocPatternMemLeak.mm, A.create_no_release_leak_bad, 1, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by `ABFDataCreate` here,memory becomes unreachable here] codetoanalyze/objcpp/pulse/NPEBasic.mm, SomeObject.methodNilDereferenceBad, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, addNilInArrayBad, 0, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,in call to `NSMutableArray.addObject:` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, addNilInDictBad, 2, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,assigned,in call to `NSMutableDictionary.setObject:forKey:` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, addNilKeyInDictBracketsBad, 2, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,assigned,in call to `mutableDictionary[someKey] = value` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, addObjectInMSetBad, 0, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `addObjectInMSet` here,parameter `object` of addObjectInMSet,in call to `NSMutableSet.addObject:` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, addObjectKeyNilInDictBad, 2, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,in call to `NSMutableDictionary.setObject:forKey:` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, arrayLiteralNilBad, 0, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,when calling `arrayLiteral` here,parameter `object` of arrayLiteral,invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, arrayWithObjectNilBad, 0, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `arrayWithObject` here,parameter `object` of arrayWithObject,in call to `NSArray.arrayWithObject` (modelled),invalid access occurs here] codetoanalyze/objcpp/pulse/NPEBasic.mm, dereferenceNilBad, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, dictionaryLiteralKeyNilBad, 0, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,when calling `dictionaryLiteral` here,parameter `key` of dictionaryLiteral,invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, dictionaryLiteralObjectNilBad, 0, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,when calling `dictionaryLiteral` here,parameter `object` of dictionaryLiteral,invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, dictionaryWithNilObjectForKeyBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `dictionaryWithObjectForKey` here,parameter `object` of dictionaryWithObjectForKey,in call to `NSDictionary.dictionaryWithObject:forKey:` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, dictionaryWithObjectForKeyNilBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `dictionaryWithObjectForKey` here,parameter `key` of dictionaryWithObjectForKey,in call to `NSDictionary.dictionaryWithObject:forKey:` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, dictionaryWithSharedKeySetBad, 2, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,in call to `NSMutableDictionary.dictionaryWithSharedKeySet` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, dictionaryWithSharedKeySetForKeysBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `dictionaryWithSharedKeySetForKeys` here,parameter `keys` of dictionaryWithSharedKeySetForKeys,in call to `NSDictionary.sharedKeySetForKeys` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, insertNilInArrayBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,in call to `NSMutableArray.insertObject:atIndex:` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, removeObjectFromDictKeyNilBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `removeObjectFromDict` here,parameter `key` of removeObjectFromDict,in call to `NSMutableDictionary.removeObjectForKey` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, removeObjectFromMSetBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `removeObjectFromMSet` here,parameter `object` of removeObjectFromMSet,in call to `NSMutableSet.removeObject:` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, removeObjectsAtIndexesFromArrayBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `removeObjectsAtIndexesFromArray` here,parameter `indexset` of removeObjectsAtIndexesFromArray,in call to `NSMutableArray.removeObjectsAtIndexes:` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, replaceNilInArrayBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,in call to `NSMutableArray.replaceObjectAtIndex:withObject:` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, replaceObjectsAtIndexesWithNilObjectsInArrayBad, 2, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `replaceObjectsAtIndexesWithObjectsInArray` here,parameter `objects` of replaceObjectsAtIndexesWithObjectsInArray,in call to `NSMutableArray.replaceObjectsAtIndexes:withObjects:` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, replaceObjectsAtNilIndexesWithObjectsInArrayBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `replaceObjectsAtIndexesWithObjectsInArray` here,parameter `indexset` of replaceObjectsAtIndexesWithObjectsInArray,in call to `NSMutableArray.replaceObjectsAtIndexes:withObjects:` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, setByAddingObjectBad, 0, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `setByAddingObject` here,parameter `object` of setByAddingObject,in call to `NSSet.setByAddingObject` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, setWithObjectBad, 0, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `setWithObject` here,parameter `object` of setWithObject,in call to `NSSet.setWithObject` (modelled),invalid access occurs here] codetoanalyze/objcpp/pulse/NPEBasic.mm, testAccessPropertyAccessorBad, 2, NIL_MESSAGING_TO_NON_POD, no_bucket, ERROR, [calling context starts here,in call to `SomeObject.ptr`,null pointer dereference part of the trace starts here,is the null pointer,assigned,when calling `SomeObject.ptr` here,invalid access occurs here] codetoanalyze/objcpp/pulse/NPEBasic.mm, testCallMethodReturnsnonPODBad, 2, NIL_MESSAGING_TO_NON_POD, no_bucket, ERROR, [calling context starts here,in call to `SomeObject.returnsnonPOD`,null pointer dereference part of the trace starts here,is the null pointer,assigned,when calling `SomeObject.returnsnonPOD` here,invalid access occurs here] codetoanalyze/objcpp/pulse/NPEBasic.mm, testCallMethodReturnsnonPODLatent, 7, NIL_MESSAGING_TO_NON_POD, no_bucket, ERROR, [*** LATENT ***,calling context starts here,in call to `SomeObject.returnsnonPOD`,null pointer dereference part of the trace starts here,is the null pointer,assigned,when calling `SomeObject.returnsnonPOD` here,invalid access occurs here] codetoanalyze/objcpp/pulse/NPEBasic.mm, testCallMethodReturnsnonPODLatentBad, 1, NIL_MESSAGING_TO_NON_POD, no_bucket, ERROR, [calling context starts here,in call to `testCallMethodReturnsnonPODLatent`,in call to `SomeObject.returnsnonPOD`,null pointer dereference part of the trace starts here,is the null pointer,assigned,when calling `SomeObject.returnsnonPOD` here,invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, testNilMessagingForModelNilNilOK_FP, 0, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `addObjectInDict` here,parameter `value` of addObjectInDict,in call to `NSMutableDictionary.setObject:forKey:` (modelled),invalid access occurs here] -codetoanalyze/objcpp/pulse/NPEBasic.mm, testNilMessagingForModelNotNilDictBad, 1, NIL_INSERTION_INTO_COLLECTION, no_bucket, ERROR, [is the null pointer,when calling `addObjectInDict` here,parameter `value` of addObjectInDict,in call to `NSMutableDictionary.setObject:forKey:` (modelled),invalid access occurs here] codetoanalyze/objcpp/pulse/NPEBasic.mm, testNonPODTraceBad, 2, NIL_MESSAGING_TO_NON_POD, no_bucket, ERROR, [calling context starts here,in call to `SomeObject.returnsnonPOD`,null pointer dereference part of the trace starts here,in call to `SomeObject.returnsNil`,is the null pointer,returned,return from call to `SomeObject.returnsNil`,in call to `SomeObject.get`,parameter `self` of SomeObject.get,a message sent to nil returns nil,return from call to `SomeObject.get`,assigned,when calling `SomeObject.returnsnonPOD` here,invalid access occurs here] codetoanalyze/objcpp/pulse/NPEBasic.mm, testTraceBad, 3, NULLPTR_DEREFERENCE, no_bucket, ERROR, [is the null pointer,assigned,in call to `SomeObject.getXPtr`,parameter `self` of SomeObject.getXPtr,a message sent to nil returns nil,return from call to `SomeObject.getXPtr`,assigned,invalid access occurs here] codetoanalyze/objcpp/pulse/NPEBasic.mm, unknown_call_twice_FP, 4, NIL_MESSAGING_TO_NON_POD, no_bucket, ERROR, [calling context starts here,in call to `SomeObject.returnsnonPOD`,null pointer dereference part of the trace starts here,in call to `SomeObject.sharedInstance`,is the null pointer,assigned,returned,return from call to `SomeObject.sharedInstance`,when calling `SomeObject.returnsnonPOD` here,invalid access occurs here]