Get Started
- CodeAnt AI
- Control Center
- Pull Request Review
- IDE
- Compliance
- Anti-Patterns
- Code Governance
- Infrastructure Security Database
- Application Security Database
Cobol
Shared coding conventions allow teams to collaborate efficiently. This rule checks that file-code names conform to a specified regular expression.
You should avoid closing a CURSOR inside a PERFORM
statement, because it could impact performance or lead to unexpected behavior if the cursor was not opened in the same loop.
To improve source code readability and reusability, SQL operations should be located in dedicated procedures (sections or paragraphs) and should not be mixed with other SQL requests.
Aligning opening and ending words of statements is critical to keep the code readable, especially when blocks contain nested statements.
For IF statements, this rule also checks the alignment of the ELSE
word.
TO BE TRANSLATED :
L’objectif est de laisser la détermination taille des blocs physiques de fichier au niveau des JCL plutôt que de l’imposer par programme. Cela permet d’optimiser cette taille sans avoir à recompiler/livrer le programme
Que doit-on contrôler?
La présence de BLOC CONTAINS 0 RECORDS (ou BLOC 0, BLOC CONTAINS 0, etc)
To ensure future code portability, obsolete keywords should not be used. The following keywords were declared obsolete in the COBOL ANSI-85 standard and removed in the ISO/IEC 1989:2002 standard:
Paragraphs: `AUTHOR, INSTALLATION, DATE-WRITTEN, DATE-COMPILED, SECURITY
Clauses: DATA RECORD(S), LABEL RECORD(S), MEMORY SIZE, MULTIPLE FILE (TAPE), RERUN, VALUE OF, CODE SEGMENT-LIMIT
Statements: ALTER, ENTER, STOP literal, GO TO without an argument
Phrases: REVERSED phrase of the OPEN statement
Special registers: DEBUG-ITEM
Sections: Debugging sections
Declarative: USE FOR DEBUGGING
The following keywords were declared obsolete in the ISO/IEC 1989:2002 standard:
Phrase: DEBUGGING MODE
Clause: PADDING CHARACTER`
Changing procedural copybooks may potentially cause issues where many programs are pulled into a package for recompile and then a potential for bind issues during turnover. Having to edit procedural copybooks frequently causes delays in program maintenance as developers have to wait for another developer to complete their work. This also causes double work when programs get out of sync and a recent change could potentially be lost in a program.
GO TO should not be used to transfer control outside the current module, because any implied EXIT points will then be ignored. A module is either a section, a paragraph, or a set of paragraphs called with the PERFORM … THRU …
statement.
The ACCEPT statement causes data entered at the console or provided by the operating system to be made available to the program in a specific data element, without any validation or sanitization.
Thus, if this data is accepted in a particular format and used by other procedures, the system is vulnerable to attack or malfunction.
You should avoid opening a cursor inside a PERFORM
statement because doing so could impact performance, or lead to unexpected behavior if the the closing of the cursor is not defined in the same loop.
According to the IBM documentation,
To aid in migrations to IBM Enterprise COBOL 5.x, this rule raises an issue when UPPER-CASE, LOWER-CASE, or NATIONAL-OF` is used.
The DISPLAY
statement outputs data to standard out or some other destination and could reveal sensitive information. Therefore, it should be avoided.
The number of distinct data items used in a condition (IF, EVALUATE
, …) should not exceed a defined threshold.
The use of an array structure is useless when the array only has one element. Using an array structure anyway can impact performance and decrease the readability of the source code.
Level 77 identifies data items that are not subdivisions of other items, and that have no subdivisions. They are atomic by declaration. To make future subdivision possible, level 01 should be used instead of level 77.
Every section should be commented to explain its goal and how it works. This comment can be placed either just before or just after the section label.
Call stacks containing lot of PERFORM
statements is a key ingredient for making what’s known as “Spaghetti code”.
Such code is hard to read, refactor and therefore maintain.
This rule supports both sections and paragraphs.
CAST(… AS CHAR/VARCHAR) can be a source of incompatibilities between database versions: the behavior of CAST may not be the same depending on the version of the database system. Such incompatibilities can cause unexpected output from applications that CAST decimal data to CHAR or VARCHAR, it’s therefore best to avoid using CAST(… AS CHAR/VARCHAR)
.
You should avoid declaring a cursor inside a PERFORM
statement because doing so could impact performance. It could also lead to unexpected behavior if the opening and closing of the cursor are not defined in the same loop.
Most COBOL environments do not support recursive PERFORM calls, since they can cause unpredictable results. This rule raises an issue when recursive PERFORM
calls are used.
When a `SELECT returns null from a nullable column, the relevant host variable isn’t updated; it simply retains its previous value. The only way you’ll ever know the column value was null is to check the relevant null indicator included in the SELECT for a negative (null) value.
This rule raises an issue when a SELECT omits a null` indicator for a nullable column.
Note that this rule raises issues only when a database catalog is provided during the SonarQube analysis.
The use of DUMP and DUMP TRANSACTION
, while potentially useful during development and debugging, could expose system information to attackers and should not be used in production.
When the size of a variable-length table is DEPENDING ON a non-BINARY/COMP
variable, use of that table is inefficient because a conversion must be done every time the table is used.
When error conditions occur, it is usually a bad idea to simply ignore them. Instead, it is better to handle them properly, or at least to log them.
Shared coding conventions allow teams to collaborate efficiently. This rule checks that data item levels are incremented according to the configured values.
Using the default configuration:
There’s no point in including the default value of a column in an insert statement. It simply clutters the code to no additional benefit.
Note that this rule raises issues only when a database catalog is provided during the SonarQube analysis.
Merging collapsible IF
statements increases the code’s readability.
Code like
Initializing a data item with a value of the wrong type will lead to runtime errors. The rule checks that numeric data items are not initialized with alphanumeric/alphabetic values and that alphanumeric /alphabetic data items are not initialized with numeric values.
Pour des traitements effectuant des COMMITs réguliers et afin de conserver la position du CURSOR lors de lecture ou de mises à jour, il est impératif que les DECLARE CURSOR soient codés avec l’option WITH HOLD
After calling CICS commands with the RESP or NOHANDLE
options, the return code should be tested.
88-level variables, also known as “condition name” variables, each have a name, a value or set of values, and a “parent” variable. Those parent variables are called “conditional variables”.
Each 88-level variable can be seen as a short-cut conditional for testing the value of the parent: IF MY-88 will intrinsically return true if the parent value matches MY-88’s value, and false
if it does not.
Thus, testing a conditional variable against a literal value is redundant and confusing. Just use the 88-levels instead.
Every paragraph should be commented to explain its goal and how it works. This comment can be placed either just before or just after the paragraph label. Moreover paragraphs used to close a module can be left uncommented.
When using some transaction managers like IBM IMS, each COBOL program is in fact considered a sub-program by the transaction manager. The GOBACK statement returns control to the transaction manager, but using STOP RUN
might cause unpredictable results or abnormal termination.
This rule allows banning certain statements.
Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of arithmetic operators, having the same value on both sides of an operator yields predictable results, and should be simplified.
A EVALUATE and a chain of IF/ELSE IF statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true
.
Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it’s simply dead code and at worst, it’s a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.
Debug statements (ones with ‘D’ or ‘d’ in the indicator area) should not be executed in production, but the WITH DEBUGGING MODE clause activates all debug lines, which could expose sensitive information to attackers. Therefore the WITH DEBUGGING MODE
clause should be removed.
This rule is a more precise version of S1308 preventing the use of GO TO. The flow of a program is already complicated to understand with simple GO TOs. It’s even worse when a GO TO is executed conditionally like this is the case with GO TO DEPENDING ON
.
The rules of operator precedence are complicated and can lead to errors. For this reason, parentheses should be used for clarification in complex statements.
This rule raises an issue when more than the allowed number of non-like operators are used in a statement without parentheses to make execution order explicit.
Because statically-called programs must be relinked before they reflect changes in the code, it makes sense to prefer dynamic calls instead. Further, since statically-called programs are included in the caller’s load module, those modules could require more main storage than if the calls were dynamic, and the called programs could reside in memory multiple times - one for each caller.
While static calls are faster, their other disadvantages make dynamic calls the preferred method. Thus, this rule raises an issue when the program to CALL
is hard-coded, rather than specified in a variable.
88-level variables, also known as “condition name” variables, represent possible values of the “conditional variables” they’re tied to. Because a condition name can be used to test the value of its conditional variable without any other contextual references to the conditional variable being tested, it makes the code easier to understand if the name of the 88-level variable references its conditional variable.
This rule raises an issue when the name of an 88-level variable does not start with the first characters of the name of its conditional variable.
Even though closing an open file isn’t always mandatory (for instance when stopping the execution of a COBOL program with the STOP RUN statement), it’s good coding practice to always explicitly close any open files. This rule checks that for every OPEN statement there is a corresponding CLOSE
statement somewhere in the program.
Paragraphs, sections and statements must be correctly indented for better code readability.
Explicitly defining a cursor as read-only can improve performance by avoiding table locking. This allows other SQL requests to execute in parallel. Therefore when a cursor will only be used to read data, without modifying anything, the `FOR READ ONLY clause or its synonyn, FOR FETCH ONLY, should be used.
Conversely when a cursor will modify data, that too should be specified using the FOR UPDATE clause.
In short, it’s better to always explicitly define the purpose of the cursor with help of the FOR READ ONLY, FOR FETCH ONLY or FOR UPDATE` clauses.
Using FETCH FIRST n ROWS ONLY in a SELECT
without ordering the results from which the “n first” results are chosen will return a seemingly random set of rows, and is surely a mistake.
Using a scalar function or an arithmetic expression in a WHERE
condition can prevent the database from using indexes on the relevant column(s), and could therefore lead to performance issues.
There should not be any statements after EXIT PROGRAM
. Such statements cannot be reached, and are therefore dead code. Dead code makes a program more complex and therefore more difficult to maintain.
OS/VS COBOL accepted the NOTE statement, but IBM Enterprise COBOL does not. Therefore all NOTE
statements should be replaced by standard comment lines.
Shared coding conventions allow teams to collaborate efficiently. This rule checks that logical file names conform to a provided regular expression.
Using recursion with paragraphs is not a problem in itself but it potentially exposes the software to endless loop. This is the case when there is no condition to end the recursion or when this condition is always false.
This rule raises an issue when a paragraph contains a PERFORM
to itself to warn the developer that there is a risk of endless loop. This rule can also be used to fully prevent recursion to be used.
TODO
Having several levels of nested SQL SELECT statements makes the code difficult to read and should therefore be avoided.
Nested control flow statements IF, PERFORM, EVALUATE
and others are often key ingredients in creating
what’s known as “Spaghetti code”. This code smell can make your program difficult to understand and maintain.
When numerous control structures are placed inside one another, the code becomes a tangled, complex web. This significantly reduces the code’s readability and maintainability, and it also complicates the testing process.
The number of columns in a FETCH statement should match the number actually selected in the relevant cursor. Use more columns in the FETCH
than the cursor, and you’ve got a data problem, because the variables you expect to be updated by the cursor are never actually touched, and neither are their null indicators. Instead, they retain whatever value they had before the fetch. Meaning you’re operating with bad data.
The storage of a packed numeric field is most efficient when you code an odd number of digits in the PICTURE description, so that the leftmost byte is fully used. Packed-decimal items are handled as fixed-point numbers for arithmetic purposes.
There can’t be any good reason to do a full table scan on large database tables due to the cost of such operation and the scalability issue that might raise. This rule raises an issue when a SELECT statement doesn’t use at least one indexed column in its WHERE
clause.
Note That this rule raises issues only when a database catalog is provided during the SonarQube analysis.
OS/VS COBOL accepted the ON statement, but IBM Enterprise COBOL does not accept it anymore. The ON statement allows the selective execution of statements it contains. Similar functions are provided in Enterprise COBOL by EVALUATE and IF
OCCURS DEPENDING ON
clauses are complicated to use correctly and do not provide any benefits with regard to memory consumption. It is best to avoid them.
L’instruction INSERT/SELECT correspond à des mises à jour de masse sans possibilité de prendre des commits intermédiaires. Ce qui est très dommageable en terme d’accès concurrents sur des environnements 24/24 7/7.
Some COBOL compilers such as IBM one will assume that the minimum value of `OCCURS DEPENDING ON is 1 but nothing is enforcing that and this behaviour can change or be different when using another compiler.
Setting the minimum value of OCCURS DEPENDING ON` makes the code more readable, and less dependent on compiler.
Defining a subprogram to be called at runtime is possible but ill-advised. This extremely powerful feature can quite easily be misused, and even when used correctly, it highly increases the overall complexity of the program, and makes it impossible before runtime to know exactly what will be executed. Therefore defining the subprogram to be called at runtime is a feature that should be avoided.
Using a data value clause in the LINKAGE SECTION
can lead to unexpected behavior at runtime.
The `LINKAGE section describes data made available from another program through the CALL statement. The data structure defined in a LINKAGE section should be located in a COPYBOOK. Otherwise, at runtime multiple COBOL programs may try to share data structures which are not similar.
First level data items can also be defined in the main program as long as there are no structural pieces of information attached to this first level like the length, the format, and so on.
This rule raises an issue only on the first invalid data item of a LINKAGE` section.
Using the OPEN
file statement is costly, and therefore be avoided inside loops. Instead, the file can be saved into a buffer to increase performance.
While it is possible to manually set a primary key value, doing so almost guarantees a key clash at some point. Instead, primary key values should be set by (in descending order of desirability):
automatic generation by the database via a column definition such as `PROD_ID INT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1, NO CACHE)
the Generate_Unique() function
a value pulled directly from a sequence, like so: nextval for SEQ_PRODUCT
This rule raises an issue when an INSERT` statement assigns values to identity columns that are configured to always generate their values.
Note That this rule raises issues only when a database catalog is provided during the SonarQube analysis.
In general, the clause INDEXED BY should be used whenever possible when handling COBOL tables. If it’s not possible, then avoid using a numeric display variable to access the table’s elements. Instead, use a BINARY/COMP
variable, which the processor can handle more efficiently.
In cross-site scripting attacks, attackers insert attack scripts into your pages. Because no system is fool-proof, it may not be enough to screen the data that’s submitted to an application. You should also escape any content sent to the user so that any malicious code that may have escaped your input screening is neutralized. Specifically, the characters crucial to forming HTML must be escaped:
||turn||into||
|&|&|
|<|<|
|>|>|
|“|"|
|’|'|
|/|/|
This rule raises an issue for anything sent to WEB
.
Shared coding conventions allow teams to collaborate efficiently. This rule checks that paragraph names match a provided regular expression.
COBOL programs that include EXEC SQL INCLUDE statements must be pre-processed with an IBM DB2 precompiler or coprocessor before compilation. The precompiler does not require a period after the closing END-EXEC
, but the coprocessor does. For portability, a period should always be used.
Since databases don’t offer “Are you sure?” dialogs, it’s best to be very certain of what you’re changing before you do it. `UPDATE and DELETE statements that don’t precisely limit their effects to single rows risk changing more than was intended. That’s why they should be reviewed carefully.
This rule raises an issue when an UPDATE or DELETE statement’s WHERE clause does not use precisely either a unique index or all parts of the table’s primary key. That includes both cases where they are omitted in whole or in part, and when they are used but could still describe multiple rows. E.G. WHERE AGE = 34, and WHERE TABLE_ID > 0 AND TABLE_ID < 40`.
Note That this rule raises issues only when a database catalog is provided during the SonarQube analysis.
The comparison of numeric values of different formats is inefficient. For instance, comparing a `COMP-3 with a COMP-4 causes a performance drag because conversions are required under the covers before the comparison.
This rule raises an issue when variables with different USAGE` clauses, or different numbers of decimal places are compared.
The rule S1279 (“DISPLAY” should not be used) is fully preventing the usage of the DISPLAY statement whereas in same cases it may be useful to output some data to SYSOUT. However, the output of a call to DISPLAY UPON CONSOLE
is unlikely to be viewed by someone because the output is displayed on the console and nowadays no one is in front of the console to see if something is happening.
Moving a large string into a small field will result in data truncation with data lost from the right side of the string.
Copybooks should be used only to share data definitions or logic. The following keywords relate to the nature or structure of a COBOL program, and should be defined directly in the source code of the COBOL program:
`IDENTIFICATION DIVISION.
PROGRAM-ID xxxxxxxx.
AUTHOR. yyyyyyyyyyy.
INSTALLATION. zzzzzz.
DATE-WRITTEN. zzzzzz.
DATE-COMPILED. zzzzzz.
ENVIRONNEMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. xxxxxx.
OBJECT-COMPUTER. xxxxxx.
SPECIAL-NAMES. DECIMAL-POINT IS COMMA.
I-O CONTROL.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
SCREEN.
REPORT.
INPUT-OUTPUT SECTION.
LINKAGE SECTION.
PROCEDURE DIVISION.`
A primary key uniquely identifies a row in a database table, and should be considered immutable. Primary key values may be used in foreign keys in other tables, as well as in external systems. Changing such a value, even with the best of motivations, is likely to wreak havoc on the system’s data integrity and potentially across other systems as well.
Note That this rule raises issues only when a database catalog is provided during the SonarQube analysis.
When the FILE STATUS
is not specified on a file, any read operations on the file should handle the “AT END” or “INVALID KEY” conditions.
There’s no point in selecting columns in a cursor that aren’t actually referenced in the relevant FETCH statement. Instead, either pare down the cursor to select only what you actually need, or FETCH
the other columns.
Program/file names offer only very limited space for indicating program function, which is why you should take advantage of the ability to specify a program `TITLE. Omitting the TITLE statement will result in a default, uncommunicative TITLE value being printed at the top of each page of the source listing. Instead, you should write an expressive title that gives a clear impression of the program’s function.
This rule raises an issue when a there is no TITLE before the IDENTIFICATION DIVISION. Ideally, TITLE` will be the first line of a program, but it cannot be placed before compiler options.
The number of RECORDS or CHARACTERS specified in a BLOCK CONTAINS clause is used to determine block size. Specify 10 RECORDS, and the block will be exactly 10x the length of the record. But that may not be the right size, depending on the environment. Instead, it is considered a best practice to specify 0 RECORDS
, so the block size will be calculated automatically.
If the second procedure of a PERFORM THRU is not defined after the first one, the source code is semantically incorrect and the program doesn’t behave as expected.
An unused data item block is dead code. Such data item blocks should be removed to increase the maintainability of the program.
Having all branches of an EVALUATE or IF chain with the same implementation indicates a problem.
In the following code:
If a SQL TABLE
is declared but not used in the program, it can be considered dead code and should therefore be removed. This will improve maintainability because developers will not wonder what the variable is used for.
An alphanumeric value should not be moved to a numeric field. Because alphanumeric values are stored differently than numeric values, simply moving the bits from one field to the other will yield strange results at best, and crashes at worst.
Instead, NUMVAL
should be used to explicitly convert the alphanumeric value to a numeric one.
This rule allows banning some modules.
COPY … SUPPRESS
suppresses the inclusion of the copybook contents from the source listing, making it very difficult to gain a complete understanding of what’s happening in the code. This could hinder both maintenance and debugging.
Shared coding conventions allow teams to collaborate efficiently. For maximum readability, this rule checks that the levels, names and PICTURE clauses for all items of the same level and which are subordinate to the same item start in the same column.
Performing math on variables that are declared - explicitly or implicitly - as `DISPLAY or NATIONAL is much less efficient than on COMPUTATIONAL, COMP, or BINARY variables. That’s because COMP variables, for instance, are defined for binary storage, which makes math on them more efficient. That’s why values that are going to be used primarily for math should be declared with a math type. When math isn’t a primary use, it may not make sense to change the declared type, but MOVEing the value to a COMP variable and performing the math on it instead would.
It is important to note however, that COMPUTATIONAL, COMP, and BINARY` formats should be used with caution if the variable will be passed to other systems which may not use the same storage format.
Afin de ne pas perturber via la programmation, les paramètres positionnés sur les BIND PACKAGE pour des environnements de type 24/24 7/7, il est important de vérifier que les ordres de SELECT simples ou dans les DECLARE CURSOR que les mots clés WITH RR, WITH RS er WITH CS ne soient pas positionnés. Le seul mot clé accepté est WITH UR.
S’assurer que sur les ordres de SELECT (simple ou mis dans des DECLARE CURSOR) que les mots clés WITH RR, WITH RS er WITH CS ne soient pas positionnés.
There is such a thing as software that’s too helpful, and that’s the case with DB2’s implicit casting of host variables used in `WHERE clauses. If for instance you compare a varchar column with the value of a numeric host variable, starting with version 10, DB2 will silently convert the numeric value to a string - at a potentially huge performance cost.
This rule raises an issue when the type of a variable used with a SQL WHERE` clause does not match the underlying type of the column to which it is compared.
Using more than one OF clause to access a data item can quickly decrease the readability of the source code. Either some OF
clauses are optional and should be removed, or there are too many intersections between several data structures and those intersections should be removed.
It is fairly normal for COBOL development teams to decide to work either with sections or with paragraphs and to make this choice a standard.
When sections are used, it is also normal to define another standard: “End every section definition with an empty paragraph definition, or a paragraph containing only a terminating statement”.
This empty paragraph can then be jumped to with a `GO TO statement to stop the execution of a section.
Accepted terminating statements in the otherwise-empty ending paragraph are: EXIT, EXIT PROGRAM, STOP RUN, and GO BACK`.
Host variables are used for passing data back and forth from the database to a COBOL program via SQL. In order to keep that transmission clear and free of errors, the format of each host variable should match its corresponding database column type.
This rule raises an issue when column and corresponding host variable don’t match in terms of numeric vs character data, and when the host variable is smaller than the column width.
88-level variables, also known as “condition name” variables, represent possible values of the “conditional variables” they’re tied to. An unused “condition name” variable is dead code. Such variables should be removed to increase the maintainability of the program.
Any statement after a STOP RUN or GOBACK
is unreachable and therefore dead code which should be removed.
When a FILE STATUS
is declared on a file, it should be tested immediately after IO operations.
Every paragraph should be commented to explain its goal and how it works. This comment can be placed either just before or just after the paragraph label. Moreover paragraphs used to close a module can be left uncommented.
Aligning common keywords in a series of statements makes the code easier to read. therefore, it is better to align the TO
keywords in a series of successive MOVE statements.
PERFORM is used to execute a paragraph located somewhere in the program and then, once executed, the execution flow will continue on the line following the PERFORM statement. This is the expected behaviour that can be broken if a GO TO is added in the called paragraph. When mixing PERFORM and GO TO you can quickly be lost on the execution flow and finally don’t get the one you expect. For this reason, calling PERFORM with paragraphs that used GO TO
should be avoided.
Having two paragraphs with the same name in the same section or in no section at all is bad practice. At best, each copy contains the same code, and the redefinition is simply useless, duplicated code. At worst, the paragraphs contain different logic, potentially leading to confusion and unexpected results as a programmer who was aware of the first paragraph definition inadvertently invokes the second. For these reasons, paragraphs with duplicated names should be either removed or renamed.
TODO
Permettre une gestion standardisée de la gestion des dates dans les traitements. Tous les traitements doivent utiliser le module MGDATR03 s’ils ont besoin d’utiliser la date du jour.
Portability issues may restrict which characters should be used in an identifier.
This rule checks identifier names against a regular expression of disallowed characters. Due to a technical limitation, the COBOL analyzer is not able for the time-being to differentiate lowercase from uppercase characters.
Shared coding conventions allow teams to collaborate efficiently. This rule checks that first level data item names match a provided regular expression.
The EVALUATE statement allows implementing case structures in Cobol. Each case is managed by a WHEN phrase activated by specific test of a variable.The WHEN OTHER phrase allows managing all the cases which have not been taken into account by the previous WHEN phrases. If the variable to be tested contains a new value that is not currently managed then the absence of the WHEN OTHER
phrase will lead a situation in which no process will be performed for this value and the program may have uncontrolled or undefined behavior.
There is no good reason to keep an empty and therefore valueless section. Such sections should be removed.
Moving a large number into a small field will result in data truncation. Generally, numeric values are truncated from the left. However, in the case of floating point values, when the target field has too little precision to hold the value being moved to it, decimals will be truncated (not rounded!) from the right.
In any case, data loss is always the result when too-large values are moved to too-small fields.
When using CICS XCTL or CICS LINK
, it is a bad practice not to specify the length of the communication area.
When a closable statement contains nested statements, it can quickly become difficult to see which statements are nested and which are not. That’s why ending a list of nested statements with END-${STATEMENT-NAME}
is advised.
OS/VS COBOL accepted the EXHIBIT statement, but IBM Enterprise COBOL does not. With IBM Enterprise COBOL, the DISPLAY
statement must be used instead.
The binary algorithm used by `SEARCH ALL is far more efficient for large tables than the one used by SEARCH. While it’s not always possible to use SEARCH ALL, it should be the preferred algorithm.
This rule raises an issue when tables with more than the specified number of possible entries are searched using SEARCH`.
Putting multiple statements on a single line lowers the code readability and makes debugging the code more complex.
Unresolved directive in <stdin> - include::{noncompliant}[]
Write one statement per line to improve readability.
Unresolved directive in <stdin> - include::{compliant}[]
The complexity of an expression is defined by the number of &&, || and condition ? ifTrue : ifFalse
operators it contains.
A single expression’s complexity should not become too high to keep the code readable.
Allowing an application to dynamically change the structure of a database at runtime is very dangerous because the application can become unstable under unexpected conditions. Best practices dictate that applications only manipulate data.
Development tools and frameworks usually have options to make debugging easier for developers. Although these features are useful during development, they should never be enabled for applications deployed in production. Debug instructions or error messages can leak detailed information about the system, like the application’s path or file names.
Magic numbers make the code more complex to understand as it requires the reader to have knowledge about the global context to understand the number itself. Their usage may seem obvious when writing the code, but it may not be the case for another developer or later once the context faded away. -1, 0, and 1 are not considered magic numbers.
SQL queries that use EXISTS subqueries are inefficient because the subquery is re-run for every row in the outer query’s table. There are more efficient ways to write most queries, ways that do not use the EXISTS
condition.
Although the WHERE condition is optional in a SELECT statement, for performance and security reasons, a WHERE
clause should always be specified to prevent reading the whole table.
Each source file should start with a header stating file ownership and the license which must be used to distribute the application.
This rule must be fed with the header text that is expected at the beginning of every file.
The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. However, redundant pairs of parentheses could be misleading and should be removed.
Conditional expressions which are always true or false can lead to unreachable code.
There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.
Duplicated string literals make the process of refactoring complex and error-prone, as any change would need to be propagated on all occurrences.
SELECT *
should be avoided because it releases control of the returned columns and could therefore lead to errors and potentially to performance issues.
Developers often use TODO tags to mark areas in the code where additional work or improvements are needed but are not implemented immediately. However, these TODO tags sometimes get overlooked or forgotten, leading to incomplete or unfinished code. This rule aims to identify and address unattended TODO tags to ensure a clean and maintainable codebase. This description explores why this is a problem and how it can be fixed to improve the overall code quality.
In a Zen-like manner, “NULL” is never equal to anything, even itself. Therefore comparisons using equality operators will always return `False, even when the value actually IS NULL.
For that reason, comparison operators should never be used to make comparisons with NULL; IS NULL and IS NOT NULL should be used instead. This extends as well to empty string (""), which is equivalent to NULL` for some database engines.
Because it is easy to extract strings from an application source code or binary, credentials should not be hard-coded. This is particularly true for applications that are distributed or that are open-source.
In the past, it has led to the following vulnerabilities:
Credentials should be stored outside of the code in a configuration file, a database, or a management service for secrets.
This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.
It’s recommended to customize the configuration of this rule with additional credential words such as “oauthToken”, “secret”, …
Control flow constructs like if-statements allow the programmer to direct the flow of a program depending on a boolean expression. However, if the condition is always true or always false, only one of the branches will ever be executed. In that case, the control flow construct and the condition no longer serve a purpose; they become gratuitous.
SQL statements should not contain dynamic clauses
Having two WHEN clauses in the same EVALUATE statement or two branches in the same IF structure with the same implementation is at best duplicate code, and at worst a coding error.
Credentials should never be included in comments. Doing so means that anyone who has access to the code also has access to the database.
This rule flags each instance of “password” in a comment