Skip to content

Commit

Permalink
feat: detect API and manifest key incompatibilities with strict_min_v…
Browse files Browse the repository at this point in the history
…ersion (mozilla#1493)
  • Loading branch information
freaktechnik committed Dec 5, 2018
1 parent 15b841f commit b20cc6e
Show file tree
Hide file tree
Showing 15 changed files with 587 additions and 54 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ Dependencies are automatically kept up-to-date using [greenkeeper](http://greenk
| npm run test-coverage-once | Runs the tests once with coverage |
| npm run test-integration-linter | Runs our integration test-suite |
| npm run prettier | Automatically format the whole code-base with Prettier |
| npm run prettier-dev | Automatically compare and format modified source files against the master branch |
| npm run prettier-dev | Automatically compare and format modified source files against the master branch |

### Building

Expand Down
4 changes: 2 additions & 2 deletions docs/import-firefox-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ And import the schema.

## Things to check for further updates

* Review the schema update carefully and see if there are any updates that require additional linting / warning from the linter (e.g properties that are meant for internal add-ons and shouldn't be used by regular add-ons, ask around if unsure)
* Check for custom format validations in ``src/schema/formats.js`` and update accordingly with upstream code (e.g ``manifestShortcutKey``)
- Review the schema update carefully and see if there are any updates that require additional linting / warning from the linter (e.g properties that are meant for internal add-ons and shouldn't be used by regular add-ons, ask around if unsure)
- Check for custom format validations in `src/schema/formats.js` and update accordingly with upstream code (e.g `manifestShortcutKey`)
100 changes: 52 additions & 48 deletions docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,22 @@ Rules are sorted by severity.

## Content

| Message code | Severity | Description |
| -------------- | -------- | ---------------------- |
| `HIDDEN_FILE` | warning | Hidden file flagged. |
| Message code | Severity | Description |
| -------------- | -------- | ----------------------- |
| `HIDDEN_FILE` | warning | Hidden file flagged. |
| `FLAGGED_FILE` | warning | Flagged filename found. |

## Package layout

| Message code | Severity | Description |
| -------------------------- | -------- | --------------------------------------------------- |
| `MOZILLA_COND_OF_USE` | notice | Mozilla conditions of use violation. |
| `FLAGGED_FILE_TYPE` | notice | (Binary) Flagged file type found. |
| `FLAGGED_FILE_EXTENSION` | warning | Flagged file extensions found |
| `FLAGGED_FILE_TYPE` | notice | (Binary) Flagged file type found. |
| `FLAGGED_FILE_EXTENSION` | warning | Flagged file extensions found |
| `DUPLICATE_XPI_ENTRY` | warning | Package contains duplicate entries |
| `ALREADY_SIGNED` | warning | Already signed |
| `COINMINER_USAGE_DETECTED` | warning | Firefox add-ons are not allowed to run coin miners. |
| `BAD_ZIPFILE` | error | Bad zip file |
| `BAD_ZIPFILE` | error | Bad zip file |
| `FILE_TOO_LARGE` | error | File is too large to parse |

## Type detection
Expand All @@ -75,52 +75,56 @@ Rules are sorted by severity.

## Language packs

| Message code | Severity | Description |
| -------------- | -------- | --------------------------- |
| Message code | Severity | Description |
| -------------- | -------- | ----------------------------- |
| FLUENT_INVALID | warning | Invalid fluent template file. |

## Web Extensions / manifest.json

| Message code | Severity | Description |
| --------------------------- | -------- | -------------------------------------------------------------------- |
| `MANIFEST_UNUSED_UPDATE` | notice | update_url ignored in manifest.json |
| `PROP_VERSION_TOOLKIT_ONLY` | notice | version is in the toolkit format in manifest.json |
| `CORRUPT_ICON_FILE` | warning | Icons must not be corrupt |
| `MANIFEST_CSP` | warning | content_security_policy in manifest.json means more review |
| `MANIFEST_CSP_UNSAFE_EVAL` | warning | usage of 'unsafe-eval' is strongly discouraged |
| `MANIFEST_PERMISSIONS` | warning | Unknown permission |
| `NO_MESSAGES_FILE` | warning | When default_locale is specified a matching messages.json must exist |
| `NO_DEFAULT_LOCALE` | warning | When \_locales directory exists, default_locale must exist |
| `UNSAFE_VAR_ASSIGNMENT` | warning | Assignment using dynamic, unsanitized values |
| `UNSUPPORTED_API` | warning | Unsupported or unknown browser API |
| `DANGEROUS_EVAL` | warning | `eval` and the `Function` constructor are discouraged |
| `STRICT_MAX_VERSION` | warning | strict_max_version not required |
| `PREDEFINED_MESSAGE_NAME` | warning | String name is reserved for a predefined |
| `MISSING_PLACEHOLDER` | warning | Placeholder for message is not |
| `WRONG_ICON_EXTENSION` | error | Icons must have valid extension |
| `MANIFEST_UPDATE_URL` | error | update_url not allowed in manifest.json |
| `MANIFEST_FIELD_REQUIRED` | error | A required field is missing |
| `MANIFEST_FIELD_INVALID` | error | A field is invalid |
| `MANIFEST_BAD_PERMISSION` | error | Bad permission |
| `JSON_BLOCK_COMMENTS` | error | Block Comments are not allowed in JSON |
| `MANIFEST_INVALID_CONTENT` | error | This add-on contains forbidden content |
| `CONTENT_SCRIPT_NOT_FOUND` | error | Content script file could not be found |
| `CONTENT_SCRIPT_EMPTY` | error | Content script file name should not be empty |
| `NO_MESSAGE` | error | Translation string is missing the message |
| `INVALID_MESSAGE_NAME` | error | String name contains invalid characters |
| `INVALID_PLACEHOLDER_NAME` | error | Placeholder name contains invalid characters |
| `NO_PLACEHOLDER_CONTENT` | error | Placeholder is missing the content |
| `JSON_INVALID` | error | JSON is not well formed |
| `JSON_DUPLICATE_KEY` | error | Duplicate key in JSON |
| `MANIFEST_VERSION_INVALID` | error | manifest_version in manifest.json is not valid. |
| `PROP_NAME_MISSING` | error | name property missing from manifest.json |
| `PROP_NAME_INVALID` | error | name property is invalid in manifest.json |
| `PROP_VERSION_MISSING` | error | version property missing from manifest.json |
| `PROP_VERSION_INVALID` | error | version is invalid in manifest.json |
| `MANIFEST_DICT_NOT_FOUND` | error | A dictionary file defined in the manifest could not be found |
| `MANIFEST_MULTIPLE_DICTS` | error | Multiple dictionaries found |
| `MANIFEST_EMPTY_DICTS` | error | Empty `dictionaries` object |
| `MANIFEST_DICT_MISSING_ID` | error | Missing `applications.gecko.id` property for a dictionary |
| Message code | Severity | Description |
| ------------------------------------------------ | -------- | ----------------------------------------------------------------------------------------------- |
| `MANIFEST_UNUSED_UPDATE` | notice | update_url ignored in manifest.json |
| `PROP_VERSION_TOOLKIT_ONLY` | notice | version is in the toolkit format in manifest.json |
| `CORRUPT_ICON_FILE` | warning | Icons must not be corrupt |
| `MANIFEST_CSP` | warning | content_security_policy in manifest.json means more review |
| `MANIFEST_CSP_UNSAFE_EVAL` | warning | usage of 'unsafe-eval' is strongly discouraged |
| `MANIFEST_PERMISSIONS` | warning | Unknown permission |
| `NO_MESSAGES_FILE` | warning | When default_locale is specified a matching messages.json must exist |
| `NO_DEFAULT_LOCALE` | warning | When \_locales directory exists, default_locale must exist |
| `UNSAFE_VAR_ASSIGNMENT` | warning | Assignment using dynamic, unsanitized values |
| `UNSUPPORTED_API` | warning | Unsupported or unknown browser API |
| `DANGEROUS_EVAL` | warning | `eval` and the `Function` constructor are discouraged |
| `STRICT_MAX_VERSION` | warning | strict_max_version not required |
| `PREDEFINED_MESSAGE_NAME` | warning | String name is reserved for a predefined |
| `MISSING_PLACEHOLDER` | warning | Placeholder for message is not |
| `WRONG_ICON_EXTENSION` | error | Icons must have valid extension |
| `MANIFEST_UPDATE_URL` | error | update_url not allowed in manifest.json |
| `MANIFEST_FIELD_REQUIRED` | error | A required field is missing |
| `MANIFEST_FIELD_INVALID` | error | A field is invalid |
| `MANIFEST_BAD_PERMISSION` | error | Bad permission |
| `JSON_BLOCK_COMMENTS` | error | Block Comments are not allowed in JSON |
| `MANIFEST_INVALID_CONTENT` | error | This add-on contains forbidden content |
| `CONTENT_SCRIPT_NOT_FOUND` | error | Content script file could not be found |
| `CONTENT_SCRIPT_EMPTY` | error | Content script file name should not be empty |
| `NO_MESSAGE` | error | Translation string is missing the message |
| `INVALID_MESSAGE_NAME` | error | String name contains invalid characters |
| `INVALID_PLACEHOLDER_NAME` | error | Placeholder name contains invalid characters |
| `NO_PLACEHOLDER_CONTENT` | error | Placeholder is missing the content |
| `JSON_INVALID` | error | JSON is not well formed |
| `JSON_DUPLICATE_KEY` | error | Duplicate key in JSON |
| `MANIFEST_VERSION_INVALID` | error | manifest_version in manifest.json is not valid. |
| `PROP_NAME_MISSING` | error | name property missing from manifest.json |
| `PROP_NAME_INVALID` | error | name property is invalid in manifest.json |
| `PROP_VERSION_MISSING` | error | version property missing from manifest.json |
| `PROP_VERSION_INVALID` | error | version is invalid in manifest.json |
| `MANIFEST_DICT_NOT_FOUND` | error | A dictionary file defined in the manifest could not be found |
| `MANIFEST_MULTIPLE_DICTS` | error | Multiple dictionaries found |
| `MANIFEST_EMPTY_DICTS` | error | Empty `dictionaries` object |
| `MANIFEST_DICT_MISSING_ID` | error | Missing `applications.gecko.id` property for a dictionary |
| `INCOMPATIBLE_API` | warning | API not compatible with `applications.gecko.strict_min_version` |
| `ANDROID_INCOMPATIBLE_API` | warning | API not compatible with Firefox for Android at `applications.gecko.strict_min_version` |
| `KEY_FIREFOX_UNSUPPORTED_BY_MIN_VERSION` | warning | Manifest key not compatible with `applications.gecko.strict_min_version` |
| `KEY_FIREFOX_ANDROID_UNSUPPORTED_BY_MIN_VERSION` | warning | Manifest key not compatible with Firefox for Android at `applications.gecko.strict_min_version` |

### Static Theme / manifest.json

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"glob": "7.1.3",
"is-mergeable-object": "1.1.0",
"jed": "1.1.1",
"mdn-browser-compat-data": "0.0.58",
"os-locale": "3.0.1",
"pino": "5.9.0",
"po2json": "0.4.5",
Expand Down
2 changes: 2 additions & 0 deletions src/const.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export const ESLINT_RULE_MAPPING = Object.assign(
'webextension-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
);
Expand Down
24 changes: 24 additions & 0 deletions src/messages/javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,34 @@ export const STORAGE_LOCAL = temporaryAPI('storage.local');
export const STORAGE_SYNC = temporaryAPI('storage.sync');
export const IDENTITY_GETREDIRECTURL = temporaryAPI('identity.getRedirectURL');

export const INCOMPATIBLE_API = {
code: 'INCOMPATIBLE_API',
message: null,
messageFormat: i18n._(
'{{api}} is not supported in Firefox version {{minVersion}}'
),
description: i18n._(
'This API is not implemented by the given minimum Firefox version'
),
};

export const ANDROID_INCOMPATIBLE_API = {
code: 'ANDROID_INCOMPATIBLE_API',
message: null,
messageFormat: i18n._(
'{{api}} is not supported in Firefox for Android version {{minVersion}}'
),
description: i18n._(
'This API is not implemented by the given minimum Firefox for Android version'
),
};

export const ESLINT_OVERWRITE_MESSAGE = {
'no-eval': DANGEROUS_EVAL,
'no-implied-eval': NO_IMPLIED_EVAL,
'no-new-func': DANGEROUS_EVAL,
'no-unsafe-innerhtml/no-unsafe-innerhtml': UNSAFE_DYNAMIC_VARIABLE_ASSIGNMENT,
'webextension-unsupported-api': UNSUPPORTED_API,
'webextension-api-compat': INCOMPATIBLE_API,
'webextension-api-compat-android': ANDROID_INCOMPATIBLE_API,
};
44 changes: 44 additions & 0 deletions src/messages/manifestjson.js
Original file line number Diff line number Diff line change
Expand Up @@ -418,3 +418,47 @@ export function noMessagesFileInLocales(path) {
file: MANIFEST_JSON,
};
}

export const KEY_FIREFOX_UNSUPPORTED_BY_MIN_VERSION =
'KEY_FIREFOX_UNSUPPORTED_BY_MIN_VERSION';
export function keyFirefoxUnsupportedByMinVersion(
key,
minVersion,
versionAdded
) {
return {
code: KEY_FIREFOX_UNSUPPORTED_BY_MIN_VERSION,
message: i18n._(
'Manifest key not supported by the specified minimum Firefox version'
),
description: i18n.sprintf(
i18n._(
'"strict_min_version" requires Firefox %(minVersion)s, which was released before version %(versionAdded)s introduced support for "%(key)s".'
),
{ key, minVersion, versionAdded }
),
file: MANIFEST_JSON,
};
}

export const KEY_FIREFOX_ANDROID_UNSUPPORTED_BY_MIN_VERSION =
'KEY_FIREFOX_ANDROID_UNSUPPORTED_BY_MIN_VERSION';
export function keyFirefoxAndroidUnsupportedByMinVersion(
key,
minVersion,
versionAdded
) {
return {
code: KEY_FIREFOX_ANDROID_UNSUPPORTED_BY_MIN_VERSION,
message: i18n._(
'Manifest key not supported by the specified minimum Firefox version'
),
description: i18n.sprintf(
i18n._(
'"strict_min_version" requires Firefox for Android %(minVersion)s, which was released before version %(versionAdded)s introduced support for "%(key)s".'
),
{ key, minVersion, versionAdded }
),
file: MANIFEST_JSON,
};
}
Loading

0 comments on commit b20cc6e

Please sign in to comment.