Skip to content

Commit f824acd

Browse files
dulmarodfacebook-github-bot
authored andcommitted
[tests] [23/n] Copy NPE test about dynamic dispatch in ObjC to Pulse
Summary: We copy a test over from biabduction to Pulse that shows that we can miss null dereferences because of not handling dynamic dispatch of ObjC classes. (This is implemented only in biabduction). Reviewed By: jvillard Differential Revision: D32359531 fbshipit-source-id: bc2ec10cd
1 parent 992fd2a commit f824acd

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

infer/tests/codetoanalyze/objc/pulse/issues.exp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ codetoanalyze/objc/pulse/null_deref/NPENilBlocks.m, BlockA.paramAssignNilBad:, 3
4444
codetoanalyze/objc/pulse/null_deref/NPENilBlocks.m, BlockA.paramReassignNilBad:, 6, NIL_BLOCK_CALL, no_bucket, ERROR, [is the null pointer,assigned,assigned,invalid access occurs here]
4545
codetoanalyze/objc/pulse/null_deref/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]
4646
codetoanalyze/objc/pulse/null_deref/NPENilBlocks.m, nilBlockCallCFuntionBad, 4, NIL_BLOCK_CALL, no_bucket, ERROR, [is the null pointer,assigned,invalid access occurs here]
47+
codetoanalyze/objc/pulse/null_deref/dynamic_dispatch.m, DynamicDispatchMain.no_dynamic_dispatch_npe_bad, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [in call to `DynamicDispatchMain.get_ddclass_from_instance:`,in call to `PInstance.get_ddclass`,is the null pointer,returned,return from call to `PInstance.get_ddclass`,returned,return from call to `DynamicDispatchMain.get_ddclass_from_instance:`,invalid access occurs here]
4748
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]
4849
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]
4950
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]
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
#import <Foundation/Foundation.h>
8+
9+
@interface DynamicDispatchClass : NSObject
10+
@end
11+
12+
@implementation DynamicDispatchClass {
13+
@public
14+
int x;
15+
}
16+
17+
@end
18+
19+
@protocol P
20+
21+
- (DynamicDispatchClass*)get_ddclass;
22+
23+
@end
24+
25+
@interface PInstance : NSObject<P>
26+
27+
@end
28+
29+
@implementation PInstance
30+
31+
- (DynamicDispatchClass*)get_ddclass {
32+
return nil;
33+
}
34+
35+
@end
36+
37+
@interface DynamicDispatchMain : NSObject
38+
39+
@end
40+
41+
@implementation DynamicDispatchMain
42+
43+
- (DynamicDispatchClass*)get_ddclass_from:(id<P>)object {
44+
return [object get_ddclass];
45+
}
46+
47+
// Pulse doesn't find the null deref in this example because it doesn't handle
48+
// dynamic dispatch
49+
- (int)dynamic_dispatch_npe_bad_FN {
50+
PInstance* object = [PInstance new];
51+
return [self get_ddclass_from:object]->x;
52+
}
53+
54+
- (DynamicDispatchClass*)get_ddclass_from_instance:(PInstance*)object {
55+
return [object get_ddclass];
56+
}
57+
58+
- (int)no_dynamic_dispatch_npe_bad {
59+
PInstance* object = [PInstance new];
60+
return [self get_ddclass_from_instance:object]->x;
61+
}
62+
63+
@end

0 commit comments

Comments
 (0)