You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.5 KiB

Infer reports null dereference bugs in Java, C, C++, and Objective-C
when it is possible that the null pointer is dereferenced, leading to
a crash.
### Null dereference in Java
Many of Infer's reports of potential Null Pointer Exceptions (NPE) come from code of the form
```java
p = foo(); // foo() might return null
stuff();
p.goo(); // dereferencing p, potential NPE
```
If you see code of this form, then you have several options.
**If you are unsure whether or not `foo()` will return null**, you should
ideally either
1. Change the code to ensure that `foo()` can not return null, or
2. Add a check that `p` is not `null` before dereferencing `p`.
Sometimes, in case (2) it is not obvious what you should do when `p`
is `null`. One possibility is to throw an exception, failing early but
explicitly. This can be done using `checkNotNull` as in the following
code:
```java
// code idiom for failing early
import static com.google.common.base.Preconditions.checkNotNull;
//... intervening code
p = checkNotNull(foo()); // foo() might return null
stuff();
p.goo(); // p cannot be null here
```
The call `checkNotNull(foo())` will never return `null`: if `foo()`
returns `null` then it fails early by throwing a Null Pointer
Exception.
Facebook NOTE: **If you are absolutely sure that foo() will not be
null**, then if you land your diff this case will no longer be
reported after your diff makes it to master.
### Null dereference in C
Here is an example of an inter-procedural null dereference bug in C:
```c
struct Person {
int age;
int height;
int weight;
};
int get_age(struct Person *who) {
return who->age;
}
int null_pointer_interproc() {
struct Person *joe = 0;
return get_age(joe);
}
```
### Null dereference in Objective-C
In Objective-C, null dereferences are less common than in Java, but they still
happen and their cause can be hidden. In general, passing a message to nil does
not cause a crash and returns `nil`, but dereferencing a pointer directly does
cause a crash as well as calling a `nil` block.
```objectivec
-(void) foo:(void (^)())callback {
callback();
}
-(void) bar {
[self foo:nil]; //crash
}
```
Moreover, there are functions from the libraries that do not allow `nil` to be
passed as argument. Here are some examples:
```objectivec
-(void) foo {
NSString *str = nil;
NSArray *animals = @[@"horse", str, @"dolphin"]; //crash
}
-(void) bar {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); //can return NULL
...
CFRelease(colorSpace); //crashes if called with NULL
}
```