{"record":{"id":"e8fb9ceb657e0cba","repo":"ruvnet/ruflo","slug":"sections-prev-id-and-curr-id-overlap","errorCode":null,"errorMessage":"Sections \"${prev.id}\" and \"${curr.id}\" overlap (${prev.offset}+${prev.size} > ${curr.offset})","messagePattern":"Sections \"(.+?)\" and \"(.+?)\" overlap \\((.+?)\\+(.+?) > (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/appliance/rvfa-format.ts","lineNumber":374,"sourceCode":"    for (const sec of header.sections) {\n      if (sec.offset < 0 || sec.size < 0) {\n        throw new Error(`Section \"${sec.id}\" has negative offset or size`);\n      }\n      if (sec.offset + sec.size > totalSize - SHA256_SIZE) {\n        throw new Error(\n          `Section \"${sec.id}\" extends beyond buffer ` +\n            `(offset=${sec.offset}, size=${sec.size}, bufLen=${totalSize})`,\n        );\n      }\n    }\n\n    // Check for overlapping sections\n    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","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/appliance/rvfa-format.ts#L356-L392","documentation":"After sorting header.sections by offset, a section's declared range [offset, offset+size) intrudes into the next section's range (prev.offset + prev.size > curr.offset). The writer always lays out sections contiguously, so any overlap means the header was hand-edited, corrupted, or crafted so extraction reads bytes belonging to a different section — a consistency check, not a size check.","triggerScenarios":"RvfaReader.fromBuffer where two header.sections[] entries reference intersecting byte ranges — e.g. offsets manually adjusted after image rebuild, a header JSON edited to point a section at another's data, or fuzzed/corrupt headers with scrambled offsets.","commonSituations":"Hand-patching a header to swap or inline a section; tools that rewrite one section in-place and forget to shift later offsets; malicious images trying to alias section data; copy-paste errors in custom build scripts that duplicate a descriptor with a stale offset.","solutions":["Rebuild the image with RvfaWriter — it recomputes all offsets contiguously in build(), which cannot overlap by construction","If patching is required, recompute every subsequent section's offset after resizing any section, then rewrite the footer hash","For untrusted images, verify the detached signature before parsing — overlapping sections on a signed file also indicates signature/content mismatch","Extract header.sections, sort by offset, and assert gaps are exactly size-aligned before distributing the image"],"exampleFix":"// before — patched section size without shifting the next offset\nsections[0].size += 256; // now overlaps sections[1]\n\n// after — shift every following section and fix the image\nlet cursor = sections[0].offset;\nfor (const s of sections.sort((a, b) => a.offset - b.offset)) {\n  s.offset = cursor;\n  cursor += s.size;\n}","handlingStrategy":"validation","validationCode":"const sections = [...header.sections].sort((a, b) => a.offset - b.offset);\nfor (let i = 1; i < sections.length; i++) {\n  if (sections[i - 1].offset + sections[i - 1].size > sections[i].offset)\n    throw new Error('section table inconsistent — rebuild image');\n}","typeGuard":null,"tryCatchPattern":"try { reader = RvfaReader.fromBuffer(buf); }\ncatch (e) {\n  if (/overlap/.test(String((e as Error).message))) {\n    // header was patched/corrupted: rebuild with RvfaWriter\n  }\n  throw e;\n}","preventionTips":["Never patch one section's size in place without shifting subsequent offsets","Always rebuild through RvfaWriter when section contents change","Verify signatures before parsing third-party images"],"tags":["rvfa","malformed-header","overlap","binary-format"],"backgroundTag":"malformed-binary-header","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}