Modify rule S3518: More LaYC Content for Python and Java (#3167)

This commit is contained in:
Anton Haubner 2023-09-28 11:35:02 +02:00 committed by GitHub
parent b965af0518
commit 9b3b79f51c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 141 additions and 21 deletions

6
rules/S3518/impact.adoc Normal file
View File

@ -0,0 +1,6 @@
=== What is the potential impact?
include::../../shared_content/layc/exception-impact.adoc[]
If the computation of the denominator is tied to user input data, this issue can
potentially even be exploited by attackers to disrupt your application.

View File

@ -0,0 +1,4 @@
This error will crash your program in most cases.
To fix it, you need to ensure that the denominator value in all division
operations is always non-zero, or check the value against zero before performing
the division.

View File

@ -1,22 +1,74 @@
If the denominator to an integer division or remainder operation is zero, a
`ArithmeticException` is thrown.
include::../introduction.adoc[]
== Why is this an issue? == Why is this an issue?
If the denominator to a division or modulo operation is zero it would result in a fatal error. A division (`/`) or remainder operation (`%`) by zero indicates a bug or logical
error.
This is because in Java, a division or remainder operation where the denominator
is zero and not a floating point value always results in an
`ArithmeticException` being thrown.
When working with ``++double++`` or ``++float++`` values, no exception will be
thrown, but the operation will result in special floating point values
representing either positive infinity, negative infinity, or `NaN`.
Unless these special values are explicitly handled by a program, zero
denominators should be avoided in floating point operations, too.
Otherwise, the application might produce unexpected results.
When working with ``++double++`` or ``++float++``, no fatal error will be raised, but it will lead to unusual result and should be avoided anyway. include::../impact.adoc[]
=== Noncompliant code example
This rule supports primitive ``++int++``, ``++long++``, ``++double++``, ``++float++`` as well as ``++BigDecimal++`` and ``++BigInteger++``. [source,java,diff-id=1,diff-type=noncompliant]
----
void test_divide() {
int z = 0;
if (unknown()) {
// ..
z = 3;
} else {
// ..
}
z = 1 / z; // Noncompliant, possible division by zero
}
----
include::../noncompliant.adoc[] === Compliant solution
include::../compliant.adoc[] [source,java,diff-id=1,diff-type=compliant]
----
void test_divide() {
int z = 0;
if (unknown()) {
// ..
z = 3;
} else {
// ..
z = 1;
}
z = 1 / z;
}
----
== Resources == Resources
=== Documentation
* https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/ArithmeticException.html[ArithmeticException]
=== Articles & blog posts
* https://cwe.mitre.org/data/definitions/369[MITRE, CWE-369] - Divide by zero * https://cwe.mitre.org/data/definitions/369[MITRE, CWE-369] - Divide by zero
* https://wiki.sei.cmu.edu/confluence/x/CTZGBQ[CERT, NUM02-J.] - Ensure that division and remainder operations do not result in divide-by-zero errors * https://wiki.sei.cmu.edu/confluence/x/CTZGBQ[CERT, NUM02-J.] - Ensure that division and remainder operations do not result in divide-by-zero errors
* https://wiki.sei.cmu.edu/confluence/x/ftYxBQ[CERT, INT33-C.] - Ensure that division and remainder operations do not result in divide-by-zero errors
=== Standards
* https://docs.oracle.com/javase/specs/jls/se17/html/jls-15.html#jls-15.17.2[The Division Operator in the JLS]
* https://docs.oracle.com/javase/specs/jls/se17/html/jls-15.html#jls-15.17.3[The Remainder Operator in the JLS]
ifdef::env-github,rspecator-view[] ifdef::env-github,rspecator-view[]
@ -24,6 +76,9 @@ ifdef::env-github,rspecator-view[]
== Implementation Specification == Implementation Specification
(visible only on this page) (visible only on this page)
This rule supports primitive ``++int++``, ``++long++``, ``++double++``, and
``++float++`` values, as well as ``++BigDecimal++`` and ``++BigInteger++``.
include::../message.adoc[] include::../message.adoc[]
include::../highlighting.adoc[] include::../highlighting.adoc[]

View File

@ -1,16 +1,21 @@
If the denominator to a division or modulo operation is zero it would result in a fatal error.
If the denominator to a division or modulo operation is zero, a
`ZeroDivisionError` is raised.
include::../introduction.adoc[]
== Why is this an issue? == Why is this an issue?
This is an issue because dividing by zero is a forbidden operation which leads to a fatal error. A division (`/`) or modulo operation (`%`) by zero indicates a bug or logical
error.
This is because in Python, a division or modulo operation where the denominator
is zero always results in a `ZeroDivisionError` being raised.
=== What is the potential impact? include::../impact.adoc[]
This issue can lead your program to an unexpected halt with all the inconveniences it entails.
== How to fix it == How to fix it
Make sure that zero never reaches the denominator. The goal is to ensure that a zero value never reaches the denominator.
=== Code examples === Code examples
@ -18,13 +23,14 @@ Make sure that zero never reaches the denominator.
[source,python,diff-id=1,diff-type=noncompliant] [source,python,diff-id=1,diff-type=noncompliant]
---- ----
def non_compliant(): def foo():
z = 0 z = 0
if (unknown()): if (unknown()):
# ... # ...
z = 4 z = 4
else: else:
# ... # ...
# (z is not reassigned to a non-zero value here)
z = 1 / z z = 1 / z
---- ----
@ -32,7 +38,7 @@ def non_compliant():
[source,python,diff-id=1,diff-type=compliant] [source,python,diff-id=1,diff-type=compliant]
---- ----
def compliant(): def foo():
z = 0 z = 0
if (unknown()): if (unknown()):
# ... # ...
@ -43,17 +49,65 @@ def compliant():
z = 1 / z z = 1 / z
---- ----
==== Noncompliant code example
[source,python,diff-id=2,diff-type=noncompliant]
----
def report_average():
sum = compute_sum()
denominator = population()
print(sum / denominator) # Noncompliant: divisor can be 0
def population():
size = read_size()
return size if size is not None else 0
----
==== Compliant solution
[source,python,diff-id=2,diff-type=compliant]
----
def report_average():
sum = compute_sum()
denominator = population()
if denominator == 0:
print("We have no data.")
else:
print(sum / denominator)
def population():
size = read_size()
return size if size is not None else 0
----
=== How does this work? === How does this work?
By ensuring that for all the paths that can define the variable ++z++, when none assigns it zero, we are sure that the issue is fixed. One approach is to inspect every possible execution path that affects the
denominator and adjust them such that none of them lead to a zero value.
The first example illustrates this by ensuring that for all the paths that can
define the variable ++z++, none assign it zero.
Thus, we are sure that the issue is fixed.
In other cases it might be necessary and safer to check and explicitly handle
the case of a zero denominator.
For instance, in the second example, an error message is displayed to the user
if the denominator is zero.
//=== Pitfalls //=== Pitfalls
//=== Going the extra mile //=== Going the extra mile
== Resources
=== Documentation
* https://docs.python.org/3/reference/expressions.html#binary-arithmetic-operations[Binary arithmetic operations]
* https://docs.python.org/3/library/exceptions.html#ZeroDivisionError[ZeroDivisionError]
=== Articles & blog posts
* https://cwe.mitre.org/data/definitions/369[MITRE, CWE-369] - Divide by zero
//== Resources
//=== Documentation
//=== Articles & blog posts //=== Articles & blog posts
//=== Conference presentations //=== Conference presentations
//=== Standards //=== Standards

View File

@ -1,9 +1,6 @@
=== What is the potential impact? === What is the potential impact?
Issues of this type interrupt the normal execution of a program, causing it to include::../../shared_content/layc/exception-impact.adoc[]
crash or putting it into an inconsistent state.
Therefore, this issue might impact the availability and reliability of your
application, or even result in data loss.
If the computation of an index value is tied to user input data, this issue can If the computation of an index value is tied to user input data, this issue can
potentially even be exploited by attackers to disrupt your application. potentially even be exploited by attackers to disrupt your application.

View File

@ -0,0 +1,4 @@
Issues of this type interrupt the normal execution of a program, causing it to
crash or putting it into an inconsistent state.
Therefore, this issue might impact the availability and reliability of your
application, or even result in data loss.