isml-linter 5.39.3 → 5.39.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1167 -1159
- package/LICENSE +21 -21
- package/README.md +245 -245
- package/bin/isml-linter.js +32 -32
- package/ismllinter.config.js +33 -33
- package/package.json +53 -53
- package/scaffold_files/ismllinter.config.js +47 -47
- package/src/Builder.js +15 -15
- package/src/Constants.js +139 -139
- package/src/IsmlLinter.js +255 -255
- package/src/enums/ParseStatus.js +5 -5
- package/src/enums/SfccTagContainer.js +287 -287
- package/src/isml_tree/ContainerNode.js +38 -38
- package/src/isml_tree/IsmlNode.js +684 -684
- package/src/isml_tree/MaskUtils.js +421 -421
- package/src/isml_tree/ParseUtils.js +514 -506
- package/src/isml_tree/TreeBuilder.js +273 -273
- package/src/publicApi.js +24 -24
- package/src/rules/line_by_line/enforce-isprint.js +53 -53
- package/src/rules/line_by_line/enforce-require.js +35 -35
- package/src/rules/line_by_line/lowercase-filename.js +29 -29
- package/src/rules/line_by_line/max-lines.js +37 -37
- package/src/rules/line_by_line/no-br.js +36 -36
- package/src/rules/line_by_line/no-git-conflict.js +43 -43
- package/src/rules/line_by_line/no-import-package.js +34 -34
- package/src/rules/line_by_line/no-inline-style.js +34 -34
- package/src/rules/line_by_line/no-isscript.js +34 -34
- package/src/rules/line_by_line/no-space-only-lines.js +47 -47
- package/src/rules/line_by_line/no-tabs.js +38 -38
- package/src/rules/line_by_line/no-trailing-spaces.js +52 -52
- package/src/rules/prototypes/RulePrototype.js +79 -79
- package/src/rules/prototypes/SingleLineRulePrototype.js +47 -47
- package/src/rules/prototypes/TreeRulePrototype.js +84 -84
- package/src/rules/tree/align-isset.js +87 -87
- package/src/rules/tree/contextual-attrs.js +105 -105
- package/src/rules/tree/custom-tags.js +54 -54
- package/src/rules/tree/disallow-tags.js +39 -39
- package/src/rules/tree/empty-eof.js +66 -66
- package/src/rules/tree/enforce-security.js +85 -85
- package/src/rules/tree/eslint-to-isscript.js +179 -179
- package/src/rules/tree/indent.js +853 -853
- package/src/rules/tree/leading-iscache.js +39 -39
- package/src/rules/tree/leading-iscontent.js +35 -35
- package/src/rules/tree/max-depth.js +54 -54
- package/src/rules/tree/no-deprecated-attrs.js +67 -67
- package/src/rules/tree/no-embedded-isml.js +17 -17
- package/src/rules/tree/no-hardcode.js +51 -51
- package/src/rules/tree/no-iselse-slash.js +35 -35
- package/src/rules/tree/no-redundant-context.js +134 -134
- package/src/rules/tree/no-require-in-loop.js +63 -63
- package/src/rules/tree/one-element-per-line.js +76 -76
- package/src/util/CommandLineUtils.js +19 -19
- package/src/util/ConfigUtils.js +219 -219
- package/src/util/ConsoleUtils.js +327 -327
- package/src/util/CustomTagContainer.js +45 -45
- package/src/util/ExceptionUtils.js +149 -149
- package/src/util/FileUtils.js +79 -79
- package/src/util/GeneralUtils.js +60 -60
- package/src/util/NativeExtensionUtils.js +6 -6
- package/src/util/RuleUtils.js +295 -295
- package/src/util/TempRuleUtils.js +232 -232
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
2
|
-
const ConfigUtils = require('../../../src/util/ConfigUtils');
|
|
3
|
-
|
|
4
|
-
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
5
|
-
const description = 'Tag not allowed';
|
|
6
|
-
|
|
7
|
-
const Rule = Object.create(TreeRulePrototype);
|
|
8
|
-
|
|
9
|
-
const config = ConfigUtils.load();
|
|
10
|
-
const disallowedTagList = config.rules['disallow-tags'] ?
|
|
11
|
-
config.rules['disallow-tags'].values || [] :
|
|
12
|
-
[];
|
|
13
|
-
|
|
14
|
-
Rule.init(ruleId, description);
|
|
15
|
-
|
|
16
|
-
Rule.isBroken = function(node) {
|
|
17
|
-
return disallowedTagList.indexOf(node.getType()) >= 0;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
Rule.check = function(node, data) {
|
|
21
|
-
const occurrenceList = this.checkChildren(node, data);
|
|
22
|
-
|
|
23
|
-
if (this.isBroken(node)) {
|
|
24
|
-
const error = this.getError(
|
|
25
|
-
node.head.trim(),
|
|
26
|
-
node.lineNumber,
|
|
27
|
-
node.columnNumber,
|
|
28
|
-
node.globalPos,
|
|
29
|
-
node.head.trim().length,
|
|
30
|
-
`Tag "${node.getType()}" is not allowed.`
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
occurrenceList.push(error);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return this.return(node, occurrenceList, config);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
module.exports = Rule;
|
|
1
|
+
const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
2
|
+
const ConfigUtils = require('../../../src/util/ConfigUtils');
|
|
3
|
+
|
|
4
|
+
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
5
|
+
const description = 'Tag not allowed';
|
|
6
|
+
|
|
7
|
+
const Rule = Object.create(TreeRulePrototype);
|
|
8
|
+
|
|
9
|
+
const config = ConfigUtils.load();
|
|
10
|
+
const disallowedTagList = config.rules['disallow-tags'] ?
|
|
11
|
+
config.rules['disallow-tags'].values || [] :
|
|
12
|
+
[];
|
|
13
|
+
|
|
14
|
+
Rule.init(ruleId, description);
|
|
15
|
+
|
|
16
|
+
Rule.isBroken = function(node) {
|
|
17
|
+
return disallowedTagList.indexOf(node.getType()) >= 0;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
Rule.check = function(node, data) {
|
|
21
|
+
const occurrenceList = this.checkChildren(node, data);
|
|
22
|
+
|
|
23
|
+
if (this.isBroken(node)) {
|
|
24
|
+
const error = this.getError(
|
|
25
|
+
node.head.trim(),
|
|
26
|
+
node.lineNumber,
|
|
27
|
+
node.columnNumber,
|
|
28
|
+
node.globalPos,
|
|
29
|
+
node.head.trim().length,
|
|
30
|
+
`Tag "${node.getType()}" is not allowed.`
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
occurrenceList.push(error);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return this.return(node, occurrenceList, config);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
module.exports = Rule;
|
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
2
|
-
const Constants = require('../../Constants');
|
|
3
|
-
const ParseUtils = require('../../isml_tree/ParseUtils');
|
|
4
|
-
|
|
5
|
-
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
6
|
-
const description = 'A blank line at the end of the file is required';
|
|
7
|
-
|
|
8
|
-
const Rule = Object.create(TreeRulePrototype);
|
|
9
|
-
|
|
10
|
-
Rule.init(ruleId, description);
|
|
11
|
-
|
|
12
|
-
Rule.isBroken = function(node) {
|
|
13
|
-
const tempNode = node.isContainer() ? node.getLastChild() : node;
|
|
14
|
-
|
|
15
|
-
return !(tempNode.tail ?
|
|
16
|
-
tempNode.tail.endsWith(Constants.EOL) :
|
|
17
|
-
tempNode.head.endsWith(Constants.EOL));
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
Rule.check = function(rootNode, data) {
|
|
21
|
-
|
|
22
|
-
const occurrenceList = [];
|
|
23
|
-
|
|
24
|
-
const node = rootNode.getLastChild();
|
|
25
|
-
|
|
26
|
-
if (this.isBroken(node)) {
|
|
27
|
-
const lineContent = node.toString().substring(node.toString().lastIndexOf(Constants.EOL) + 1);
|
|
28
|
-
const lineBreakQty = ParseUtils.getLineBreakQty(node.toString());
|
|
29
|
-
const lineNumber = node.lineNumber + lineBreakQty - 1;
|
|
30
|
-
let globalPos = node.globalPos;
|
|
31
|
-
let length = node.head.trim().length;
|
|
32
|
-
|
|
33
|
-
if (node.tail) {
|
|
34
|
-
const lastLineBreakPos = node.tail.lastIndexOf(Constants.EOL);
|
|
35
|
-
const trailingSpaces = node.tail.substring(lastLineBreakPos + 1);
|
|
36
|
-
|
|
37
|
-
if (trailingSpaces.length > 0) {
|
|
38
|
-
globalPos = node.tailGlobalPos + node.tail.trim().length + 1;
|
|
39
|
-
length = trailingSpaces.length;
|
|
40
|
-
|
|
41
|
-
if (data.isCrlfLineBreak) {
|
|
42
|
-
globalPos += ParseUtils.getLineBreakQty(node.tail.trimStart());
|
|
43
|
-
}
|
|
44
|
-
} else {
|
|
45
|
-
globalPos = node.tailGlobalPos + 1;
|
|
46
|
-
length = node.tail.trim().length;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const error = this.getError(
|
|
51
|
-
lineContent,
|
|
52
|
-
lineNumber,
|
|
53
|
-
node.columnNumber,
|
|
54
|
-
globalPos,
|
|
55
|
-
length
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
occurrenceList.push(error);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
occurrenceList
|
|
63
|
-
};
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
module.exports = Rule;
|
|
1
|
+
const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
2
|
+
const Constants = require('../../Constants');
|
|
3
|
+
const ParseUtils = require('../../isml_tree/ParseUtils');
|
|
4
|
+
|
|
5
|
+
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
6
|
+
const description = 'A blank line at the end of the file is required';
|
|
7
|
+
|
|
8
|
+
const Rule = Object.create(TreeRulePrototype);
|
|
9
|
+
|
|
10
|
+
Rule.init(ruleId, description);
|
|
11
|
+
|
|
12
|
+
Rule.isBroken = function(node) {
|
|
13
|
+
const tempNode = node.isContainer() ? node.getLastChild() : node;
|
|
14
|
+
|
|
15
|
+
return !(tempNode.tail ?
|
|
16
|
+
tempNode.tail.endsWith(Constants.EOL) :
|
|
17
|
+
tempNode.head.endsWith(Constants.EOL));
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
Rule.check = function(rootNode, data) {
|
|
21
|
+
|
|
22
|
+
const occurrenceList = [];
|
|
23
|
+
|
|
24
|
+
const node = rootNode.getLastChild();
|
|
25
|
+
|
|
26
|
+
if (this.isBroken(node)) {
|
|
27
|
+
const lineContent = node.toString().substring(node.toString().lastIndexOf(Constants.EOL) + 1);
|
|
28
|
+
const lineBreakQty = ParseUtils.getLineBreakQty(node.toString());
|
|
29
|
+
const lineNumber = node.isContainer() ? node.getLastChild().tailEndLineNumber : node.lineNumber + lineBreakQty - 1;
|
|
30
|
+
let globalPos = node.globalPos;
|
|
31
|
+
let length = node.head.trim().length;
|
|
32
|
+
|
|
33
|
+
if (node.tail) {
|
|
34
|
+
const lastLineBreakPos = node.tail.lastIndexOf(Constants.EOL);
|
|
35
|
+
const trailingSpaces = node.tail.substring(lastLineBreakPos + 1);
|
|
36
|
+
|
|
37
|
+
if (trailingSpaces.length > 0) {
|
|
38
|
+
globalPos = node.tailGlobalPos + node.tail.trim().length + 1;
|
|
39
|
+
length = trailingSpaces.length;
|
|
40
|
+
|
|
41
|
+
if (data.isCrlfLineBreak) {
|
|
42
|
+
globalPos += ParseUtils.getLineBreakQty(node.tail.trimStart());
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
globalPos = node.tailGlobalPos + 1;
|
|
46
|
+
length = node.tail.trim().length;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const error = this.getError(
|
|
51
|
+
lineContent,
|
|
52
|
+
lineNumber,
|
|
53
|
+
node.columnNumber,
|
|
54
|
+
globalPos,
|
|
55
|
+
length
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
occurrenceList.push(error);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
occurrenceList
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
module.exports = Rule;
|
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
2
|
-
const ConfigUtils = require('../../util/ConfigUtils');
|
|
3
|
-
|
|
4
|
-
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
5
|
-
const description = 'This code introduces a security risk';
|
|
6
|
-
|
|
7
|
-
const Rule = Object.create(TreeRulePrototype);
|
|
8
|
-
|
|
9
|
-
// Rule options;
|
|
10
|
-
const REVERSE_TABNABBING = 'prevent-reverse-tabnabbing';
|
|
11
|
-
|
|
12
|
-
Rule.init(ruleId, description);
|
|
13
|
-
|
|
14
|
-
Rule.getDefaultAttrs = () => {
|
|
15
|
-
const result = {};
|
|
16
|
-
|
|
17
|
-
result[REVERSE_TABNABBING] = true;
|
|
18
|
-
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
Rule.isBroken = function(node) {
|
|
23
|
-
const config = this.getConfigs();
|
|
24
|
-
const errorList = [];
|
|
25
|
-
|
|
26
|
-
if (config[REVERSE_TABNABBING]) {
|
|
27
|
-
const tabNabbingResult = checkReverseTabNabbing(node);
|
|
28
|
-
|
|
29
|
-
if (tabNabbingResult) {
|
|
30
|
-
errorList.push(tabNabbingResult);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return errorList;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
Rule.check = function(node, data) {
|
|
38
|
-
|
|
39
|
-
const config = ConfigUtils.load();
|
|
40
|
-
const occurrenceList = this.checkChildren(node, data);
|
|
41
|
-
const errorMessageList = this.isBroken(node);
|
|
42
|
-
|
|
43
|
-
for (let i = 0; i < errorMessageList.length; i++) {
|
|
44
|
-
const error = this.getError(
|
|
45
|
-
node.head.trim(),
|
|
46
|
-
node.lineNumber,
|
|
47
|
-
node.columnNumber,
|
|
48
|
-
node.globalPos,
|
|
49
|
-
node.head.trim().length,
|
|
50
|
-
errorMessageList[i]
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
occurrenceList.push(error);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return this.return(node, occurrenceList, config);
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const checkReverseTabNabbing = node => {
|
|
60
|
-
if (node.isOfType('a')) {
|
|
61
|
-
const attributeList = node.getAttributeList();
|
|
62
|
-
let hasTargetBlankAttribute = false;
|
|
63
|
-
let hasRelNoOpenerAttribute = false;
|
|
64
|
-
|
|
65
|
-
for (let i = 0; i < attributeList.length; i++) {
|
|
66
|
-
const attribute = attributeList[i];
|
|
67
|
-
|
|
68
|
-
if (attribute.name === 'target' && attribute.value === '_blank') {
|
|
69
|
-
hasTargetBlankAttribute = true;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (attribute.name === 'rel' && attribute.value.indexOf('noopener') >= 0) {
|
|
73
|
-
hasRelNoOpenerAttribute = true;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (hasTargetBlankAttribute && !hasRelNoOpenerAttribute) {
|
|
78
|
-
return 'Potential reverse tabnabbing security hole detected. Consider adding \'rel="noopener"\'';
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return null;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
module.exports = Rule;
|
|
1
|
+
const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
2
|
+
const ConfigUtils = require('../../util/ConfigUtils');
|
|
3
|
+
|
|
4
|
+
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
5
|
+
const description = 'This code introduces a security risk';
|
|
6
|
+
|
|
7
|
+
const Rule = Object.create(TreeRulePrototype);
|
|
8
|
+
|
|
9
|
+
// Rule options;
|
|
10
|
+
const REVERSE_TABNABBING = 'prevent-reverse-tabnabbing';
|
|
11
|
+
|
|
12
|
+
Rule.init(ruleId, description);
|
|
13
|
+
|
|
14
|
+
Rule.getDefaultAttrs = () => {
|
|
15
|
+
const result = {};
|
|
16
|
+
|
|
17
|
+
result[REVERSE_TABNABBING] = true;
|
|
18
|
+
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
Rule.isBroken = function(node) {
|
|
23
|
+
const config = this.getConfigs();
|
|
24
|
+
const errorList = [];
|
|
25
|
+
|
|
26
|
+
if (config[REVERSE_TABNABBING]) {
|
|
27
|
+
const tabNabbingResult = checkReverseTabNabbing(node);
|
|
28
|
+
|
|
29
|
+
if (tabNabbingResult) {
|
|
30
|
+
errorList.push(tabNabbingResult);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return errorList;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
Rule.check = function(node, data) {
|
|
38
|
+
|
|
39
|
+
const config = ConfigUtils.load();
|
|
40
|
+
const occurrenceList = this.checkChildren(node, data);
|
|
41
|
+
const errorMessageList = this.isBroken(node);
|
|
42
|
+
|
|
43
|
+
for (let i = 0; i < errorMessageList.length; i++) {
|
|
44
|
+
const error = this.getError(
|
|
45
|
+
node.head.trim(),
|
|
46
|
+
node.lineNumber,
|
|
47
|
+
node.columnNumber,
|
|
48
|
+
node.globalPos,
|
|
49
|
+
node.head.trim().length,
|
|
50
|
+
errorMessageList[i]
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
occurrenceList.push(error);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return this.return(node, occurrenceList, config);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const checkReverseTabNabbing = node => {
|
|
60
|
+
if (node.isOfType('a')) {
|
|
61
|
+
const attributeList = node.getAttributeList();
|
|
62
|
+
let hasTargetBlankAttribute = false;
|
|
63
|
+
let hasRelNoOpenerAttribute = false;
|
|
64
|
+
|
|
65
|
+
for (let i = 0; i < attributeList.length; i++) {
|
|
66
|
+
const attribute = attributeList[i];
|
|
67
|
+
|
|
68
|
+
if (attribute.name === 'target' && attribute.value === '_blank') {
|
|
69
|
+
hasTargetBlankAttribute = true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (attribute.name === 'rel' && attribute.value.indexOf('noopener') >= 0) {
|
|
73
|
+
hasRelNoOpenerAttribute = true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (hasTargetBlankAttribute && !hasRelNoOpenerAttribute) {
|
|
78
|
+
return 'Potential reverse tabnabbing security hole detected. Consider adding \'rel="noopener"\'';
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return null;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
module.exports = Rule;
|