Model init method in NSData and understand the field bytes

Reviewed By: sblackshear

Differential Revision: D3627970

fbshipit-source-id: f70d913
master
Dulma Churchill 9 years ago committed by Facebook Github Bot 6
parent 4490d9b033
commit ff597a6c03

@ -40,6 +40,13 @@ NSData* __objc_alloc(NSData*);
return nil;
}
- (instancetype)initWithBytesNoCopy:(void*)bytes
length:(NSUInteger)length
freeWhenDone:(BOOL)flag {
self->_bytes = bytes;
return self;
}
- (void)dealloc {
if (self)
free(self->_bytes);

@ -92,3 +92,15 @@ let add_missing_fields tenv class_name ck fields =
Printing.log_out " Updating info for class '%s' in tenv\n" class_name;
Tenv.add tenv class_tn_name class_type_info
| _ -> ()
let modelled_fields_in_classes = [("NSData", "_bytes", Typ.Tptr (Typ.Tvoid, Typ.Pk_pointer))]
let modelled_field class_name_info =
let modelled_field_in_class res (class_name, field_name, typ) =
if class_name = class_name_info.Clang_ast_t.ni_name then
let class_name_qualified = class_name_info.Clang_ast_t.ni_qual_name in
let field_name_qualified = Ast_utils.make_qual_name_decl class_name_qualified field_name in
let name = General_utils.mk_class_field_name field_name_qualified in
(name, typ, Typ.item_annotation_empty) :: res
else res in
IList.fold_left modelled_field_in_class [] modelled_fields_in_classes

@ -24,3 +24,5 @@ val build_sil_field : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.na
Clang_ast_t.type_ptr -> Clang_ast_t.property_attribute list -> field_type
val add_missing_fields : Tenv.t -> string -> Csu.class_kind -> field_type list -> unit
val modelled_field : Clang_ast_t.named_decl_info -> field_type list

@ -98,7 +98,8 @@ let create_superclasses_fields type_ptr_to_sil_type tenv curr_class decl_list
superclasses, fields
(* Adds pairs (interface name, interface_type_info) to the global environment. *)
let add_class_to_tenv type_ptr_to_sil_type tenv curr_class decl_info class_name decl_list ocidi =
let add_class_to_tenv type_ptr_to_sil_type tenv curr_class decl_info name_info decl_list ocidi =
let class_name = Ast_utils.get_qualified_name name_info in
Printing.log_out "ADDING: ObjCInterfaceDecl for '%s'\n" class_name;
let interface_name = CTypes.mk_classname class_name Csu.Objc in
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in
@ -122,13 +123,14 @@ let add_class_to_tenv type_ptr_to_sil_type tenv curr_class decl_info class_name
| _ -> fields, superclasses, methods in
let fields = General_utils.append_no_duplicates_fields fields fields_sc in
(* We add the special hidden counter_field for implementing reference counting *)
let fields = General_utils.append_no_duplicates_fields [Typ.objc_ref_counter_field] fields in
let modelled_fields = Typ.objc_ref_counter_field :: CField_decl.modelled_field name_info in
let all_fields = General_utils.append_no_duplicates_fields modelled_fields fields in
Printing.log_out "Class %s field:\n" class_name;
IList.iter (fun (fn, _, _) ->
Printing.log_out "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) fields;
Printing.log_out "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) all_fields;
let interface_type_info =
{
Typ.instance_fields = fields;
Typ.instance_fields = all_fields;
static_fields = [];
csu = Csu.Class Csu.Objc;
struct_name = Some (Mangled.from_string class_name);
@ -170,8 +172,8 @@ let interface_declaration type_ptr_to_sil_type tenv decl =
| ObjCInterfaceDecl (decl_info, name_info, decl_list, _, ocidi) ->
let name = Ast_utils.get_qualified_name name_info in
let curr_class = get_curr_class name ocidi in
let typ =
add_class_to_tenv type_ptr_to_sil_type tenv curr_class decl_info name decl_list ocidi in
let typ = add_class_to_tenv type_ptr_to_sil_type tenv curr_class decl_info name_info
decl_list ocidi in
let _ = add_class_implementation type_ptr_to_sil_type tenv ocidi in
let _ = add_super_class_decl type_ptr_to_sil_type tenv ocidi in
let _ = add_protocols_decl type_ptr_to_sil_type tenv ocidi.Clang_ast_t.otdi_protocols in

@ -16,17 +16,18 @@
@implementation A
NSString* FBCreateURLQueryStringBodyEscaping(NSDictionary* parameters,
NSString* s) {
NSString* createURLQueryStringBodyEscaping(NSDictionary* parameters,
NSString* s) {
NSString* resultString;
if (s) {
char* resultBuffer = (char*)malloc(5 * sizeof(char));
NSString* resultString = [s initWithBytesNoCopy:resultBuffer
length:5
encoding:NSUTF8StringEncoding
freeWhenDone:YES];
resultString = [s initWithBytesNoCopy:resultBuffer
length:5
encoding:NSUTF8StringEncoding
freeWhenDone:YES];
}
return s;
return resultString;
}
+ (NSData*)randomBytes:(NSUInteger)numOfBytes {
@ -40,6 +41,15 @@ NSString* FBCreateURLQueryStringBodyEscaping(NSDictionary* parameters,
}
}
- (NSData*)readDataOfLength:(NSUInteger)length {
size_t bytesLength = length;
void* bytes = malloc(bytesLength);
if (bytes == NULL) {
return nil;
}
return [[NSData alloc] initWithBytesNoCopy:bytes length:5 freeWhenDone:YES];
}
- (NSData*)macForIV:(NSData*)IV {
uint8_t* result = malloc(10);
return [NSData dataWithBytesNoCopy:result length:10];

@ -10,8 +10,7 @@
package endtoend.objc.infer;
import static org.hamcrest.MatcherAssert.assertThat;
import static utils.matchers.ResultContainsErrorInMethod.contains;
import static utils.matchers.ResultContainsNoErrorInMethod.doesNotContain;
import static utils.matchers.ResultContainsExactly.containsExactly;
import com.google.common.collect.ImmutableList;
@ -50,57 +49,18 @@ public class MemoryLeaksFromModelsTest {
}
@Test
public void whenInferRunsOnFBCreateURLQueryStringBodyEscapingThenMLIsNotFound()
throws InterruptedException, IOException, InferException {
InferResults inferResults = InferRunner.runInferObjC(inferCmd);
assertThat(
"Results should not contain memory leak",
inferResults,
doesNotContain(
MEMORY_LEAK,
memory_leak_file,
"FBCreateURLQueryStringBodyEscaping"));
}
@Test
public void whenInferRunsOnRandomBytesThenMLIsNotFound()
throws InterruptedException, IOException, InferException {
InferResults inferResults = InferRunner.runInferObjC(inferCmd);
assertThat(
"Results should not contain memory leak",
inferResults,
doesNotContain(
MEMORY_LEAK,
memory_leak_file,
"randomBytes:"));
}
@Test
public void whenInferRunsOn_macForIVThenMLIsFound()
throws InterruptedException, IOException, InferException {
InferResults inferResults = InferRunner.runInferObjC(inferCmd);
assertThat(
"Results should contain memory leak",
inferResults,
contains(
MEMORY_LEAK,
memory_leak_file,
"macForIV:"
)
);
}
@Test
public void whenInferRunsOnHexStringValueThenMLIsNotFound()
throws InterruptedException, IOException, InferException {
InferResults inferResults = InferRunner.runInferObjC(inferCmd);
assertThat(
"Results should not contain memory leak",
inferResults,
doesNotContain(
MEMORY_LEAK,
memory_leak_file,
"hexStringValue"));
}
public void matchErrors()
throws InterruptedException, IOException, InferException {
InferResults inferResults = InferRunner.runInferObjC(inferCmd);
String[] procedures = {"macForIV:"};
assertThat(
"Results should contain the expected memory leak",
inferResults,
containsExactly(
MEMORY_LEAK,
memory_leak_file,
procedures
)
);
}
}

Loading…
Cancel
Save