{"record":{"id":"37ece03901cb7f37","repo":"PyO3/pyo3","slug":"string-contains-nul-bytes","errorCode":null,"errorMessage":"string contains nul bytes","messagePattern":"string contains nul bytes","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pyo3-ffi/src/lib.rs","lineNumber":428,"sourceCode":"/// use core::ffi::CStr;\n///\n/// const HELLO: &CStr = pyo3_ffi::c_str!(\"hello\");\n/// static WORLD: &CStr = pyo3_ffi::c_str!(\"world\");\n/// ```\n#[macro_export]\nmacro_rules! c_str {\n    // TODO: deprecate this now MSRV is above 1.77\n    ($s:expr) => {\n        $crate::_cstr_from_utf8_with_nul_checked(concat!($s, \"\\0\"))\n    };\n}\n\n/// Private helper for `c_str!` macro.\n#[doc(hidden)]\npub const fn _cstr_from_utf8_with_nul_checked(s: &str) -> &core::ffi::CStr {\n    match core::ffi::CStr::from_bytes_with_nul(s.as_bytes()) {\n        Ok(cstr) => cstr,\n        Err(_) => panic!(\"string contains nul bytes\"),\n    }\n}\n\n// Macros for declaring `extern` blocks that link against libpython.\n#[path = \"impl_/macros.rs\"]\n#[macro_use]\nmod macros;\n\npub mod compat;\nmod impl_;\n\npub use self::abstract_::*;\n#[cfg(not(RustPython))]\npub use self::bltinmodule::*;\npub use self::boolobject::*;\npub use self::bytearrayobject::*;\npub use self::bytesobject::*;\npub use self::ceval::*;","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/PyO3/pyo3/blob/ac9b6899d348be4d54614d060dea53a645a12e36/pyo3-ffi/src/lib.rs#L410-L446","documentation":"The hidden const helper _cstr_from_utf8_with_nul_checked builds a CStr from a &str at compile time via c_str!. CStr::from_bytes_with_nul fails if the input has interior NUL bytes or doesn't end in exactly one NUL, and const fns can only panic, so it panics with \"string contains nul bytes\".","triggerScenarios":"Using the c_str! macro (or calling _cstr_from_utf8_with_nul_checked) with a string literal containing an interior \\0 or not properly NUL-terminated by the macro.","commonSituations":"Programmatically generated literals that embed embedded NULs; typos like \"foo\\0bar\" intended as a C identifier; macro misuse with already-escaped strings.","solutions":["Remove interior NUL bytes from the string literal","Use a single trailing \\0 only (which the macro expects)","Use std::ffi::CStr::from_bytes_with_nul manually with error handling for runtime strings"],"exampleFix":"// before\nlet s = c_str!(\"foo\\0bar\\0\");\n// after\nlet s = c_str!(\"foobar\\0\");","handlingStrategy":"validation","validationCode":"fn is_cstr_safe(s: &str) -> bool {\n    s.as_bytes().iter().filter(|&&b| b == 0).count() == 1 && s.ends_with('\\0')\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never embed interior NUL bytes in string literals passed to c_str!","Let the macro add the trailing NUL; don't double-terminate","Prefer CStr::from_bytes_with_nul with match for runtime strings"],"tags":["ffi","cstr","nul-byte","const-panic","compile-time"],"backgroundTag":"interior-nul-byte","analyzedSha":"ac9b6899d348be4d54614d060dea53a645a12e36","analyzedAt":"2026-09-05T09:20:35.319Z","contentChangedAt":"2026-09-05T09:20:35.319Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}