-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[nstring-internal-ptr] Adding a new issue type NSSTRING_INTERNAL_PTR_…
…CAPTURED_IN_BLOCK Summary: The issue is that when the result of a call to the method `cStringUsingEncoding` of `NSString` or its property `UTF8String` is captured in an escaping block without copying it first, this can cause a crash. We adapt the checker for finding CXX String Captured In Block to deal with this case too as both cases are very similar. First, we add the context info to the captured variables in the preanalysis, and then flag it in the checker. Reviewed By: geralt-encore Differential Revision: D65070300 fbshipit-source-id: 87dde7d90e8e22f69ad23afe78cdea90c50f5c23
- Loading branch information
1 parent
324d444
commit 7f85732
Showing
10 changed files
with
169 additions
and
65 deletions.
There are no files selected for viewing
23 changes: 23 additions & 0 deletions
23
infer/documentation/issues/NSSTRING_INTERNAL_PTR_CAPTURED_IN_BLOCK.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
This check flags when the result of a call to the method `cStringUsingEncoding` of `NSString` or its property `UTF8String` | ||
is captured in an escaping block. In both cases this C string is a pointer to a structure inside the string object, which | ||
may have a lifetime shorter than the string object and will certainly not have a longer lifetime. Therefore, you should copy | ||
the C string if it needs to be stored outside of the memory context in which you use it. | ||
|
||
Example: | ||
|
||
``` | ||
char* encoding = (char*)[name cStringUsingEncoding:NSUTF8StringEncoding]; | ||
dispatch_async(dispatch_get_main_queue(), ^{ | ||
const char* c = encoding; //bug | ||
}); | ||
char* utf8string = name.UTF8String; | ||
dispatch_async(dispatch_get_main_queue(), ^{ | ||
const char* c = utf8string; //bug | ||
}); | ||
``` | ||
|
||
This could cause crashes because the variable is likely to be freed when the code is executed, leaving the pointer dangling. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
infer/tests/codetoanalyze/objc/self-in-block/CStringUsingEncodingTest.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* 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. | ||
*/ | ||
|
||
#include <Foundation/Foundation.h> | ||
|
||
@interface CStringUsingEncodingTest : NSObject | ||
|
||
@end | ||
|
||
@implementation CStringUsingEncodingTest | ||
|
||
- (void)cStringUsingEncoding_no_copy_bad:(NSString*)name { | ||
char* encoding = (char*)[name cStringUsingEncoding:NSUTF8StringEncoding]; | ||
dispatch_async(dispatch_get_main_queue(), ^{ | ||
const char* c = encoding; | ||
}); | ||
} | ||
|
||
- (void)cStringUsingEncoding_copy_good:(NSString*)name { | ||
char* encoding = (char*)[name cStringUsingEncoding:NSUTF8StringEncoding]; | ||
char* encoding_copy = ""; | ||
strcpy(encoding_copy, encoding); | ||
dispatch_async(dispatch_get_main_queue(), ^{ | ||
const char* c = encoding_copy; | ||
}); | ||
} | ||
|
||
- (void)UTF8String_no_copy_bad:(NSString*)name { | ||
char* utf8string = name.UTF8String; | ||
dispatch_async(dispatch_get_main_queue(), ^{ | ||
const char* c = utf8string; | ||
}); | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters