diff --git a/infer/src/pulse/PulseModels.ml b/infer/src/pulse/PulseModels.ml index 864eb68e8..bbca6645f 100644 --- a/infer/src/pulse/PulseModels.ml +++ b/infer/src/pulse/PulseModels.ml @@ -1804,6 +1804,9 @@ module ProcNameDispatcher = struct ; +map_context_tenv (PatternMatch.ObjectiveC.implements "NSSet") &:: "setByAddingObject:" <>$ any_arg $+ capt_arg_payload $--> ObjC.insertion_into_collection_key_or_value ~desc:"NSSet.setByAddingObject" + ; +map_context_tenv (PatternMatch.ObjectiveC.implements "NSArray") + &:: "arrayWithObject:" <>$ capt_arg_payload + $--> ObjC.insertion_into_collection_key_or_value ~desc:"NSArray.arrayWithObject" ; +match_regexp_opt Config.pulse_model_return_nonnull &::.*--> Misc.return_positive ~desc:"modelled as returning not null due to configuration option" diff --git a/infer/tests/codetoanalyze/objcpp/pulse/NPEBasic.mm b/infer/tests/codetoanalyze/objcpp/pulse/NPEBasic.mm index 74856339d..3a351a7ed 100644 --- a/infer/tests/codetoanalyze/objcpp/pulse/NPEBasic.mm +++ b/infer/tests/codetoanalyze/objcpp/pulse/NPEBasic.mm @@ -426,3 +426,28 @@ void setInitWithObjectsForCount(id object) { 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/objcpp/pulse/issues.exp b/infer/tests/codetoanalyze/objcpp/pulse/issues.exp index b86987b3c..04e08c164 100644 --- a/infer/tests/codetoanalyze/objcpp/pulse/issues.exp +++ b/infer/tests/codetoanalyze/objcpp/pulse/issues.exp @@ -5,6 +5,8 @@ codetoanalyze/objcpp/pulse/NPEBasic.mm, addNilInDictBad, 2, NIL_INSERTION_INTO_C 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]