{"record":{"id":"972d16b35a755d48","repo":"nautechsystems/nautilus_trader","slug":"json-string-contains-interior-null-bytes","errorCode":null,"errorMessage":"JSON string contains interior null bytes","messagePattern":"JSON string contains interior null bytes","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/core/src/ffi/parsing.rs","lineNumber":85,"sourceCode":"    arr.iter()\n        .map(|value| {\n            value\n                .as_str()\n                .expect(\"C string JSON array must contain only strings\")\n                .to_owned()\n        })\n        .collect()\n}\n\n/// Convert a slice of `String` into a C string pointer (JSON encoded).\n///\n/// # Panics\n///\n/// Panics if JSON serialization fails or if the generated string contains interior null bytes.\n#[must_use]\npub fn string_vec_to_bytes(strings: &[String]) -> *const c_char {\n    let json_string = serde_json::to_string(strings).expect(\"Failed to serialize strings to JSON\");\n    let c_string = CString::new(json_string).expect(\"JSON string contains interior null bytes\");\n\n    c_string.into_raw()\n}\n\n/// Convert a C bytes pointer into an owned `Option<HashMap<String, Value>>`.\n///\n/// # Safety\n///\n/// Assumes `ptr` is a valid C string pointer.\n///\n/// # Panics\n///\n/// Panics if `ptr` is not null but contains invalid UTF-8 or JSON.\n#[must_use]\npub unsafe fn optional_bytes_to_json(ptr: *const c_char) -> Option<HashMap<String, Value>> {\n    // SAFETY: A non-null pointer is valid under the caller's contract\n    unsafe { optional_json_from_cstr(ptr) }\n}","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/core/src/ffi/parsing.rs#L67-L103","documentation":"Panic in `string_vec_to_bytes`: after serializing to JSON, `CString::new(json_string).expect(\"JSON string contains interior null bytes\")` aborts if the JSON text contains an interior NUL byte. Since CString cannot represent interior nulls, the library treats such output as a contract violation. For normal string contents serde_json escapes NULs as \\u0000, so this is also effectively unreachable for plain strings.","triggerScenarios":"Calling `string_vec_to_bytes` when the serialized JSON unexpectedly contains a raw interior null byte — realistically only via non-standard serialization output or corrupted string data, not ordinary `Vec<String>` content.","commonSituations":"Very rare: custom string types or patched serializers emitting raw NULs; post-processing the JSON string before passing it in; memory corruption. Ordinary usage (strings containing '\\0') is safe because serde_json escapes them.","solutions":["Inspect the input strings for raw NUL bytes and strip them at the source if feeding non-standard data","Do not post-process/replace within the serialized JSON before conversion","Use the standard serde_json version; rebuild if a patched dependency is present","If reproducible with plain strings, report it — the expected behavior is escaped \\u0000, no panic"],"exampleFix":"// before\nlet s = String::from_utf8(vec![b'a', 0, b'b']).unwrap(); // raw interior NUL handled ad-hoc\n// after\nlet cleaned: String = s.chars().filter(|&c| c != '\\0').collect();\nlet ptr = string_vec_to_bytes(&[cleaned]);","handlingStrategy":"validation","validationCode":"assert!(!json_string.contains('\\0'), \"JSON payload must not contain raw NUL bytes\");","typeGuard":null,"tryCatchPattern":"let result = std::panic::catch_unwind(|| string_vec_to_bytes(strings));\nif result.is_err() { eprintln!(\"interior NUL in serialized JSON\"); }","preventionTips":["Strip or escape raw NUL bytes from strings at the source","Do not post-process serialized JSON before conversion","Keep serde_json standard (it escapes \\u0000 automatically)","Check for memory corruption if this panic ever fires with plain strings"],"tags":["rust","ffi","json","panic","cstring"],"backgroundTag":"json-serialization-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}