Skip to content

Commit 034bb32

Browse files
authored
Handle null pointer. (#1141)
1 parent a9d660b commit 034bb32

File tree

1 file changed

+31
-11
lines changed

1 file changed

+31
-11
lines changed

data-pipeline-ffi/src/response.rs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
//! Define FFI compatible AgentResponse struct
55
66
use data_pipeline::trace_exporter::agent_response::AgentResponse;
7-
use std::ffi::{c_char, CString};
7+
use std::{
8+
ffi::{c_char, CString},
9+
ptr::null,
10+
};
811

912
/// Structure containing the agent response to a trace payload
1013
/// MUST be freed with `ddog_trace_exporter_response_free`
@@ -35,18 +38,22 @@ impl From<AgentResponse> for ExporterResponse {
3538
/// `response` is valid.
3639
#[no_mangle]
3740
pub unsafe extern "C" fn ddog_trace_exporter_response_get_body(
38-
response: &ExporterResponse,
41+
response: *const ExporterResponse,
3942
) -> *const c_char {
40-
response.body.as_ptr()
43+
if response.is_null() {
44+
null()
45+
} else {
46+
(*response).body.as_ptr()
47+
}
4148
}
4249

4350
/// Free `response` and all its contents. After being called response will not point to a valid
4451
/// memory address so any further actions on it could lead to undefined behavior.
4552
#[no_mangle]
46-
pub unsafe extern "C" fn ddog_trace_exporter_response_free(
47-
response: Option<Box<ExporterResponse>>,
48-
) {
49-
drop(response)
53+
pub unsafe extern "C" fn ddog_trace_exporter_response_free(response: *mut ExporterResponse) {
54+
if !response.is_null() {
55+
drop(Box::from_raw(response));
56+
}
5057
}
5158

5259
#[cfg(test)]
@@ -59,20 +66,33 @@ mod tests {
5966
let agent_response = AgentResponse::Changed {
6067
body: "res".to_string(),
6168
};
62-
let response = Box::new(ExporterResponse::from(agent_response));
69+
let response = &ExporterResponse::from(agent_response) as *const ExporterResponse;
6370
let body = unsafe {
64-
CStr::from_ptr(ddog_trace_exporter_response_get_body(&response)).to_string_lossy()
71+
CStr::from_ptr(ddog_trace_exporter_response_get_body(response)).to_string_lossy()
6572
};
6673
assert_eq!(body, "res".to_string());
6774
}
6875

6976
#[test]
7077
fn constructor_test_unchanged() {
7178
let agent_response = AgentResponse::Unchanged;
72-
let response = Box::new(ExporterResponse::from(agent_response));
79+
let response = Box::into_raw(Box::new(ExporterResponse::from(agent_response)));
7380
let body = unsafe {
74-
CStr::from_ptr(ddog_trace_exporter_response_get_body(&response)).to_string_lossy()
81+
CStr::from_ptr(ddog_trace_exporter_response_get_body(response)).to_string_lossy()
7582
};
7683
assert_eq!(body, "".to_string());
84+
unsafe {
85+
ddog_trace_exporter_response_free(response);
86+
}
87+
}
88+
89+
#[test]
90+
fn handle_null_test() {
91+
unsafe {
92+
let body = ddog_trace_exporter_response_get_body(null());
93+
assert!(body.is_null());
94+
95+
ddog_trace_exporter_response_free(null::<ExporterResponse>() as *mut ExporterResponse);
96+
}
7797
}
7898
}

0 commit comments

Comments
 (0)