{"record":{"id":"9486e3f27b89d0cb","repo":"ruvnet/ruflo","slug":"path-contains-null-bytes","errorCode":null,"errorMessage":"Path contains null bytes","messagePattern":"Path contains null bytes","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/appliance/rvfa-format.ts","lineNumber":387,"sourceCode":"    const sorted = [...header.sections].sort((a, b) => a.offset - b.offset);\n    for (let i = 1; i < sorted.length; i++) {\n      const prev = sorted[i - 1];\n      const curr = sorted[i];\n      if (prev.offset + prev.size > curr.offset) {\n        throw new Error(\n          `Sections \"${prev.id}\" and \"${curr.id}\" overlap ` +\n            `(${prev.offset}+${prev.size} > ${curr.offset})`,\n        );\n      }\n    }\n\n    return new RvfaReader(buf, header);\n  }\n\n  /** Read an RVFA image from a file path. */\n  static async fromFile(path: string): Promise<RvfaReader> {\n    if (path.includes('\\0')) {\n      throw new Error('Path contains null bytes');\n    }\n    const data = await readFile(path);\n    return RvfaReader.fromBuffer(data);\n  }\n\n  /** Return the parsed header. */\n  getHeader(): RvfaHeader {\n    return this.header;\n  }\n\n  /** List all sections declared in the header. */\n  getSections(): RvfaSection[] {\n    return this.header.sections;\n  }\n\n  /**\n   * Extract and decompress a section by its id.\n   *","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/appliance/rvfa-format.ts#L369-L405","documentation":"Thrown by RvfaReader.fromFile before opening the file. Null bytes can truncate or manipulate a resolved path on systems with C-style string handling, so the library rejects them up front rather than handing an unsafe path to readFile. It is an input-sanitization guard, not a file-not-found check.","triggerScenarios":"Calling RvfaReader.fromFile(path) where path contains a literal NUL ('\\0') character. Typical sources: an argv path that was copy-pasted from untrusted text, a path assembled by Buffer concatenation that included a 0x00 byte, or a path field read from an untrusted manifest.","commonSituations":"CLI invoked with a malformed argument; a test fixture built from raw buffers; an upstream tool that emits C-style null-terminated strings without trimming the terminator.","solutions":["Sanitize the path at the trust boundary: reject or strip '\\0' before calling fromFile.","Validate argv/env-supplied paths during CLI argument parsing, not inside the reader caller.","If a NUL was unintentional, regenerate the path string from a clean source."],"exampleFix":"// before\nconst reader = await RvfaReader.fromFile(argv[2]);\n\n// after\nconst p = argv[2];\nif (typeof p !== 'string' || p.includes('\\0')) {\n  throw new Error('Invalid path: contains null byte');\n}\nconst reader = await RvfaReader.fromFile(p);","handlingStrategy":"validation","validationCode":"function isSafeFilePath(p: unknown): boolean {\n  return typeof p === 'string' && p.length > 0 && !p.includes('\\0');\n}\nif (!isSafeFilePath(path)) {\n  throw new Error('Refusing path with null byte');\n}","typeGuard":"function isSafeFilePath(p: unknown): p is string {\n  return typeof p === 'string' && p.length > 0 && !p.includes('\\0');\n}","tryCatchPattern":null,"preventionTips":["Treat every external path as untrusted and sanitize at the boundary.","Never assemble paths by concatenating raw buffers that may contain 0x00.","Keep path validation in argv parsing, not deep inside file readers."],"tags":["path-validation","security","rvfa","input-sanitization"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}