@abaplint/core 2.79.33 → 2.79.34
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/build/abaplint.d.ts +5 -0
- package/build/src/abap/2_statements/expressions/find_type.js +12 -0
- package/build/src/abap/2_statements/expressions/index.js +1 -0
- package/build/src/abap/2_statements/statements/find.js +1 -2
- package/build/src/abap/2_statements/statements/replace.js +1 -2
- package/build/src/registry.js +1 -1
- package/build/src/rules/dangerous_statement.js +24 -0
- package/build/src/rules/obsolete_statement.js +2 -3
- package/package.json +2 -2
package/build/abaplint.d.ts
CHANGED
|
@@ -1655,6 +1655,7 @@ declare namespace Expressions {
|
|
|
1655
1655
|
ClassGlobal_2 as ClassGlobal,
|
|
1656
1656
|
ClassName,
|
|
1657
1657
|
Color,
|
|
1658
|
+
FindType,
|
|
1658
1659
|
CompareOperator,
|
|
1659
1660
|
Compare,
|
|
1660
1661
|
ComponentChainSimple,
|
|
@@ -1915,6 +1916,10 @@ declare class Find implements IStatement {
|
|
|
1915
1916
|
getMatcher(): IStatementRunnable;
|
|
1916
1917
|
}
|
|
1917
1918
|
|
|
1919
|
+
declare class FindType extends Expression {
|
|
1920
|
+
getRunnable(): IStatementRunnable;
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1918
1923
|
declare class FloatingPointType extends AbstractType {
|
|
1919
1924
|
private readonly length;
|
|
1920
1925
|
constructor(length: number, qualifiedName?: string);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FindType = void 0;
|
|
4
|
+
const version_1 = require("../../../version");
|
|
5
|
+
const combi_1 = require("../combi");
|
|
6
|
+
class FindType extends combi_1.Expression {
|
|
7
|
+
getRunnable() {
|
|
8
|
+
return (0, combi_1.opt)((0, combi_1.alt)("REGEX", "SUBSTRING", (0, combi_1.ver)(version_1.Version.v755, "PCRE")));
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.FindType = FindType;
|
|
12
|
+
//# sourceMappingURL=find_type.js.map
|
|
@@ -27,6 +27,7 @@ __exportStar(require("./class_friends"), exports);
|
|
|
27
27
|
__exportStar(require("./class_global"), exports);
|
|
28
28
|
__exportStar(require("./class_name"), exports);
|
|
29
29
|
__exportStar(require("./color"), exports);
|
|
30
|
+
__exportStar(require("./find_type"), exports);
|
|
30
31
|
__exportStar(require("./compare_operator"), exports);
|
|
31
32
|
__exportStar(require("./compare"), exports);
|
|
32
33
|
__exportStar(require("./component_chain_simple"), exports);
|
|
@@ -3,14 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Find = void 0;
|
|
4
4
|
const combi_1 = require("../combi");
|
|
5
5
|
const expressions_1 = require("../expressions");
|
|
6
|
-
const version_1 = require("../../../version");
|
|
7
6
|
class Find {
|
|
8
7
|
getMatcher() {
|
|
9
8
|
// SUBMATCHES handling is a workaround
|
|
10
9
|
const options = (0, combi_1.per)("IGNORING CASE", "RESPECTING CASE", "IN BYTE MODE", "IN CHARACTER MODE", (0, combi_1.seq)("OF", expressions_1.Source), (0, combi_1.seq)("FROM", expressions_1.Source), (0, combi_1.seq)("TO", expressions_1.Source), (0, combi_1.seq)("MATCH OFFSET", expressions_1.Target), (0, combi_1.seq)("MATCH LINE", expressions_1.Target), (0, combi_1.seq)("MATCH COUNT", expressions_1.Target), (0, combi_1.seq)("MATCH LENGTH", expressions_1.Target), (0, combi_1.seq)("LENGTH", expressions_1.Source), (0, combi_1.seq)("RESULTS", expressions_1.Target), (0, combi_1.seq)("SUBMATCHES", expressions_1.Target), (0, combi_1.seq)("SUBMATCHES", expressions_1.Target, expressions_1.Target), (0, combi_1.seq)("SUBMATCHES", (0, combi_1.plus)(expressions_1.Target)));
|
|
11
10
|
const sectionLength = (0, combi_1.seq)("SECTION LENGTH", expressions_1.Source, "OF");
|
|
12
11
|
const before = (0, combi_1.seq)((0, combi_1.optPrio)((0, combi_1.alt)("TABLE", "SECTION OFFSET", sectionLength)), expressions_1.Source);
|
|
13
|
-
const ret = (0, combi_1.seq)("FIND", (0, combi_1.opt)((0, combi_1.alt)("FIRST OCCURRENCE OF", "ALL OCCURRENCES OF")),
|
|
12
|
+
const ret = (0, combi_1.seq)("FIND", (0, combi_1.opt)((0, combi_1.alt)("FIRST OCCURRENCE OF", "ALL OCCURRENCES OF")), expressions_1.FindType, expressions_1.Source, "IN", before, (0, combi_1.opt)(options));
|
|
14
13
|
return ret;
|
|
15
14
|
}
|
|
16
15
|
}
|
|
@@ -3,13 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Replace = void 0;
|
|
4
4
|
const combi_1 = require("../combi");
|
|
5
5
|
const expressions_1 = require("../expressions");
|
|
6
|
-
const version_1 = require("../../../version");
|
|
7
6
|
class Replace {
|
|
8
7
|
getMatcher() {
|
|
9
8
|
const length = (0, combi_1.seq)("LENGTH", expressions_1.Source);
|
|
10
9
|
const offset = (0, combi_1.seq)("OFFSET", expressions_1.Source);
|
|
11
10
|
const section = (0, combi_1.seq)((0, combi_1.opt)("IN"), "SECTION", (0, combi_1.per)(offset, length), "OF", expressions_1.Source);
|
|
12
|
-
const source = (0, combi_1.seq)((0, combi_1.opt)("OF"),
|
|
11
|
+
const source = (0, combi_1.seq)((0, combi_1.opt)("OF"), expressions_1.FindType, expressions_1.Source);
|
|
13
12
|
const cas = (0, combi_1.alt)("IGNORING CASE", "RESPECTING CASE");
|
|
14
13
|
const repl = (0, combi_1.seq)("REPLACEMENT COUNT", expressions_1.Target);
|
|
15
14
|
const replo = (0, combi_1.seq)("REPLACEMENT OFFSET", expressions_1.Target);
|
package/build/src/registry.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DangerousStatement = exports.DangerousStatementConf = void 0;
|
|
4
4
|
const Statements = require("../abap/2_statements/statements");
|
|
5
|
+
const Expressions = require("../abap/2_statements/expressions");
|
|
5
6
|
const issue_1 = require("../issue");
|
|
6
7
|
const _abap_rule_1 = require("./_abap_rule");
|
|
7
8
|
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
@@ -24,6 +25,8 @@ class DangerousStatementConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
|
24
25
|
this.deleteTextpool = true;
|
|
25
26
|
this.deleteDynpro = true;
|
|
26
27
|
this.importDynpro = true;
|
|
28
|
+
/** Finds instances of dynamic SQL: SELECT, UPDATE, DELETE, INSERT, MODIFY */
|
|
29
|
+
this.dynamicSQL = true;
|
|
27
30
|
}
|
|
28
31
|
}
|
|
29
32
|
exports.DangerousStatementConf = DangerousStatementConf;
|
|
@@ -37,6 +40,7 @@ class DangerousStatement extends _abap_rule_1.ABAPRule {
|
|
|
37
40
|
key: "dangerous_statement",
|
|
38
41
|
title: "Dangerous statement",
|
|
39
42
|
shortDescription: `Detects potentially dangerous statements`,
|
|
43
|
+
extendedInformation: `Dynamic SQL: Typically ABAP logic does not need dynamic SQL`,
|
|
40
44
|
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Security],
|
|
41
45
|
};
|
|
42
46
|
}
|
|
@@ -90,9 +94,29 @@ class DangerousStatement extends _abap_rule_1.ABAPRule {
|
|
|
90
94
|
if (message) {
|
|
91
95
|
issues.push(issue_1.Issue.atStatement(file, statementNode, this.getDescription(message), this.getMetadata().key, this.conf.severity));
|
|
92
96
|
}
|
|
97
|
+
if (this.conf.dynamicSQL) {
|
|
98
|
+
message = this.findDynamicSQL(statementNode);
|
|
99
|
+
if (message) {
|
|
100
|
+
issues.push(issue_1.Issue.atStatement(file, statementNode, this.getDescription(message), this.getMetadata().key, this.conf.severity));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
93
103
|
}
|
|
94
104
|
return issues;
|
|
95
105
|
}
|
|
106
|
+
findDynamicSQL(statementNode) {
|
|
107
|
+
const statement = statementNode.get();
|
|
108
|
+
if (statement instanceof Statements.UpdateDatabase
|
|
109
|
+
|| statement instanceof Statements.Select
|
|
110
|
+
|| statement instanceof Statements.SelectLoop
|
|
111
|
+
|| statement instanceof Statements.InsertDatabase
|
|
112
|
+
|| statement instanceof Statements.ModifyDatabase
|
|
113
|
+
|| statement instanceof Statements.DeleteDatabase) {
|
|
114
|
+
if (statementNode.findFirstExpression(Expressions.Dynamic)) {
|
|
115
|
+
return "Dynamic SQL";
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
96
120
|
}
|
|
97
121
|
exports.DangerousStatement = DangerousStatement;
|
|
98
122
|
//# sourceMappingURL=dangerous_statement.js.map
|
|
@@ -123,7 +123,7 @@ POSIX REGEX: https://help.sap.com/doc/abapdocu_755_index_htm/7.55/en-US/index.ht
|
|
|
123
123
|
this.conf = conf;
|
|
124
124
|
}
|
|
125
125
|
runParsed(file) {
|
|
126
|
-
var _a, _b;
|
|
126
|
+
var _a, _b, _c;
|
|
127
127
|
const issues = [];
|
|
128
128
|
const statements = file.getStatements();
|
|
129
129
|
let prev = undefined;
|
|
@@ -272,8 +272,7 @@ POSIX REGEX: https://help.sap.com/doc/abapdocu_755_index_htm/7.55/en-US/index.ht
|
|
|
272
272
|
}
|
|
273
273
|
if (configVersion >= version_1.Version.v756 && this.conf.regex) {
|
|
274
274
|
if (sta instanceof Statements.Find || sta instanceof Statements.Replace) {
|
|
275
|
-
|
|
276
|
-
if (concat.includes("REGEX")) {
|
|
275
|
+
if ((_c = staNode.findFirstExpression(Expressions.FindType)) === null || _c === void 0 ? void 0 : _c.concatTokens().includes("REGEX")) {
|
|
277
276
|
const issue = issue_1.Issue.atStatement(file, staNode, "REGEX obsolete, use PCRE", this.getMetadata().key, this.conf.severity);
|
|
278
277
|
issues.push(issue);
|
|
279
278
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.79.
|
|
3
|
+
"version": "2.79.34",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"homepage": "https://abaplint.org",
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@microsoft/api-extractor": "^7.18.
|
|
57
|
+
"@microsoft/api-extractor": "^7.18.17",
|
|
58
58
|
"@types/chai": "^4.2.22",
|
|
59
59
|
"@types/mocha": "^9.0.0",
|
|
60
60
|
"@types/node": "^16.11.6",
|