require("source-map-support").install();
/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	var __webpack_modules__ = ([
/* 0 */,
/* 1 */
/***/ ((module) => {

module.exports = require("path");;

/***/ }),
/* 2 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {



Object.defineProperty(exports, "__esModule", ({
  value: true
}));
exports.errorParamsToUnsupportedVersionRange = errorParamsToUnsupportedVersionRange;
exports.normalizePath = normalizePath;
exports.getRootExpression = getRootExpression;
exports.getNodeReference = getNodeReference;
exports.getVariable = getVariable;
exports.getLocale = getLocale;
exports.getI18Data = getI18Data;
exports.buildI18nObject = buildI18nObject;
exports.checkMinNodeVersion = checkMinNodeVersion;
exports.getPackageTypeAsString = getPackageTypeAsString;
exports.ignorePrivateFunctions = ignorePrivateFunctions;
exports.ensureFilenameExists = ensureFilenameExists;
exports.isLocalUrl = isLocalUrl;
exports.apiToMessage = apiToMessage;
exports.isBrowserNamespace = isBrowserNamespace;
exports.parseCspPolicy = parseCspPolicy;
exports.getLineAndColumnFromMatch = getLineAndColumnFromMatch;
exports.couldBeMinifiedCode = couldBeMinifiedCode;
exports.firefoxStrictMinVersion = firefoxStrictMinVersion;
exports.basicCompatVersionComparison = basicCompatVersionComparison;
exports.firstStableVersion = firstStableVersion;
exports.isCompatible = isCompatible;
exports.createCompatibilityRule = createCompatibilityRule;
exports.i18n = exports.AddonsLinterUserError = void 0;

var _url = _interopRequireDefault(__webpack_require__(3));

var _upath = _interopRequireDefault(__webpack_require__(4));

var _jed2 = _interopRequireDefault(__webpack_require__(5));

var _semver = _interopRequireDefault(__webpack_require__(6));

var _commonTags = __webpack_require__(7);

var _osLocale = _interopRequireDefault(__webpack_require__(8));

var _logger = _interopRequireDefault(__webpack_require__(9));

var _const = __webpack_require__(11);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/* global nodeRequire, localesRoot */
const SOURCE_MAP_RE = new RegExp(/\/\/[#@]\s(source(?:Mapping)?URL)=\s*(\S+)/); // Represents an error condition related to a user error (e.g. an invalid
// configuration option passed to the linter class, usually through the
// command line arguments).
//
// In bin/addons-linter instances of this error are recognized through the
// error name property and by default they will be logged on stderr as
// plain error messages and the error stack trace omitted (unless explicitly
// requested by passing --stack as an additional CLI options, useful for
// debugging reasons).

class AddonsLinterUserError extends Error {
  get name() {
    return 'AddonsLinterUserError';
  }

}

exports.AddonsLinterUserError = AddonsLinterUserError;

function errorParamsToUnsupportedVersionRange(errorParams) {
  const {
    min_manifest_version,
    max_manifest_version
  } = errorParams || {};

  if (min_manifest_version != null || max_manifest_version != null) {
    return [min_manifest_version ? `< ${min_manifest_version}` : undefined, max_manifest_version ? `> ${max_manifest_version}` : undefined].filter(e => e !== undefined).join(', ');
  }

  return '';
}

function normalizePath(iconPath) {
  // Convert the icon path to a URL so we can strip any fragments and resolve
  // . and .. automatically. We need an absolute URL to use as a base so we're
  // using https://example.com/.
  const {
    pathname
  } = new URL(iconPath, 'https://example.com/'); // Convert filename to unix path separator (as the ones stored
  // into the scanned files map).

  return _upath.default.toUnix(decodeURIComponent(pathname).slice(1));
}
/*
 * Takes an AST node and returns the root property.
 *
 * example: foo().bar.baz() will return the AST node for foo.
 */


function getRootExpression(node) {
  let root = node.callee; // If we encounter a member, grab the parent

  if (node.callee.type === 'MemberExpression') {
    let parent = node.callee.object;

    while (parent.type !== 'Identifier') {
      if (parent.callee.type === 'MemberExpression') {
        parent = parent.callee.object;
      } else {
        parent = parent.callee;
      }
    }

    root = parent;
  }

  return root;
}
/*
 * Returns the name of the reference node passed.
 *
 * example: var foo = document;
 *  The node for foo will return 'document'
 */


function getNodeReference(context, node) {
  const {
    variables
  } = context.getScope();
  let scopeVar; // Just return the value if the node passed in is a reference to a literal.

  if (typeof node === 'undefined' || node.type === 'Literal') {
    return node;
  } // Finds variable reference in current scope.


  for (let i = 0; i < variables.length; i++) {
    const variable = variables[i];

    if (variable.name === node.name) {
      scopeVar = variable;
      break;
    }
  }

  if (scopeVar && scopeVar.defs && scopeVar.defs[0] && scopeVar.defs[0].parent && scopeVar.defs[0].parent.parent && scopeVar.defs[0].parent.parent.body) {
    // This represents all occurrences of the variable
    const occurances = scopeVar.defs[0].parent.parent.body;
    let lastAssignment;

    if (occurances instanceof Array) {
      occurances.forEach(occurance => {
        if (occurance.type === 'VariableDeclaration' && occurance.declarations[0].init !== null) {
          // Get what the name of what it was assigned to or the raw
          // value depending on the initalization
          lastAssignment = occurance.declarations[0].init;
        } else if (occurance.type === 'ExpressionStatement' && occurance.expression.type === 'AssignmentExpression') {
          // Get the right hand side of the assignment
          lastAssignment = occurance.expression.right;
        }
      });
    } // Return the name of the first definition of the variable which
    // corresponds to the node passed in.


    if (lastAssignment) {
      return lastAssignment;
    }
  } // If that variable doesn't exist in scope, then just return the node's
  // name.


  return node;
}
/*
 * Get a variable from a eslint context object if it exists, otherwise
 * undefined.
 */


function getVariable(context, name) {
  const {
    variables
  } = context.getScope();
  let result;
  variables.forEach(variable => {
    if (variable.name === name && variable.defs && variable.defs[0] && variable.defs[0].name && variable.defs[0].name.parent) {
      result = variable.defs[0].name.parent.init;
    }
  });
  return result;
}

function getLocale() {
  return _osLocale.default.sync();
}

function getI18Data(locale) {
  let i18ndata = {};

  try {
    // eslint-disable-next-line global-require, import/no-dynamic-require
    i18ndata = nodeRequire(`${localesRoot}/${locale}/messages.js`);
  } catch (err) {
    _logger.default.info('Initialize locales using extract-locales command');
  }

  return i18ndata;
}
/*
 * Gettext utils. Used for translating strings.
 */


function buildI18nObject(i18nData) {
  const _jed = new _jed2.default(i18nData);

  return {
    jed: _jed,
    getI18Data,
    _: str => {
      return _jed.gettext(str);
    },
    gettext: str => {
      return _jed.gettext(str);
    },
    sprintf: (fmt, args) => {
      return _jed.sprintf(fmt, args);
    }
  };
}

const i18n = buildI18nObject(getI18Data(getLocale()));
/*
 * Check the minimum node version is met
 */

exports.i18n = i18n;

async function checkMinNodeVersion(minVersion, _process = process) {
  // eslint-disable-next-line no-param-reassign
  minVersion = minVersion || '0.12.0';

  if (!_semver.default.gte(_process.version, minVersion)) {
    throw new Error((0, _commonTags.oneLine)`Node version must be ${minVersion} or
                    greater. You are using ${_process.version}.`);
  }
}

function getPackageTypeAsString(numericPackageType) {
  const packageKeys = Object.keys(_const.PACKAGE_TYPES);

  for (let i = 0; i < packageKeys.length; i++) {
    const packageType = packageKeys[i];

    if (parseInt(numericPackageType, 10) === _const.PACKAGE_TYPES[packageType]) {
      return packageType;
    }
  }

  throw new Error(`Invalid package type constant "${numericPackageType}"`);
}
/*
 * Looks through all exported functions and returns only
 * "public" *functions* that aren't prefixed with an _
 *
 * Used for ignoring private functions and constants in rules files.
 * Rules can have private functions we don't run; anything that
 * starts with an "_" shouldn't be returned.
 *
 * This exists because we export private functions in rule files
 * for testing.
 */


function ignorePrivateFunctions(list) {
  const filteredList = {};
  Object.keys(list).forEach(functionName => {
    if (functionName.startsWith('_') === false && typeof list[functionName] === 'function') {
      filteredList[functionName] = list[functionName];
    }
  });
  return filteredList;
}
/*
 * Check a filename to make sure it's valid; used by scanners so we never
 * accept new scanners that don't specify which file they're referencing.
 */


function ensureFilenameExists(filename) {
  if (typeof filename !== 'string' || filename.length < 1) {
    throw new Error('Filename is required');
  }
}

function isLocalUrl(urlInput) {
  const parsedUrl = _url.default.parse(urlInput);

  const {
    protocol,
    path
  } = parsedUrl; // Check protocol is chrome: or resource: if set.
  // Details on the chrome protocol are here: https://goo.gl/W52T0Q
  // Details on resource protocol are here: https://goo.gl/HHqeJA

  if (protocol && !_const.LOCAL_PROTOCOLS.includes(protocol)) {
    return false;
  } // Disallow protocol-free remote urls.


  if (path.startsWith('//')) {
    return false;
  }

  return true;
}

function apiToMessage(string) {
  return string.replace(/^extension/, 'ext').replace(/\./g, '_').toUpperCase().substr(0, 25);
}

function isBrowserNamespace(string) {
  return ['browser', 'chrome'].includes(string);
}

function parseCspPolicy(policy) {
  if (!policy) {
    return {};
  } // eslint-disable-next-line no-param-reassign


  policy = policy.toLowerCase();
  const parsedPolicy = {};
  const directives = policy.split(';');
  directives.forEach(directive => {
    // eslint-disable-next-line no-param-reassign
    directive = directive.trim();
    const tokens = directive.split(/\s+/);
    const name = tokens[0];

    if (name) {
      parsedPolicy[name] = tokens.slice(1, tokens.length);
    }
  });
  return parsedPolicy;
}

function getLineAndColumnFromMatch(match) {
  const matchedLines = match.input.substr(0, match.index).split('\n');
  const matchedColumn = matchedLines.slice(-1)[0].length + 1;
  const matchedLine = matchedLines.length;
  return {
    matchedLine,
    matchedColumn
  };
}
/**
 * Determines if the source text is minified.
 * Using the percentage no. of the indented lines from a sample set of lines
 * to determine if the js file is minified.
 * Inspired by code for the Firefox Developer Toolbar.
 */


function couldBeMinifiedCode(code) {
  // Fast exit if `code` is empty. Could happen in tests, but also in real
  // files.
  if (!code) {
    return false;
  } // If there's a source map reference it's very certainly minified code.


  if (SOURCE_MAP_RE.test(code)) {
    return true;
  } // Number of lines to look at, taken from the head of the code.


  const sampleSize = 30; // Threshold in percent of indented lines to mark a file as not
  // minified.

  const indentCountThreshold = 20; // percentage
  // Length of a line that looks suspicious of being minified

  const hugeLinesLength = 500; // Number of huge lines to also mark a file as potentially minified
  // Hint: Minified AngularJS has 12 lines, jQuery 4

  const hugeLinesThreshold = 4;
  let lineEndIndex = 0;
  let lineStartIndex = 0;
  let lines = 1;
  let indentCount = 0;
  let hugeLinesCount = 0; // Strip comments.

  const normalizedCode = code.replace(/\/\*[\S\s]*?\*\/|\/\/.+/g, '');

  while (lines < sampleSize) {
    lineEndIndex = normalizedCode.indexOf('\n', lineStartIndex);

    if (lineEndIndex === -1) {
      break;
    }

    const currentLine = normalizedCode.slice(lineStartIndex, lineEndIndex);

    if (/^\s+/.test(currentLine)) {
      indentCount++;
    }

    if (currentLine.length >= hugeLinesLength) {
      hugeLinesCount++;
    }

    lineStartIndex = lineEndIndex + 1;
    lines++;
  }

  return indentCount / lines * 100 < indentCountThreshold || hugeLinesCount > hugeLinesThreshold;
}

function firefoxStrictMinVersion(manifestJson) {
  if (manifestJson.applications && manifestJson.applications.gecko && manifestJson.applications.gecko.strict_min_version) {
    return parseInt(manifestJson.applications.gecko.strict_min_version.split('.')[0], 10);
  }

  return null;
}

function basicCompatVersionComparison(versionAdded, minVersion) {
  const asNumber = parseInt(versionAdded, 10);
  return !Number.isNaN(asNumber) && asNumber > minVersion;
}
/**
 * @param {*} supportInfo - bcd support info of a feature
 * @returns {string|boolean} The first version number to support the feature
 *          or a boolean indicating if the feature is supported at all. We do
 *          not consider any holes in the supported versions, only the first
 *          stable version is taken into account.
 */


function firstStableVersion(supportInfo) {
  let supportInfoArray = supportInfo;

  if (!Array.isArray(supportInfo)) {
    supportInfoArray = [supportInfo];
  }

  return supportInfoArray.reduce((versionAdded, supportEntry) => {
    if (!Object.prototype.hasOwnProperty.call(supportEntry, 'flags') && (!versionAdded || supportEntry.version_added && !basicCompatVersionComparison(supportEntry.version_added, parseInt(versionAdded, 10)))) {
      return supportEntry.version_added;
    }

    return versionAdded;
  }, false);
}

function isCompatible(bcd, path, minVersion, application) {
  const steps = path.split('.');
  let {
    api
  } = bcd.webextensions;

  for (const step of steps) {
    if (Object.prototype.hasOwnProperty.call(api, step)) {
      api = api[step];
    } else {
      break;
    }
  } // API namespace may be undocumented or not implemented, ignore in that case.


  if (api.__compat) {
    const supportInfo = api.__compat.support[application];
    const versionAdded = firstStableVersion(supportInfo);
    return !basicCompatVersionComparison(versionAdded, minVersion);
  }

  return true;
}

function createCompatibilityRule(application, message, context, bcd, hasBrowserApi) {
  const {
    addonMetadata
  } = context.settings;
  const minVersion = addonMetadata && firefoxStrictMinVersion({
    applications: {
      gecko: {
        strict_min_version: context.settings.addonMetadata.firefoxMinVersion
      }
    }
  });

  if (minVersion) {
    return {
      MemberExpression(node) {
        if (!node.computed && node.object.object && isBrowserNamespace(node.object.object.name)) {
          const namespace = node.object.property.name;
          const property = node.property.name;
          const api = `${namespace}.${property}`;

          if (hasBrowserApi(namespace, property, addonMetadata) && !isCompatible(bcd, api, minVersion, application)) {
            context.report(node, message.messageFormat, {
              api,
              minVersion: addonMetadata.firefoxMinVersion
            });
          }
        }
      }

    };
  }

  return {};
}

/***/ }),
/* 3 */
/***/ ((module) => {

module.exports = require("url");;

/***/ }),
/* 4 */
/***/ ((module) => {

module.exports = require("upath");;

/***/ }),
/* 5 */
/***/ ((module) => {

module.exports = require("jed");;

/***/ }),
/* 6 */
/***/ ((module) => {

module.exports = require("semver");;

/***/ }),
/* 7 */
/***/ ((module) => {

module.exports = require("common-tags");;

/***/ }),
/* 8 */
/***/ ((module) => {

module.exports = require("os-locale");;

/***/ }),
/* 9 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {



Object.defineProperty(exports, "__esModule", ({
  value: true
}));
exports.createLogger = createLogger;
exports.default = void 0;

var _pino = _interopRequireDefault(__webpack_require__(10));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function createLogger(_process = process) {
  const level = _process.env.LOG_LEVEL || 'fatal';
  return (0, _pino.default)({
    name: 'AddonLinterJS',
    level
  }, process.stdout);
}

var _default = createLogger();

exports.default = _default;

/***/ }),
/* 10 */
/***/ ((module) => {

module.exports = require("pino");;

/***/ }),
/* 11 */
/***/ ((__unused_webpack_module, exports) => {



Object.defineProperty(exports, "__esModule", ({
  value: true
}));
exports.RESTRICTED_HOMEPAGE_URLS = exports.ZIP_LIB_CORRUPT_FILE_ERROR = exports.MESSAGE_PLACEHOLDER_REGEXP = exports.LOCALES_DIRECTORY = exports.MESSAGES_JSON = exports.CSP_KEYWORD_RE = exports.TEMPORARY_APIS = exports.FLAGGED_FILE_MAGIC_NUMBERS = exports.DEPRECATED_JAVASCRIPT_APIS = exports.DEPRECATED_MANIFEST_PROPERTIES = exports.STATIC_THEME_IMAGE_MIMES = exports.FILE_EXTENSIONS_TO_MIME = exports.IMAGE_FILE_EXTENSIONS = exports.FLAGGED_FILE_EXTENSIONS = exports.RESERVED_FILENAMES = exports.PERMS_DATAPATH_REGEX = exports.ALREADY_SIGNED_REGEX = exports.FLAGGED_FILE_REGEX = exports.HIDDEN_FILE_REGEX = exports.MAX_FILE_SIZE_TO_PARSE_MB = exports.MANIFEST_VERSION_MAX = exports.MANIFEST_VERSION_MIN = exports.MANIFEST_VERSION_DEFAULT = exports.MANIFEST_JSON = exports.LOCAL_PROTOCOLS = exports.PACKAGE_TYPES = exports.PACKAGE_SUBPACKAGE = exports.PACKAGE_MULTI = exports.PACKAGE_SEARCHPROV = exports.PACKAGE_LANGPACK = exports.PACKAGE_DICTIONARY = exports.PACKAGE_THEME = exports.PACKAGE_EXTENSION = exports.PACKAGE_ANY = exports.MESSAGE_TYPES = exports.ESLINT_TYPES = exports.VALIDATION_WARNING = exports.VALIDATION_NOTICE = exports.VALIDATION_ERROR = exports.ESLINT_RULE_MAPPING = exports.EXTERNAL_RULE_MAPPING = exports.ESLINT_WARNING = exports.ESLINT_ERROR = void 0;
const ESLINT_ERROR = 2;
exports.ESLINT_ERROR = ESLINT_ERROR;
const ESLINT_WARNING = 1; // Disable escapers (Sanitizer.escapeHTML, escapeHTML)
// and unwrappers (Sanitizer.unwrapSafeHTML, unwrapSafeHTML)
// which are allowed by default by this plugin.

exports.ESLINT_WARNING = ESLINT_WARNING;
const DISABLE_ALLOWED_ESCAPERS = {
  escape: {
    taggedTemplates: [],
    methods: []
  }
}; // 3rd party / eslint-internal rules

const EXTERNAL_RULE_MAPPING = {
  'no-eval': [ESLINT_WARNING, {
    allowIndirect: false
  }],
  'no-implied-eval': ESLINT_WARNING,
  'no-new-func': ESLINT_WARNING,
  'no-unsanitized/method': [ESLINT_WARNING, DISABLE_ALLOWED_ESCAPERS],
  'no-unsanitized/property': [ESLINT_WARNING, DISABLE_ALLOWED_ESCAPERS]
};
exports.EXTERNAL_RULE_MAPPING = EXTERNAL_RULE_MAPPING;
const ESLINT_RULE_MAPPING = {
  'deprecated-entities': ESLINT_WARNING,
  'event-listener-fourth': ESLINT_WARNING,
  'global-require-arg': ESLINT_WARNING,
  'opendialog-nonlit-uri': ESLINT_WARNING,
  'opendialog-remote-uri': ESLINT_WARNING,
  'webextension-api': ESLINT_WARNING,
  'webextension-deprecated-api': ESLINT_WARNING,
  'webextension-unsupported-api': ESLINT_WARNING,
  'content-scripts-file-absent': ESLINT_ERROR,
  'webextension-api-compat': ESLINT_WARNING,
  'webextension-api-compat-android': ESLINT_WARNING,
  ...EXTERNAL_RULE_MAPPING
};
exports.ESLINT_RULE_MAPPING = ESLINT_RULE_MAPPING;
const VALIDATION_ERROR = 'error';
exports.VALIDATION_ERROR = VALIDATION_ERROR;
const VALIDATION_NOTICE = 'notice';
exports.VALIDATION_NOTICE = VALIDATION_NOTICE;
const VALIDATION_WARNING = 'warning';
exports.VALIDATION_WARNING = VALIDATION_WARNING;
const ESLINT_TYPES = {
  0: VALIDATION_NOTICE,
  1: VALIDATION_WARNING,
  2: VALIDATION_ERROR
};
exports.ESLINT_TYPES = ESLINT_TYPES;
const MESSAGE_TYPES = [VALIDATION_ERROR, VALIDATION_NOTICE, VALIDATION_WARNING]; // Package type constants.

exports.MESSAGE_TYPES = MESSAGE_TYPES;
const PACKAGE_ANY = 0;
exports.PACKAGE_ANY = PACKAGE_ANY;
const PACKAGE_EXTENSION = 1;
exports.PACKAGE_EXTENSION = PACKAGE_EXTENSION;
const PACKAGE_THEME = 2;
exports.PACKAGE_THEME = PACKAGE_THEME;
const PACKAGE_DICTIONARY = 3;
exports.PACKAGE_DICTIONARY = PACKAGE_DICTIONARY;
const PACKAGE_LANGPACK = 4;
exports.PACKAGE_LANGPACK = PACKAGE_LANGPACK;
const PACKAGE_SEARCHPROV = 5;
exports.PACKAGE_SEARCHPROV = PACKAGE_SEARCHPROV;
const PACKAGE_MULTI = 1; // A multi extension is an extension

exports.PACKAGE_MULTI = PACKAGE_MULTI;
const PACKAGE_SUBPACKAGE = 7;
exports.PACKAGE_SUBPACKAGE = PACKAGE_SUBPACKAGE;
const PACKAGE_TYPES = {
  PACKAGE_ANY,
  PACKAGE_EXTENSION,
  PACKAGE_THEME,
  PACKAGE_DICTIONARY,
  PACKAGE_LANGPACK,
  PACKAGE_SEARCHPROV,
  PACKAGE_MULTI,
  PACKAGE_SUBPACKAGE
};
exports.PACKAGE_TYPES = PACKAGE_TYPES;
const LOCAL_PROTOCOLS = ['chrome:', 'resource:'];
exports.LOCAL_PROTOCOLS = LOCAL_PROTOCOLS;
const MANIFEST_JSON = 'manifest.json'; // The manifest_version value to use to complete the validation if an explicit one
// was missing from the extension manifest.json (but we will still be collecting the
// error for the missing manifest_version property, because it is mandatory).

exports.MANIFEST_JSON = MANIFEST_JSON;
const MANIFEST_VERSION_DEFAULT = 2; // Default min/max_manifest_version values used for schema definitions that do not
// have an explicit one on their own.

exports.MANIFEST_VERSION_DEFAULT = MANIFEST_VERSION_DEFAULT;
const MANIFEST_VERSION_MIN = 2;
exports.MANIFEST_VERSION_MIN = MANIFEST_VERSION_MIN;
const MANIFEST_VERSION_MAX = 3; // This is the limit in megabytes of a file we will parse (eg. CSS, JS, etc.)
// A singular CSS/JS file over 4MB seems bad and may actually be full of data
// best stored in JSON/some other data format rather than code.
// https://github.com/mozilla/addons-linter/issues/730
// We increased this limit from 2MB to 4MB as per:
// https://github.com/mozilla/addons/issues/181
//
// We should be careful about increasing this any further.

exports.MANIFEST_VERSION_MAX = MANIFEST_VERSION_MAX;
const MAX_FILE_SIZE_TO_PARSE_MB = 4;
exports.MAX_FILE_SIZE_TO_PARSE_MB = MAX_FILE_SIZE_TO_PARSE_MB;
const HIDDEN_FILE_REGEX = /^__MACOSX\//;
exports.HIDDEN_FILE_REGEX = HIDDEN_FILE_REGEX;
const FLAGGED_FILE_REGEX = /thumbs\.db$|\.DS_Store$|\.orig$|\.old$|~$/i;
exports.FLAGGED_FILE_REGEX = FLAGGED_FILE_REGEX;
const ALREADY_SIGNED_REGEX = /^META-INF\/manifest\.mf/;
exports.ALREADY_SIGNED_REGEX = ALREADY_SIGNED_REGEX;
const PERMS_DATAPATH_REGEX = /^\/(permissions|optional_permissions)\/([\d+])/;
exports.PERMS_DATAPATH_REGEX = PERMS_DATAPATH_REGEX;
const RESERVED_FILENAMES = ['mozilla-recommendation.json'];
exports.RESERVED_FILENAMES = RESERVED_FILENAMES;
const FLAGGED_FILE_EXTENSIONS = ['.class', '.dll', '.dylib', '.exe', '.jar', '.sh', '.so', '.swf'];
exports.FLAGGED_FILE_EXTENSIONS = FLAGGED_FILE_EXTENSIONS;
const IMAGE_FILE_EXTENSIONS = ['jpg', 'jpeg', 'webp', 'gif', 'png', 'svg'];
exports.IMAGE_FILE_EXTENSIONS = IMAGE_FILE_EXTENSIONS;
const FILE_EXTENSIONS_TO_MIME = {
  svg: 'image/svg+xml',
  gif: 'image/gif',
  jpg: 'image/jpeg',
  jpeg: 'image/jpeg',
  png: 'image/png',
  webp: 'image/webp'
}; // Unique list of mime types for the allowed static theme images.

exports.FILE_EXTENSIONS_TO_MIME = FILE_EXTENSIONS_TO_MIME;
const STATIC_THEME_IMAGE_MIMES = [...new Set(Object.values(FILE_EXTENSIONS_TO_MIME))]; // Mapping of "schema data paths" of the deprecated properties that we
// issue warnings for.
// If the value is `null` we will be using the `deprecated` message
// from the schema. Otherwise `code`, `message` and `description` will be taken
// from the object provided.
// Note that we have to use the constants name as we can't import
// the message object here.

exports.STATIC_THEME_IMAGE_MIMES = STATIC_THEME_IMAGE_MIMES;
const DEPRECATED_MANIFEST_PROPERTIES = {
  '/theme/images/headerURL': 'MANIFEST_THEME_LWT_ALIAS',
  '/theme/colors/accentcolor': 'MANIFEST_THEME_LWT_ALIAS',
  '/theme/colors/textcolor': 'MANIFEST_THEME_LWT_ALIAS'
}; // Mapping of deprecated javascript apis.
// If the value is `null` we will be using the `deprecated` message
// from the schema. Otherwise `code`, `message` and `description` will be taken
// from the object provided.
// Note that we have to use the constants name as we can't import
// the message object here.

exports.DEPRECATED_MANIFEST_PROPERTIES = DEPRECATED_MANIFEST_PROPERTIES;
const DEPRECATED_JAVASCRIPT_APIS = {
  // These APIs were already deprecated by Chrome and Firefox never
  // supported them. We do still issue deprecation warnings for them.
  'app.getDetails': 'DEPRECATED_CHROME_API',
  'extension.onRequest': 'DEPRECATED_CHROME_API',
  'extension.onRequestExternal': 'DEPRECATED_CHROME_API',
  'extension.sendRequest': 'DEPRECATED_CHROME_API',
  'tabs.getAllInWindow': 'DEPRECATED_CHROME_API',
  'tabs.getSelected': 'DEPRECATED_CHROME_API',
  'tabs.onActiveChanged': 'DEPRECATED_CHROME_API',
  'tabs.onSelectionChanged': 'DEPRECATED_CHROME_API',
  'tabs.sendRequest': 'DEPRECATED_CHROME_API',
  // https://github.com/mozilla/addons-linter/issues/2556
  'proxy.register': 'DEPRECATED_API',
  'proxy.unregister': 'DEPRECATED_API',
  'proxy.onProxyError': 'DEPRECATED_API',
  'proxy.registerProxyScript': 'DEPRECATED_API'
}; // A list of magic numbers that we won't allow.

exports.DEPRECATED_JAVASCRIPT_APIS = DEPRECATED_JAVASCRIPT_APIS;
const FLAGGED_FILE_MAGIC_NUMBERS = [[0x4d, 0x5a], // EXE or DLL,
[0x5a, 0x4d], // Alternative EXE or DLL
[0x7f, 0x45, 0x4c, 0x46], // UNIX elf
[0x23, 0x21], // Shell script
[0xca, 0xfe, 0xba, 0xbe], // Java + Mach-O (dylib)
[0xca, 0xfe, 0xd0, 0x0d], // Java packed
[0x43, 0x57, 0x53] // Compressed SWF
]; // These are APIs that will cause problems when loaded temporarily
// in about:debugging.
// APIs listed here should be defined in https://mzl.la/31p4AMc

exports.FLAGGED_FILE_MAGIC_NUMBERS = FLAGGED_FILE_MAGIC_NUMBERS;
const TEMPORARY_APIS = ['identity.getRedirectURL', 'storage.sync', 'storage.managed', 'runtime.onMessageExternal', 'runtime.onConnectExternal']; // All valid CSP keywords that are options to keys like `default-src` and
// `script-src`. Used in manifest.json parser for validation.
// See https://mzl.la/2vwqbGU for more details and allowed options.

exports.TEMPORARY_APIS = TEMPORARY_APIS;
const CSP_KEYWORD_RE = new RegExp(['(self|none|unsafe-inline|strict-dynamic|unsafe-hashed-attributes)', // Only match these keywords, anything else is forbidden
'(?!.)', '|(sha(256|384|512)-|nonce-)'].join(''));
exports.CSP_KEYWORD_RE = CSP_KEYWORD_RE;
const MESSAGES_JSON = 'messages.json';
exports.MESSAGES_JSON = MESSAGES_JSON;
const LOCALES_DIRECTORY = '_locales'; // This is a string, since it has to be matched globally on a message string.
// This should match
// https://searchfox.org/mozilla-central/rev/3abf6fa7e2a6d9a7bfb88796141b0f012e68c2db/toolkit/components/extensions/ExtensionCommon.jsm#1711

exports.LOCALES_DIRECTORY = LOCALES_DIRECTORY;
const MESSAGE_PLACEHOLDER_REGEXP = '\\$([a-zA-Z0-9_@]+)\\$'; // yauzl should trow error with this message in case of corrupt zip file

exports.MESSAGE_PLACEHOLDER_REGEXP = MESSAGE_PLACEHOLDER_REGEXP;
const ZIP_LIB_CORRUPT_FILE_ERROR = 'end of central directory record signature not found'; // URLs in this array are restricted from being used in the manifest.json "homepage_url" prperty

exports.ZIP_LIB_CORRUPT_FILE_ERROR = ZIP_LIB_CORRUPT_FILE_ERROR;
const RESTRICTED_HOMEPAGE_URLS = ['addons-dev.allizom.org', 'addons.mozilla.org'];
exports.RESTRICTED_HOMEPAGE_URLS = RESTRICTED_HOMEPAGE_URLS;

/***/ }),
/* 12 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {



Object.defineProperty(exports, "__esModule", ({
  value: true
}));
exports._nonLiteralUri = _nonLiteralUri;
exports._methodPassedRemoteUri = _methodPassedRemoteUri;
exports.ESLINT_OVERWRITE_MESSAGE = exports.ANDROID_INCOMPATIBLE_API = exports.INCOMPATIBLE_API = exports.RUNTIME_ONCONNECTEXTERNAL = exports.RUNTIME_ONMESSAGEEXTERNAL = exports.STORAGE_MANAGED = exports.IDENTITY_GETREDIRECTURL = exports.STORAGE_SYNC = exports.DEPRECATED_CHROME_API = exports.DEPRECATED_API = exports.REMOVED_MV2_API = exports.UNSUPPORTED_API = exports.UNSAFE_DYNAMIC_VARIABLE_ASSIGNMENT = exports.KNOWN_LIBRARY = exports.UNADVISED_LIBRARY = exports.BANNED_LIBRARY = exports.NO_DOCUMENT_WRITE = exports.UNEXPECTED_GLOGAL_ARG = exports.NO_IMPLIED_EVAL = exports.DANGEROUS_EVAL = exports.OPENDIALOG_NONLIT_URI = exports.OPENDIALOG_REMOTE_URI = exports.CONTENT_SCRIPT_EMPTY = exports.CONTENT_SCRIPT_NOT_FOUND = exports.EVENT_LISTENER_FOURTH = exports.JS_SYNTAX_ERROR = void 0;

var _commonTags = __webpack_require__(7);

var _utils = __webpack_require__(2);

const JS_SYNTAX_ERROR = {
  code: 'JS_SYNTAX_ERROR',
  message: _utils.i18n._('JavaScript syntax error'),
  description: _utils.i18n._((0, _commonTags.oneLine)`There is a JavaScript syntax error in your
    code, which might be related to some experimental JavaScript features that
    aren't an official part of the language specification and therefore not
    supported yet. The validation cannot continue on this file.`)
};
exports.JS_SYNTAX_ERROR = JS_SYNTAX_ERROR;
const EVENT_LISTENER_FOURTH = {
  code: 'EVENT_LISTENER_FOURTH',
  message: _utils.i18n._('addEventListener` called with truthy fourth argument.'),
  description: _utils.i18n._((0, _commonTags.oneLine)`When called with a truthy forth argument,
    listeners can be triggered potentially unsafely by untrusted code. This
    requires careful review.`)
};
exports.EVENT_LISTENER_FOURTH = EVENT_LISTENER_FOURTH;
const CONTENT_SCRIPT_NOT_FOUND = {
  code: 'CONTENT_SCRIPT_NOT_FOUND',
  legacyCode: null,
  message: _utils.i18n._('Content script file could not be found.'),
  description: _utils.i18n._('Content script file could not be found')
};
exports.CONTENT_SCRIPT_NOT_FOUND = CONTENT_SCRIPT_NOT_FOUND;
const CONTENT_SCRIPT_EMPTY = {
  code: 'CONTENT_SCRIPT_EMPTY',
  legacyCode: null,
  message: _utils.i18n._('Content script file name should not be empty.'),
  description: _utils.i18n._('Content script file name should not be empty')
};
exports.CONTENT_SCRIPT_EMPTY = CONTENT_SCRIPT_EMPTY;

function _nonLiteralUri(method) {
  return {
    code: `${method}_NONLIT_URI`.toUpperCase(),
    message: _utils.i18n._(`'${method}' called with a non-literal uri`),
    description: _utils.i18n._((0, _commonTags.oneLine)`Calling '${method}' with variable
      parameters can result in potential security vulnerabilities if the
      variable contains a remote URI. Consider using 'window.open' with
      the 'chrome=no' flag.`)
  };
}

function _methodPassedRemoteUri(method) {
  return {
    code: `${method}_REMOTE_URI`.toUpperCase(),
    message: _utils.i18n._(`'${method}' called with non-local URI`),
    description: _utils.i18n._((0, _commonTags.oneLine)`Calling '${method}' with a non-local
      URI will result in the dialog being opened with chrome privileges.`)
  };
}

const OPENDIALOG_REMOTE_URI = _methodPassedRemoteUri('openDialog');

exports.OPENDIALOG_REMOTE_URI = OPENDIALOG_REMOTE_URI;

const OPENDIALOG_NONLIT_URI = _nonLiteralUri('openDialog');

exports.OPENDIALOG_NONLIT_URI = OPENDIALOG_NONLIT_URI;
const DANGEROUS_EVAL = {
  code: 'DANGEROUS_EVAL',
  message: null,
  description: _utils.i18n._((0, _commonTags.oneLine)`Evaluation of strings as code can lead to
    security vulnerabilities and performance issues, even in the
    most innocuous of circumstances. Please avoid using \`eval\` and the
    \`Function\` constructor when at all possible.'`)
};
exports.DANGEROUS_EVAL = DANGEROUS_EVAL;
const NO_IMPLIED_EVAL = {
  code: 'NO_IMPLIED_EVAL',
  message: null,
  description: _utils.i18n._((0, _commonTags.oneLine)`setTimeout, setInterval and execScript
    functions should be called only with function expressions as their
    first argument`)
};
exports.NO_IMPLIED_EVAL = NO_IMPLIED_EVAL;
const UNEXPECTED_GLOGAL_ARG = {
  code: 'UNEXPECTED_GLOGAL_ARG',
  message: _utils.i18n._('Unexpected global passed as an argument'),
  description: _utils.i18n._((0, _commonTags.oneLine)`Passing a global as an argument
    is not recommended. Please make this a var instead.`)
};
exports.UNEXPECTED_GLOGAL_ARG = UNEXPECTED_GLOGAL_ARG;
const NO_DOCUMENT_WRITE = {
  code: 'NO_DOCUMENT_WRITE',
  message: _utils.i18n._('Use of document.write strongly discouraged.'),
  description: _utils.i18n._((0, _commonTags.oneLine)`document.write will fail in many
    circumstances when used in extensions, and has potentially severe security
    repercussions when used improperly. Therefore, it should not be used.`)
};
exports.NO_DOCUMENT_WRITE = NO_DOCUMENT_WRITE;
const BANNED_LIBRARY = {
  code: 'BANNED_LIBRARY',
  message: _utils.i18n._('Banned 3rd-party JS library'),
  description: _utils.i18n._((0, _commonTags.oneLine)`Your add-on uses a JavaScript library we
    consider unsafe. Read more: https://bit.ly/1TRIyZY`)
};
exports.BANNED_LIBRARY = BANNED_LIBRARY;
const UNADVISED_LIBRARY = {
  code: 'UNADVISED_LIBRARY',
  message: _utils.i18n._('Unadvised 3rd-party JS library'),
  description: _utils.i18n._((0, _commonTags.oneLine)`Your add-on uses a JavaScript library we do
    not recommend. Read more: https://bit.ly/1TRIyZY`)
};
exports.UNADVISED_LIBRARY = UNADVISED_LIBRARY;
const KNOWN_LIBRARY = {
  code: 'KNOWN_LIBRARY',
  message: _utils.i18n._('Known JS library detected'),
  description: _utils.i18n._((0, _commonTags.oneLine)`JavaScript libraries are discouraged for
    simple add-ons, but are generally accepted.`)
};
exports.KNOWN_LIBRARY = KNOWN_LIBRARY;
const UNSAFE_DYNAMIC_VARIABLE_ASSIGNMENT = {
  code: 'UNSAFE_VAR_ASSIGNMENT',
  // Uses original message from eslint
  message: null,
  description: _utils.i18n._((0, _commonTags.oneLine)`Due to both security and performance
    concerns, this may not be set using dynamic values which have
    not been adequately sanitized. This can lead to security issues or fairly
    serious performance degradation.`)
};
exports.UNSAFE_DYNAMIC_VARIABLE_ASSIGNMENT = UNSAFE_DYNAMIC_VARIABLE_ASSIGNMENT;
const UNSUPPORTED_API = {
  code: 'UNSUPPORTED_API',
  message: null,
  messageFormat: _utils.i18n._('{{api}} is not supported'),
  description: _utils.i18n._('This API has not been implemented by Firefox.')
};
exports.UNSUPPORTED_API = UNSUPPORTED_API;
const REMOVED_MV2_API = {
  code: 'UNSUPPORTED_API',
  message: null,
  messageFormat: _utils.i18n._('"{{api}}" has been removed in Manifest Version 3 (`manifest_version` property)'),
  description: null
};
exports.REMOVED_MV2_API = REMOVED_MV2_API;
const DEPRECATED_API = {
  code: 'DEPRECATED_API',
  message: null,
  messageFormat: _utils.i18n._('{{api}} is deprecated'),
  description: _utils.i18n._('This API has been deprecated by Firefox.')
};
exports.DEPRECATED_API = DEPRECATED_API;
const DEPRECATED_CHROME_API = {
  // We are re-using the same code here for consistency and for technical
  // reasons. We aren't really able to issue different codes from the same
  // rule, so until we have to, we're going to re-use the `DEPRECATED_API`
  // code.
  // Because of that implementation detail ``description`` isn't being usable
  // too.
  code: 'DEPRECATED_API',
  message: null,
  messageFormat: _utils.i18n._('"{{api}}" is deprecated or unimplemented'),
  description: null
};
exports.DEPRECATED_CHROME_API = DEPRECATED_CHROME_API;

function temporaryAPI(api) {
  return {
    code: (0, _utils.apiToMessage)(api),
    message: _utils.i18n._(`"${api}" can cause issues when loaded temporarily`),
    description: _utils.i18n._((0, _commonTags.oneLine)`This API can cause issues when loaded
      temporarily using about:debugging in Firefox unless you specify
      applications|browser_specific_settings > gecko > id in the manifest.
      Please see: https://mzl.la/2hizK4a for more.`)
  };
}

const STORAGE_SYNC = temporaryAPI('storage.sync');
exports.STORAGE_SYNC = STORAGE_SYNC;
const IDENTITY_GETREDIRECTURL = temporaryAPI('identity.getRedirectURL');
exports.IDENTITY_GETREDIRECTURL = IDENTITY_GETREDIRECTURL;
const STORAGE_MANAGED = temporaryAPI('storage.managed');
exports.STORAGE_MANAGED = STORAGE_MANAGED;
const RUNTIME_ONMESSAGEEXTERNAL = temporaryAPI('runtime.onMessageExternal');
exports.RUNTIME_ONMESSAGEEXTERNAL = RUNTIME_ONMESSAGEEXTERNAL;
const RUNTIME_ONCONNECTEXTERNAL = temporaryAPI('runtime.onConnectExternal');
exports.RUNTIME_ONCONNECTEXTERNAL = RUNTIME_ONCONNECTEXTERNAL;
const INCOMPATIBLE_API = {
  code: 'INCOMPATIBLE_API',
  message: null,
  messageFormat: _utils.i18n._('{{api}} is not supported in Firefox version {{minVersion}}'),
  description: _utils.i18n._('This API is not implemented by the given minimum Firefox version')
};
exports.INCOMPATIBLE_API = INCOMPATIBLE_API;
const ANDROID_INCOMPATIBLE_API = {
  code: 'ANDROID_INCOMPATIBLE_API',
  message: null,
  messageFormat: _utils.i18n._('{{api}} is not supported in Firefox for Android version {{minVersion}}'),
  description: _utils.i18n._('This API is not implemented by the given minimum Firefox for Android version')
};
exports.ANDROID_INCOMPATIBLE_API = ANDROID_INCOMPATIBLE_API;
const ESLINT_OVERWRITE_MESSAGE = {
  'no-eval': DANGEROUS_EVAL,
  'no-implied-eval': NO_IMPLIED_EVAL,
  'no-new-func': DANGEROUS_EVAL,
  'no-unsanitized/property': UNSAFE_DYNAMIC_VARIABLE_ASSIGNMENT,
  'no-unsanitized/method': UNSAFE_DYNAMIC_VARIABLE_ASSIGNMENT,
  'webextension-unsupported-api': UNSUPPORTED_API,
  'webextension-deprecated-api': DEPRECATED_API,
  'webextension-api-compat': INCOMPATIBLE_API,
  'webextension-api-compat-android': ANDROID_INCOMPATIBLE_API
};
exports.ESLINT_OVERWRITE_MESSAGE = ESLINT_OVERWRITE_MESSAGE;

/***/ })
/******/ 	]);
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
var exports = __webpack_exports__;


Object.defineProperty(exports, "__esModule", ({
  value: true
}));
exports.create = exports.default = void 0;

var path = _interopRequireWildcard(__webpack_require__(1));

var _utils = __webpack_require__(2);

var _javascript = __webpack_require__(12);

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

const rule = {
  create(context) {
    const existingFiles = Object.keys(context.settings.existingFiles || {}).map(fileName => {
      return path.resolve('/', fileName);
    });
    return {
      MemberExpression(node) {
        if (!node.object.object || !(0, _utils.isBrowserNamespace)(node.object.object.name)) {
          // Early return when it's not our case.
          return;
        }

        const namespace = node.object.property.name;
        const property = node.property.name; // Namespace should be tabs function should be executeScript and it should be a call.
        // I.E. browser.tabs.executeScript().

        if (namespace !== 'tabs' || property !== 'executeScript' || node.parent.type !== 'CallExpression') {
          return;
        }

        node.parent.arguments.forEach(arg => {
          // Skipping the argument if it's not an object.
          if (arg.type !== 'ObjectExpression') {
            return;
          }

          const fileProperty = arg.properties.find(prop => prop.key && prop.key.name === 'file');
          const fileValue = fileProperty && fileProperty.value && fileProperty.value.value; // Skipping the argument if there is no file property, or value is not a static string.

          if (!fileProperty || fileProperty.value.type !== 'Literal' || typeof fileValue !== 'string') {
            return;
          } // If filename is empty, report an issue.


          if (fileValue === '') {
            context.report({
              loc: fileProperty.value.loc,
              message: _javascript.CONTENT_SCRIPT_EMPTY.code
            });
            return;
          } // We can't reliably validate relative file names because they
          // are resolved as relative to the current page url on Firefox
          // and the rule itself doesn't know the path of the html file (or
          // files) where the js file is going to be loaded, and so we chose
          // to validate only the absolute file paths to avoid false positive.
          // (Also note that Firefox and Chrome behave differently when
          // resolving relative content script paths used in a tabs.executeScript API call).


          if (!path.isAbsolute(fileValue)) {
            return;
          }

          const normalizedName = path.resolve('/', path.normalize(fileValue)); // If file exists then we are good.

          if (existingFiles.includes(normalizedName)) {
            return;
          } // File not exists report an issue.


          context.report({
            loc: fileProperty.value.loc,
            message: _javascript.CONTENT_SCRIPT_NOT_FOUND.code
          });
        });
      }

    };
  }

};
var _default = rule;
exports.default = _default;
const {
  create
} = rule;
exports.create = create;
})();

module.exports = __webpack_exports__.default;
/******/ })()
;
//# sourceMappingURL=content-scripts-file-absent.js.map