{"record":{"id":"3fd435259066eeb7","repo":"denoland/deno","slug":"nul-byte-found-in-provided-data","errorCode":null,"errorMessage":"nul byte found in provided data","messagePattern":"nul byte found in provided data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"runtime/subprocess_windows/src/env.rs","lineNumber":227,"sourceCode":"// they are compared using a caseless string mapping.\nimpl From<OsString> for EnvKey {\n  fn from(k: OsString) -> Self {\n    EnvKey {\n      utf16: k.encode_wide().collect(),\n      os_string: k,\n    }\n  }\n}\n\nimpl From<&OsStr> for EnvKey {\n  fn from(k: &OsStr) -> Self {\n    Self::from(k.to_os_string())\n  }\n}\n\npub fn ensure_no_nuls<T: AsRef<OsStr>>(s: T) -> io::Result<T> {\n  if s.as_ref().encode_wide().any(|b| b == 0) {\n    Err(io::Error::new(\n      io::ErrorKind::InvalidInput,\n      \"nul byte found in provided data\",\n    ))\n  } else {\n    Ok(s)\n  }\n}\n\npub fn make_envp(\n  maybe_env: Option<BTreeMap<EnvKey, OsString>>,\n) -> io::Result<(*mut c_void, Vec<u16>)> {\n  // On Windows we pass an \"environment block\" which is not a char**, but\n  // rather a concatenation of null-terminated k=v\\0 sequences, with a final\n  // \\0 to terminate.\n  if let Some(env) = maybe_env {\n    let mut blk = Vec::new();\n\n    // If there are no environment variables to set then signal this by","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/runtime/subprocess_windows/src/env.rs#L209-L245","documentation":"On Windows, Deno builds the child-process environment block by encoding every variable name and value as NUL-terminated UTF-16 in make_envp(). Before that, ensure_no_nuls() scans each key and value and rejects any that already contain a U+0000, because an embedded NUL would terminate the entry early and silently corrupt the rest of the block. The failure surfaces from Deno.Command spawn as an InvalidInput error ('nul byte found in provided data').","triggerScenarios":"Calling new Deno.Command(prog, { env: {...} }).spawn() / .output() on Windows when any env key or value contains a NUL character, e.g. env: { TOKEN: \"a\\u0000b\" }. make_envp() runs ensure_no_nuls() over every entry of the env map supplied to the spawn options.","commonSituations":"Env values copied verbatim from binary files, protobuf/length-prefixed buffers, or Windows registry strings that carry embedded NUL terminators; passing serialized data through environment variables; strings assembled with String.fromCharCode(0).","solutions":["Strip or reject U+0000 in every env key and value before passing env to Deno.Command","Pass binary data via stdin, a temp file, or argv instead of environment variables","Add a spawn smoke test that uses the exact env map your app builds so NULs are caught before deployment"],"exampleFix":"// before\nconst cmd = new Deno.Command(\"cmd.exe\", {\n  env: { TOKEN: \"abc\\u0000def\" }, // embedded NUL -> spawn fails\n});\nconst child = cmd.spawn();\n\n// after\nconst clean = (s: string) => s.replaceAll(\"\\u0000\", \"\");\nconst env = Object.fromEntries(\n  Object.entries(rawEnv).map(([k, v]) => [clean(k), clean(String(v))]),\n);\nconst cmd = new Deno.Command(\"cmd.exe\", { env });\nconst child = cmd.spawn();","handlingStrategy":"validation","validationCode":"const hasNul = (s: string) => s.includes(\"\\u0000\");\nfunction assertCleanEnv(env: Record<string, string>) {\n  for (const [k, v] of Object.entries(env)) {\n    if (hasNul(k) || hasNul(v)) {\n      throw new Error(`NUL byte in environment entry: ${JSON.stringify(k)}`);\n    }\n  }\n}\n// assertCleanEnv(env) before new Deno.Command(prog, { env })","typeGuard":null,"tryCatchPattern":"try {\n  const child = cmd.spawn();\n} catch (err) {\n  if (err instanceof TypeError && err.message.includes(\"nul byte\")) {\n    // sanitize env (strip U+0000) and retry spawn\n  } else throw err;\n}","preventionTips":["Never pass binary blobs through env vars; use stdin or temp files","Sanitize strings read from files, registries, or protocols before injecting them into env","On Windows CI, run a spawn smoke test with the exact env map production builds"],"tags":["windows","subprocess","environment-variables","nul-byte","invalid-input"],"backgroundTag":"nul-byte-in-string","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}