@@ -179,7 +179,8 @@ impl AndroidLogger {
179
179
180
180
static ANDROID_LOGGER : OnceLock < AndroidLogger > = OnceLock :: new ( ) ;
181
181
182
- const LOGGING_TAG_MAX_LEN : usize = 23 ;
182
+ // Maximum length of a tag that does not require allocation.
183
+ const LOGGING_TAG_MAX_LEN : usize = 127 ;
183
184
const LOGGING_MSG_MAX_LEN : usize = 4000 ;
184
185
185
186
impl Default for AndroidLogger {
@@ -211,10 +212,10 @@ impl Log for AndroidLogger {
211
212
return ;
212
213
}
213
214
214
- // tag must not exceed LOGGING_TAG_MAX_LEN
215
+ // tag longer than LOGGING_TAG_MAX_LEN causes allocation
215
216
let mut tag_bytes: [ MaybeUninit < u8 > ; LOGGING_TAG_MAX_LEN + 1 ] = uninit_array ( ) ;
216
217
217
- let module_path = record. module_path ( ) . unwrap_or_default ( ) . to_owned ( ) ;
218
+ let module_path = record. module_path ( ) . unwrap_or_default ( ) ;
218
219
219
220
// If no tag was specified, use module name
220
221
let custom_tag = & config. tag ;
@@ -223,10 +224,23 @@ impl Log for AndroidLogger {
223
224
. map ( |s| s. as_bytes ( ) )
224
225
. unwrap_or_else ( || module_path. as_bytes ( ) ) ;
225
226
226
- // truncate the tag here to fit into LOGGING_TAG_MAX_LEN
227
- self . fill_tag_bytes ( & mut tag_bytes, tag) ;
228
- // use stack array as C string
229
- let tag: & CStr = unsafe { CStr :: from_ptr ( mem:: transmute ( tag_bytes. as_ptr ( ) ) ) } ;
227
+ // In case we end up allocating, keep the CString alive.
228
+ let _owned_tag;
229
+ let tag: & CStr = if tag. len ( ) < tag_bytes. len ( ) {
230
+ // use stack array as C string
231
+ self . fill_tag_bytes ( & mut tag_bytes, tag) ;
232
+ // SAFETY: fill_tag_bytes always puts a nullbyte in tag_bytes.
233
+ unsafe { CStr :: from_ptr ( mem:: transmute ( tag_bytes. as_ptr ( ) ) ) }
234
+ } else {
235
+ // Tag longer than available stack buffer; allocate.
236
+ // We're using either
237
+ // - CString::as_bytes on config.tag, or
238
+ // - str::as_bytes on record.module_path()
239
+ // Neither of those include the terminating nullbyte.
240
+ _owned_tag = CString :: new ( tag)
241
+ . expect ( "config.tag or record.module_path() should never contain nullbytes" ) ;
242
+ _owned_tag. as_ref ( )
243
+ } ;
230
244
231
245
// message must not exceed LOGGING_MSG_MAX_LEN
232
246
// therefore split log message into multiple log calls
0 commit comments