Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11134x 11134x 11134x 11134x 11134x 33143x 33143x 33143x 33143x 33143x 33143x 33143x 33143x 33143x 33143x 33143x 33143x 33143x 33143x 11134x 11134x 10568x 10568x 11134x 11134x 244x 244x 11134x 11134x 311x 311x 311x 311x 264x 264x 47x 311x 311x 311x 311x 311x 311x 311x 47x 47x 46x 46x 1x 1x 47x 47x 47x 311x 218x 218x 218x 218x 171x 171x 218x 47x 47x 47x 218x 218x 218x 1x 1x 46x 218x 23x 23x 23x 218x 47x 47x 47x 11134x 11134x | import {Issue} from "../issue";
import * as Expressions from "../abap/2_statements/expressions";
import {ABAPRule} from "./_abap_rule";
import {BasicRuleConfig} from "./_basic_rule_config";
import {IRuleMetadata, RuleTag} from "./_irule";
import {ABAPFile} from "../abap/abap_file";
import {ABAPObject} from "../objects/_abap_object";
import {LanguageVersion} from "../version";
import {Severity} from "../severity";
// ABAP Cloud: 17 system fields allowed for reading
// https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABENSYSTEM_FIELDS.html
const CLOUD_ALLOWED = new Set([
"SY-BATCH",
"SY-DBCNT",
"SY-FDPOS",
"SY-INDEX",
"SY-LANGU",
"SY-MANDT",
"SY-MSGID",
"SY-MSGNO",
"SY-MSGTY",
"SY-MSGV1",
"SY-MSGV2",
"SY-MSGV3",
"SY-MSGV4",
"SY-SUBRC",
"SY-SYSID",
"SY-TABIX",
"SY-UNAME",
]);
// ABAP for Key Users: 5 system fields allowed for reading
const KEYUSER_ALLOWED = new Set([
"SY-DBCNT",
"SY-FDPOS",
"SY-INDEX",
"SY-SUBRC",
"SY-TABIX",
]);
export class SyReadRestrictionConf extends BasicRuleConfig {
}
export class SyReadRestriction extends ABAPRule {
private conf = new SyReadRestrictionConf();
public getMetadata(): IRuleMetadata {
return {
key: "sy_read_restriction",
title: "SY field read restriction",
shortDescription: `Finds reads of SY fields not allowed in the current language version`,
extendedInformation:
`In ABAP Cloud, only 17 system fields may be read; reads of other fields produce a warning.\n` +
`In ABAP for Key Users, only 5 system fields may be read:\n` +
`SY-DBCNT, SY-FDPOS, SY-INDEX, SY-SUBRC, SY-TABIX.\n` +
`https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABENSYSTEM_FIELDS.html`,
tags: [RuleTag.SingleFile],
badExample: `lv = sy-uname.`,
goodExample: `IF sy-subrc = 0. ENDIF.`,
};
}
public getConfig() {
return this.conf;
}
public setConfig(conf: SyReadRestrictionConf) {
this.conf = conf;
}
public runParsed(file: ABAPFile, _obj: ABAPObject) {
const issues: Issue[] = [];
const langVer = this.reg.getConfig().getLanguageVersion();
if (langVer === LanguageVersion.Normal) {
return [];
}
const allowed = langVer === LanguageVersion.KeyUser ? KEYUSER_ALLOWED : CLOUD_ALLOWED;
const severity = langVer === LanguageVersion.KeyUser ? this.conf.severity : Severity.Warning;
// Collect tokens that appear in writable Target positions — they're modifications,
// handled by the sy_modification rule, not this one.
const writeTokens = new Set<unknown>();
for (const t of file.getStructure()?.findAllExpressionsRecursive(Expressions.Target) || []) {
const concat = t.concatTokens().toUpperCase();
if (!concat.startsWith("SY-")) {
continue;
}
writeTokens.add(t.getFirstToken());
}
// Walk all tokens looking for the sequence SY - <fieldname>
const tokens = file.getTokens();
for (let i = 0; i + 2 < tokens.length; i++) {
const sy = tokens[i];
const dash = tokens[i + 1];
const fld = tokens[i + 2];
if (sy.getStr().toUpperCase() !== "SY") {
continue;
}
if (dash.getStr() !== "-") {
continue;
}
// Adjacent: no whitespace between the three tokens, on the same row
if (sy.getEnd().getCol() !== dash.getStart().getCol()
|| dash.getEnd().getCol() !== fld.getStart().getCol()
|| sy.getRow() !== dash.getRow()
|| dash.getRow() !== fld.getRow()) {
continue;
}
if (writeTokens.has(sy)) {
continue;
}
const fieldName = "SY-" + fld.getStr().toUpperCase();
if (!allowed.has(fieldName)) {
const message = `SY field "${fieldName}" cannot be read in language version ${langVer}`;
issues.push(Issue.atToken(file, sy, message, this.getMetadata().key, severity));
}
}
return issues;
}
}
|