function sanitizeTTProgram()

in src/core/fonts.js [2352:2547]


    function sanitizeTTProgram(table, ttContext) {
      let data = table.data;
      let i = 0,
        j,
        n,
        b,
        funcId,
        pc,
        lastEndf = 0,
        lastDeff = 0;
      const stack = [];
      const callstack = [];
      const functionsCalled = [];
      let tooComplexToFollowFunctions = ttContext.tooComplexToFollowFunctions;
      let inFDEF = false,
        ifLevel = 0,
        inELSE = 0;
      for (let ii = data.length; i < ii; ) {
        const op = data[i++];
        // The TrueType instruction set docs can be found at
        // https://developer.apple.com/fonts/TTRefMan/RM05/Chap5.html
        if (op === 0x40) {
          // NPUSHB - pushes n bytes
          n = data[i++];
          if (inFDEF || inELSE) {
            i += n;
          } else {
            for (j = 0; j < n; j++) {
              stack.push(data[i++]);
            }
          }
        } else if (op === 0x41) {
          // NPUSHW - pushes n words
          n = data[i++];
          if (inFDEF || inELSE) {
            i += n * 2;
          } else {
            for (j = 0; j < n; j++) {
              b = data[i++];
              stack.push((b << 8) | data[i++]);
            }
          }
        } else if ((op & 0xf8) === 0xb0) {
          // PUSHB - pushes bytes
          n = op - 0xb0 + 1;
          if (inFDEF || inELSE) {
            i += n;
          } else {
            for (j = 0; j < n; j++) {
              stack.push(data[i++]);
            }
          }
        } else if ((op & 0xf8) === 0xb8) {
          // PUSHW - pushes words
          n = op - 0xb8 + 1;
          if (inFDEF || inELSE) {
            i += n * 2;
          } else {
            for (j = 0; j < n; j++) {
              b = data[i++];
              stack.push(signedInt16(b, data[i++]));
            }
          }
        } else if (op === 0x2b && !tooComplexToFollowFunctions) {
          // CALL
          if (!inFDEF && !inELSE) {
            // collecting information about which functions are used
            funcId = stack.at(-1);
            if (isNaN(funcId)) {
              info("TT: CALL empty stack (or invalid entry).");
            } else {
              ttContext.functionsUsed[funcId] = true;
              if (funcId in ttContext.functionsStackDeltas) {
                const newStackLength =
                  stack.length + ttContext.functionsStackDeltas[funcId];
                if (newStackLength < 0) {
                  warn("TT: CALL invalid functions stack delta.");
                  ttContext.hintsValid = false;
                  return;
                }
                stack.length = newStackLength;
              } else if (
                funcId in ttContext.functionsDefined &&
                !functionsCalled.includes(funcId)
              ) {
                callstack.push({ data, i, stackTop: stack.length - 1 });
                functionsCalled.push(funcId);
                pc = ttContext.functionsDefined[funcId];
                if (!pc) {
                  warn("TT: CALL non-existent function");
                  ttContext.hintsValid = false;
                  return;
                }
                data = pc.data;
                i = pc.i;
              }
            }
          }
        } else if (op === 0x2c && !tooComplexToFollowFunctions) {
          // FDEF
          if (inFDEF || inELSE) {
            warn("TT: nested FDEFs not allowed");
            tooComplexToFollowFunctions = true;
          }
          inFDEF = true;
          // collecting information about which functions are defined
          lastDeff = i;
          funcId = stack.pop();
          ttContext.functionsDefined[funcId] = { data, i };
        } else if (op === 0x2d) {
          // ENDF - end of function
          if (inFDEF) {
            inFDEF = false;
            lastEndf = i;
          } else {
            pc = callstack.pop();
            if (!pc) {
              warn("TT: ENDF bad stack");
              ttContext.hintsValid = false;
              return;
            }
            funcId = functionsCalled.pop();
            data = pc.data;
            i = pc.i;
            ttContext.functionsStackDeltas[funcId] = stack.length - pc.stackTop;
          }
        } else if (op === 0x89) {
          // IDEF - instruction definition
          if (inFDEF || inELSE) {
            warn("TT: nested IDEFs not allowed");
            tooComplexToFollowFunctions = true;
          }
          inFDEF = true;
          // recording it as a function to track ENDF
          lastDeff = i;
        } else if (op === 0x58) {
          // IF
          ++ifLevel;
        } else if (op === 0x1b) {
          // ELSE
          inELSE = ifLevel;
        } else if (op === 0x59) {
          // EIF
          if (inELSE === ifLevel) {
            inELSE = 0;
          }
          --ifLevel;
        } else if (op === 0x1c) {
          // JMPR
          if (!inFDEF && !inELSE) {
            const offset = stack.at(-1);
            // only jumping forward to prevent infinite loop
            if (offset > 0) {
              i += offset - 1;
            }
          }
        }
        // Adjusting stack not extactly, but just enough to get function id
        if (!inFDEF && !inELSE) {
          let stackDelta = 0;
          if (op <= 0x8e) {
            stackDelta = TTOpsStackDeltas[op];
          } else if (op >= 0xc0 && op <= 0xdf) {
            stackDelta = -1;
          } else if (op >= 0xe0) {
            stackDelta = -2;
          }
          if (op >= 0x71 && op <= 0x75) {
            n = stack.pop();
            if (!isNaN(n)) {
              stackDelta = -n * 2;
            }
          }
          while (stackDelta < 0 && stack.length > 0) {
            stack.pop();
            stackDelta++;
          }
          while (stackDelta > 0) {
            stack.push(NaN); // pushing any number into stack
            stackDelta--;
          }
        }
      }
      ttContext.tooComplexToFollowFunctions = tooComplexToFollowFunctions;
      const content = [data];
      if (i > data.length) {
        content.push(new Uint8Array(i - data.length));
      }
      if (lastDeff > lastEndf) {
        warn("TT: complementing a missing function tail");
        // new function definition started, but not finished
        // complete function by [CLEAR, ENDF]
        content.push(new Uint8Array([0x22, 0x2d]));
      }
      foldTTTable(table, content);
    }