Skip to content

Commit 0341944

Browse files
james7132mockersf
authored andcommitted
Fix unhandled null characters in Android logs (#12743)
# Objective Fix #12728. Fix unsoundnesss from unhandled null characters in Android logs. ## Solution Use `CString` instead of using formatted Strings. Properly document the safety invariants of the FFI call.
1 parent ba1aca3 commit 0341944

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

crates/bevy_log/src/android_tracing.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ use bevy_utils::tracing::{
33
span::{Attributes, Record},
44
Event, Id, Level, Subscriber,
55
};
6-
use std::fmt::{Debug, Write};
6+
use std::{
7+
ffi::CString,
8+
fmt::{Debug, Write},
9+
};
710
use tracing_subscriber::{field::Visit, layer::Context, registry::LookupSpan, Layer};
811

912
#[derive(Default)]
@@ -37,16 +40,6 @@ impl Visit for StringRecorder {
3740
}
3841
}
3942

40-
impl core::fmt::Display for StringRecorder {
41-
fn fmt(&self, mut f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
42-
if !self.0.is_empty() {
43-
write!(&mut f, " {}", self.0)
44-
} else {
45-
Ok(())
46-
}
47-
}
48-
}
49-
5043
impl core::default::Default for StringRecorder {
5144
fn default() -> Self {
5245
StringRecorder::new()
@@ -74,24 +67,33 @@ impl<S: Subscriber + for<'a> LookupSpan<'a>> Layer<S> for AndroidLayer {
7467
}
7568

7669
fn on_event(&self, event: &Event<'_>, _ctx: Context<'_, S>) {
70+
fn sanitize(string: &str) -> CString {
71+
let mut bytes: Vec<u8> = string
72+
.as_bytes()
73+
.into_iter()
74+
.copied()
75+
.filter(|byte| *byte != 0)
76+
.collect();
77+
CString::new(bytes).unwrap()
78+
}
79+
7780
let mut recorder = StringRecorder::new();
7881
event.record(&mut recorder);
7982
let meta = event.metadata();
80-
let level = meta.level();
81-
let priority = match *level {
83+
let priority = match *meta.level() {
8284
Level::TRACE => android_log_sys::LogPriority::VERBOSE,
8385
Level::DEBUG => android_log_sys::LogPriority::DEBUG,
8486
Level::INFO => android_log_sys::LogPriority::INFO,
8587
Level::WARN => android_log_sys::LogPriority::WARN,
8688
Level::ERROR => android_log_sys::LogPriority::ERROR,
8789
};
88-
let message = format!("{}\0", recorder);
89-
let tag = format!("{}\0", meta.name());
90+
// SAFETY: Called only on Android platforms. priority is guaranteed to be in range of c_int.
91+
// The provided tag and message are null terminated properly.
9092
unsafe {
9193
android_log_sys::__android_log_write(
9294
priority as android_log_sys::c_int,
93-
tag.as_ptr() as *const android_log_sys::c_char,
94-
message.as_ptr() as *const android_log_sys::c_char,
95+
sanitize(meta.name()).as_ptr(),
96+
sanitize(&recorder.0).as_ptr(),
9597
);
9698
}
9799
}

0 commit comments

Comments
 (0)