{"record":{"id":"ff8e3fbf591f2582","repo":"mozilla/pdf.js","slug":"bad-domain-for-stiched-function","errorCode":null,"errorMessage":"Bad domain for stiched function","messagePattern":"Bad domain for stiched function","errorType":"exception","errorClass":"FormatError","httpStatus":null,"severity":"error","filePath":"src/core/function.js","lineNumber":299,"sourceCode":"    return function constructInterpolatedFn(src, srcOffset, dest, destOffset) {\n      const x = n === 1 ? src[srcOffset] : src[srcOffset] ** n;\n\n      for (let j = 0; j < length; ++j) {\n        dest[destOffset + j] = c0[j] + x * diff[j];\n      }\n    };\n  }\n\n  static constructStiched(factory, dict) {\n    const domain = toNumberArray(dict.getArray(\"Domain\"));\n\n    if (!domain) {\n      throw new FormatError(\"No domain\");\n    }\n\n    const inputSize = domain.length / 2;\n    if (inputSize !== 1) {\n      throw new FormatError(\"Bad domain for stiched function\");\n    }\n    const { xref } = factory;\n\n    const fns = [];\n    for (const fn of dict.get(\"Functions\")) {\n      fns.push(this.parse(factory, xref.fetchIfRef(fn)));\n    }\n\n    const bounds = toNumberArray(dict.getArray(\"Bounds\"));\n    const encode = toNumberArray(dict.getArray(\"Encode\"));\n    const tmpBuf = new Float32Array(1);\n\n    return function constructStichedFn(src, srcOffset, dest, destOffset) {\n      // Clamp to domain.\n      const v = MathClamp(src[srcOffset], domain[0], domain[1]);\n      // calculate which bound the value is in\n      const length = bounds.length;\n      let i;","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/function.js#L281-L317","documentation":"Thrown by PDFFunction.constructStiched (FunctionType 3) when /Domain exists but its length is not exactly 2 (i.e. inputSize !== 1). The PDF spec restricts stitching functions to a single input dimension, so any Domain with more than one interval is illegal for this function type.","triggerScenarios":"A FunctionType 3 dictionary has a /Domain array whose length is not 2 (e.g. [0 1 0 1] for a 2-D function). Reached during rendering of shading/gradients that reference the stitching function.","commonSituations":"PDF generation tools that wrongly reuse a multi-dimensional domain on a stitching function, or hand-authored PDFs where Domain was copy-pasted from a sampled function. Surfaced when rendering gradients with multiple stops.","solutions":["If you control generation, ensure stitching functions use a single-input Domain of length 2.","Validate against PDF 32000-1 §7.10.4 which mandates one input dimension for Type 3 functions.","Catch FormatError at render time and skip the shading.","Repair/regenerate the PDF with a conformant writer (e.g. Ghostscript) and re-render."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function stitchingDomainIsSingleInput(dict) {\n  const d = dict.getArray?.('Domain');\n  return Array.isArray(d) && d.length === 2 && d.every(Number.isFinite);\n}","typeGuard":"function isSingleIntervalDomain(arr) {\n  return Array.isArray(arr) && arr.length === 2 &&\n    typeof arr[0] === 'number' && typeof arr[1] === 'number';\n}","tryCatchPattern":"try { await page.render({ canvasContext }).promise; }\ncatch (err) {\n  if (err?.name === 'FormatError' && /Bad domain for stiched/.test(err.message)) {\n    console.warn('Stitching function has multi-dimensional domain; skipping.');\n  } else throw err;\n}","preventionTips":["Restrict stitching functions to exactly one input interval ([min max]).","Validate against PDF 32000-1 §7.10.4 when authoring.","Catch FormatError around render to degrade gracefully."],"tags":["pdf","function","stitching","domain","malformed-pdf"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}