/
sql_escape_host_variables.ts
90 lines (77 loc) · 3.47 KB
/
sql_escape_host_variables.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import * as Statements from "../abap/2_statements/statements";
import * as Expressions from "../abap/2_statements/expressions";
import {Issue} from "../issue";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {Version} from "../version";
import {RuleTag, IRuleMetadata} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
import {ABAPObject} from "../objects/_abap_object";
import {EditHelper} from "../edit_helper";
export class SQLEscapeHostVariablesConf extends BasicRuleConfig {
}
export class SQLEscapeHostVariables extends ABAPRule {
private conf = new SQLEscapeHostVariablesConf();
public getMetadata(): IRuleMetadata {
return {
key: "sql_escape_host_variables",
title: "Escape SQL host variables",
shortDescription: `Escape SQL host variables, from 740sp05`,
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#avoid-obsolete-language-elements`,
tags: [RuleTag.Upport, RuleTag.Styleguide, RuleTag.Quickfix, RuleTag.Syntax],
badExample: `SELECT * FROM tab INTO TABLE res WHERE field = val.`,
goodExample: `SELECT * FROM tab INTO TABLE @res WHERE field = @val.`,
};
}
public getConfig() {
return this.conf;
}
public setConfig(conf: SQLEscapeHostVariablesConf) {
this.conf = conf;
}
public runParsed(file: ABAPFile, obj: ABAPObject) {
const issues: Issue[] = [];
const type = obj.getType();
if (type === "INTF" || type === "TYPE") {
return [];
}
if (this.reg.getConfig().getVersion() < Version.v740sp02
&& this.reg.getConfig().getVersion() !== Version.Cloud) {
return [];
}
for (const s of file.getStatements()) {
if (s.get() instanceof Statements.UpdateDatabase
|| s.get() instanceof Statements.ModifyDatabase
|| s.get() instanceof Statements.Select
|| s.get() instanceof Statements.SelectLoop
|| s.get() instanceof Statements.InsertDatabase
|| s.get() instanceof Statements.DeleteDatabase) {
for (const o of s.findAllExpressionsMulti([Expressions.SQLSource, Expressions.SQLSourceSimple])) {
const first = o.getFirstChild();
if ((first?.get() instanceof Expressions.Source && first.getChildren()[0].get() instanceof Expressions.FieldChain)
|| (first?.get() instanceof Expressions.SimpleSource3 && first.getChildren()[0].get() instanceof Expressions.FieldChain)) {
const message = "Escape SQL host variables";
const firstToken = o.getFirstChild()!.getFirstToken();
const fix = EditHelper.replaceToken(file, firstToken, "@" + firstToken?.getStr());
const issue = Issue.atToken(file, first.getFirstToken(), message, this.getMetadata().key, this.conf.severity, fix);
issues.push(issue);
break;
}
}
for (const o of s.findAllExpressions(Expressions.SQLTarget)) {
const escaped = o.findDirectTokenByText("@");
if (escaped !== undefined) {
continue;
}
const message = "Escape SQL host variables";
const firstToken = o.getFirstChild()!.getFirstToken();
const fix = EditHelper.replaceToken(file, firstToken, "@" + firstToken?.getStr());
const issue = Issue.atToken(file, o.getFirstToken(), message, this.getMetadata().key, this.conf.severity, fix);
issues.push(issue);
break;
}
}
}
return issues;
}
}