summaryrefslogtreecommitdiff
path: root/rust/tests/type_container.rs
blob: ab4cbb0b00be5211bcc7a0bd197907103ee5879c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use binaryninja::binary_view::BinaryView;
use binaryninja::file_metadata::FileMetadata;
use binaryninja::headless::Session;
use binaryninja::platform::Platform;
use binaryninja::types::Type;

#[test]
fn test_types() {
    let _session = Session::new().expect("Failed to initialize session");
    let platform = Platform::by_name("windows-x86_64").expect("windows-x86_64 exists");
    let type_container = platform.type_container();
    let types = type_container.types().unwrap();
    // windows-x86_64 has a few thousand, not zero.
    assert_eq!(types.len(), platform.types().len());
}

#[test]
fn test_type_id() {
    let _session = Session::new().expect("Failed to initialize session");
    let platform = Platform::by_name("windows-x86_64").expect("windows-x86_64 exists");
    let type_container = platform.type_container();
    let type_ids = type_container.type_ids().unwrap();
    let first_type_id = type_ids.iter().next().unwrap();
    let found_type = type_container
        .type_by_id(first_type_id)
        .expect("Type ID not valid!");
    let found_type_name = type_container
        .type_name(first_type_id)
        .expect("Type name not found for Type ID");
    let found_type_for_type_name = type_container
        .type_by_name(found_type_name)
        .expect("Found type name not valid!");
    // These _should_ be the same type.
    assert_eq!(found_type, found_type_for_type_name);
}

#[test]
fn test_add_delete_type() {
    let _session = Session::new().expect("Failed to initialize session");
    let empty_view = BinaryView::from_data(&FileMetadata::new(), &[]);
    let view_type_container = empty_view.type_container();
    let test_type = Type::int(4, true);
    assert!(
        view_type_container.add_types([("mytype", test_type)]),
        "Failed to add types!"
    );
    let my_type_id = view_type_container
        .type_id("mytype")
        .expect("mytype not found");
    assert!(
        view_type_container.delete_type(&my_type_id),
        "Type was deleted!"
    );
    // There should be no type ids if the type was actually deleted
    assert_eq!(view_type_container.type_ids().unwrap().len(), 0)
}

#[test]
fn test_immutable_container() {
    let _session = Session::new().expect("Failed to initialize session");
    let platform = Platform::by_name("windows-x86_64").expect("windows-x86_64 exists");
    // Platform type containers are immutable, so we shouldn't be able to delete/add/rename types.
    let plat_type_container = platform.type_container();
    assert!(
        !plat_type_container.is_mutable(),
        "Platform should NOT be mutable!"
    );
    assert_ne!(
        platform.types().len(),
        0,
        "Something deleted all the platform types!"
    );
    let type_ids = plat_type_container.type_ids().unwrap();
    let first_type_id = type_ids.iter().next().unwrap();
    // Platform type containers are immutable so these should be false!
    assert!(
        !plat_type_container.delete_type(first_type_id),
        "Type was deleted!"
    );
    assert!(
        !plat_type_container.add_types([("new_type", Type::int(4, true))]),
        "Type was added!"
    );
    assert!(
        !plat_type_container.rename_type(first_type_id, "renamed_type"),
        "Type was renamed!"
    );
}

#[test]
fn test_parse_type() {
    let _session = Session::new().expect("Failed to initialize session");
    let platform = Platform::by_name("windows-x86_64").expect("windows-x86_64 exists");
    let type_container = platform.type_container();
    // HANDLE will be pulled in from the platform, which is `windows-x86_64`.
    let parsed_type = type_container
        .parse_type_string("typedef HANDLE test;", false)
        .map_err(|e| e.to_vec())
        .expect("Failed to parse type");
    assert_eq!(parsed_type.name, "test".into());
    assert_eq!(parsed_type.ty.to_string(), "HANDLE");
}

#[test]
fn test_container_lifetime() {
    let _session = Session::new().expect("Failed to initialize session");
    let platform = Platform::by_name("windows-x86_64").expect("windows-x86_64 exists");
    let empty_view = BinaryView::from_data(&FileMetadata::new(), &[]);
    let plat_type_container_dropped = platform.type_container();
    let view_type_container_dropped = empty_view.type_container();
    let _plat_types_dropped = plat_type_container_dropped.types();
    let _view_types_dropped = view_type_container_dropped.types();
    drop(plat_type_container_dropped);
    drop(view_type_container_dropped);
    let plat_type_container_0 = platform.type_container();
    let view_type_container_0 = empty_view.type_container();
    let test_type = Type::int(4, true);
    view_type_container_0.add_types([("mytype", test_type)]);
    let plat_types_0 = plat_type_container_0.types();
    let view_types_0 = view_type_container_0.types();
    let plat_type_container_1 = platform.type_container();
    let view_type_container_1 = empty_view.type_container();
    let plat_types_1 = plat_type_container_1.types();
    let view_types_1 = view_type_container_1.types();
    // If the types do not equal the container is being freed from the first set of calls.
    assert_eq!(plat_types_0, plat_types_1);
    assert_eq!(view_types_0, view_types_1);
}