Language: JavaScript
Label: vulnerable
CWE: CWE-77 \u2014 Improper Neutralization of Special Elements used in a Command ('Command Injection')
The product constructs all or part of a command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended command when it is sent to a downstream component.

Code:
  process: function(image, options, callback) {

    if (typeof options === 'function') {
      callback = options;
      options = null;
    }

    const shellMetaChar = /\$\(.+\)/;
    if (shellMetaChar.test(image)) {
      callback(Error('Invalid image path'));
      return;
    }
    
    var defaultOptions = utils.merge({}, Tesseract.options);
    options = utils.merge(defaultOptions, options);

    // generate output file name
    var output = path.resolve(tmpdir, 'node-tesseract-' + uuid.v4());

    // add the tmp file to the list
    Tesseract.tmpFiles.push(output);

    // assemble tesseract command
    var command = [options.binary, image, output];

    if (options.l !== null) {
      command.push('-l ' + options.l);
    }

    if (options.psm !== null) {
      command.push('--psm ' + options.psm);
    }

    if (options.config !== null) {
      command.push(options.config);
    }

    command = command.join(' ');

    var opts = options.env || {};

    // Run the tesseract command
    exec(command, opts, function(err, stdout, stderr) {
      if (err) {
        // Something went wrong executing the assembled command
        callback(err, null);
        return;
      }

      let extra = {};

      const regex = /OSD:[\s\w\d\(\),.]+: ([\d]+)/;
      if (regex.test(stderr)) {
        let match = regex.exec(stderr);
        let orientation = parseInt(match[1]);
        extra.orientation = orientation;
      }

      // Find one of the three possible extension
      glob(output + '.+(html|hocr|txt)', function(err, files){
        if (err) {
          callback(err, null);
          return;
        }
        fs.readFile(files[0], Tesseract.outputEncoding, function(err, data) {
          if (err) {
            callback(err, null);
            return;
          }

          var index = Tesseract.tmpFiles.indexOf(output);
          if (~index) Tesseract.tmpFiles.splice(index, 1);

          fs.unlinkSync(files[0]);

          callback(null, data, extra);
        });
      })
    }); // end exec

  }