From 56fe82a6797ba306906b4252347c7ef6849f33f0 Mon Sep 17 00:00:00 2001 From: "Simeon H.K. Fitch" Date: Mon, 22 Jun 2026 10:42:14 -0400 Subject: [PATCH] Fixed missing null terminator in config string used in `Booster::save_buffer`. --- src/booster.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/booster.rs b/src/booster.rs index e439f65..4f3b9b0 100644 --- a/src/booster.rs +++ b/src/booster.rs @@ -130,12 +130,16 @@ impl Booster { /// Format is "ubj" when binary, otherwise "json" pub fn save_buffer(&self, binary: bool) -> XGBResult> { trace!("Writing Booster to buffer"); - let config = format!("{{\"format\":\"{}\"}}", if binary { "ubj" } else { "json" }); + // Must be NUL-terminated: XGBoost treats this as a C string and calls + // strlen on it. Passing a bare Rust String's bytes (no trailing NUL) + // makes XGBoost read past the end of the allocation. + let config = ffi::CString::new(format!("{{\"format\":\"{}\"}}", if binary { "ubj" } else { "json" })) + .map_err(|e| XGBError::new(e.to_string()))?; let mut out_len: xgboost_sys::bst_ulong = 0; let mut out_buffer = ptr::null(); xgb_call!(xgboost_sys::XGBoosterSaveModelToBuffer( self.handle, - config.as_bytes().as_ptr() as *const raw::c_char, + config.as_ptr() as *const raw::c_char, &mut out_len, &mut out_buffer ))?;