All files / src/plugins/utils findOctetSequencePaths.js

97.92% Statements 47/48
94.74% Branches 36/38
100% Functions 5/5
97.87% Lines 46/47

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104                    32x 329x   23x     306x   306x 6x 300x 63x 237x 143x     304x       63x 63x 63x   63x     63x 63x 6x 55x 35x         2x 2x 2x 2x 2x 18x 1x   17x     2x   2x 2x         2x 2x 2x           61x       143x 143x 143x 110x 245x     245x       12x 233x       59x           143x     32x  
// Finds octet sequences (type: string, format: binary) in schemas including
// nested arrays, objects, nested arrays of type object, objects with properties
// that are nested arrays, and objects with properties that are objects This
// function takes a resolved schema object (no refs) and returns a list of
// paths to octet sequences (empty list if none found). The function accepts
// the path both as an array and a string and returns the path in the same
// format received:
// typeof(path) === 'array' => [[path1, get], [path2, get], ...]
// typeof(path) === 'string' => ['path1.get', 'path2.get', ...]
 
const findOctetSequencePaths = (resolvedSchema, path) => {
  if (!resolvedSchema) {
    // schema is empty, no octet sequence
    return [];
  }
 
  const pathsToOctetSequence = [];
 
  if (resolvedSchema.type === 'string' && resolvedSchema.format === 'binary') {
    pathsToOctetSequence.push(path);
  } else if (resolvedSchema.type === 'array') {
    pathsToOctetSequence.push(...arrayOctetSequences(resolvedSchema, path));
  } else if (resolvedSchema.type === 'object') {
    pathsToOctetSequence.push(...objectOctetSequences(resolvedSchema, path));
  }
 
  return pathsToOctetSequence;
};
 
function arrayOctetSequences(resolvedSchema, path) {
  const arrayPathsToOctetSequence = [];
  const arrayItems = resolvedSchema.items;
  Eif (arrayItems !== undefined) {
    // supports both array and string (delimited by .) paths
    const pathToSchema = Array.isArray(path)
      ? path.concat('items')
      : `${path}.items`;
    try {
      if (arrayItems.type === 'string' && arrayItems.format === 'binary') {
        arrayPathsToOctetSequence.push(pathToSchema);
      } else if (arrayItems.type === 'object' || arrayItems.type === 'array') {
        arrayPathsToOctetSequence.push(
          ...findOctetSequencePaths(arrayItems, pathToSchema)
        );
      }
    } catch (err) {
      Eif (err instanceof TypeError) {
        const escapedPaths = [];
        const strEscaper = function(strToEscape) {
          let newStr = '';
          for (let i = 0; i < strToEscape.length; i++) {
            if (strToEscape.charAt(i) == '/') {
              newStr = newStr + '\\/';
            } else {
              newStr = newStr + strToEscape.charAt(i);
            }
          }
          escapedPaths.push(newStr);
        };
        path.forEach(strEscaper);
        const e = new TypeError(
          'items.type and items.format must resolve for the path "' +
            escapedPaths.join('/') +
            '"'
        );
        e.stack = err.stack;
        e.original = err;
        throw e;
      } else {
        throw err;
      }
    }
  }
  return arrayPathsToOctetSequence;
}
 
function objectOctetSequences(resolvedSchema, path) {
  const objectPathsToOctetSequence = [];
  const objectProperties = resolvedSchema.properties;
  if (objectProperties) {
    Object.keys(objectProperties).forEach(function(prop) {
      const propPath = Array.isArray(path)
        ? path.concat(['properties', prop])
        : `${path}.properties.${prop}`;
      if (
        objectProperties[prop].type === 'string' &&
        objectProperties[prop].format === 'binary'
      ) {
        objectPathsToOctetSequence.push(propPath);
      } else if (
        objectProperties[prop].type === 'object' ||
        objectProperties[prop].type === 'array'
      ) {
        objectPathsToOctetSequence.push(
          ...findOctetSequencePaths(objectProperties[prop], propPath)
        );
      }
    });
  }
  return objectPathsToOctetSequence;
}
 
module.exports.findOctetSequencePaths = findOctetSequencePaths;