-
Notifications
You must be signed in to change notification settings - Fork 49
Prevent truncating log tag name #83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -179,7 +179,8 @@ impl AndroidLogger { | |
|
||
static ANDROID_LOGGER: OnceLock<AndroidLogger> = OnceLock::new(); | ||
|
||
const LOGGING_TAG_MAX_LEN: usize = 23; | ||
// Maximum length of a tag that does not require allocation. | ||
const LOGGING_TAG_MAX_LEN: usize = 127; | ||
const LOGGING_MSG_MAX_LEN: usize = 4000; | ||
|
||
impl Default for AndroidLogger { | ||
|
@@ -211,10 +212,10 @@ impl Log for AndroidLogger { | |
return; | ||
} | ||
|
||
// tag must not exceed LOGGING_TAG_MAX_LEN | ||
// tag longer than LOGGING_TAG_MAX_LEN causes allocation | ||
let mut tag_bytes: [MaybeUninit<u8>; LOGGING_TAG_MAX_LEN + 1] = uninit_array(); | ||
|
||
let module_path = record.module_path().unwrap_or_default().to_owned(); | ||
let module_path = record.module_path().unwrap_or_default(); | ||
|
||
// If no tag was specified, use module name | ||
let custom_tag = &config.tag; | ||
|
@@ -223,10 +224,23 @@ impl Log for AndroidLogger { | |
.map(|s| s.as_bytes()) | ||
.unwrap_or_else(|| module_path.as_bytes()); | ||
|
||
// truncate the tag here to fit into LOGGING_TAG_MAX_LEN | ||
self.fill_tag_bytes(&mut tag_bytes, tag); | ||
// use stack array as C string | ||
let tag: &CStr = unsafe { CStr::from_ptr(mem::transmute(tag_bytes.as_ptr())) }; | ||
// In case we end up allocating, keep the CString alive. | ||
let _owned_tag; | ||
let tag: &CStr = if tag.len() < tag_bytes.len() { | ||
// use stack array as C string | ||
self.fill_tag_bytes(&mut tag_bytes, tag); | ||
// SAFETY: fill_tag_bytes always puts a nullbyte in tag_bytes. | ||
unsafe { CStr::from_ptr(mem::transmute(tag_bytes.as_ptr())) } | ||
MarijnS95 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} else { | ||
// Tag longer than available stack buffer; allocate. | ||
// We're using either | ||
// - CString::as_bytes on config.tag, or | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, for Not sure if there's a clean way to handle that without making this very complex while dealing with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's an excellent observation! Please see the latest commit for an update that makes the happy-path of having a preconfigured tag not go through all this copy-to-buffer-and-then-reinterpret-as-cstr stuff. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whoops, I didn't notice PR got merged in the meantime - I'll follow up with a cleanup. |
||
// - str::as_bytes on record.module_path() | ||
// Neither of those include the terminating nullbyte. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TIL again 😅 Putting nullbytes in the module path sounds pretty evil though. I guess the current code does handle this case by doing a pointer transmute into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the Note that there is a builder API that trivially allows someone to set the |
||
_owned_tag = CString::new(tag) | ||
.expect("config.tag or record.module_path() should never contain nullbytes"); | ||
_owned_tag.as_ref() | ||
}; | ||
|
||
// message must not exceed LOGGING_MSG_MAX_LEN | ||
// therefore split log message into multiple log calls | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice opportunity for a doc-comment and a note regarding the NUL terminator being exempt from this limit?