Skip to content

Commit 7e795c5

Browse files
CWE-681- 01 - README and code examples added (#792)
* CWE-681- 01 - README and code examples added * fixed some typos, missing formatting, SPDX --------- Signed-off-by: ebakrra <[email protected]> Signed-off-by: Helge Wehder <[email protected]> Co-authored-by: Helge Wehder <[email protected]>
1 parent e20e4db commit 7e795c5

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# CWE-681: Avoid an uncontrolled loss of precision when passing floating-point literals to a Decimal constructor
2+
3+
When working with decimal numbers in Python, using floating-point literals as input to the `Decimal` constructor can lead to unintended imprecision due to the limitations of `IEEE 754` [Wikipedia 2025](https://en.wikipedia.org/wiki/IEEE_754) floating-point representation; therefore, to ensure accurate decimal representation, it is advisable to avoid using floating-point literals.
4+
5+
## Noncompliant Code Example
6+
7+
In the `noncompliant01.py` code example, a floating-point value is given to the Decimal constructor. The decimal `0.45` cannot be exactly represented by a floating-point literal, and hence the output of the decimal is imprecise. This is because `0.45` as a floating-point representation deals with the number in binary. In binary, many decimal fractions cannot be represented exactly. As a result, `0.45` is stored as an approximate binary fraction in a `float`, and when this approximation is converted to a Decimal, the inexactness is preserved, can result in `0.450000000000000011102230246251565404236316680908203125`.
8+
9+
*[noncompliant01.py](noncompliant01.py):*
10+
11+
```py
12+
"""Non-compliant Code Example"""
13+
14+
from decimal import Decimal
15+
16+
print(Decimal(0.45))
17+
```
18+
19+
## Compliant Solution
20+
21+
In the `compliant01.py` code example, the floating-point value is passed as a string, allowing the value to be directly converted to a `Decimal` object with the exact decimal value. This is because the string representation is interpreted exactly as it appears, maintaining all the specified digits.
22+
23+
*[compliant01.py](compliant01.py):*
24+
25+
```py
26+
"""Compliant Code Example"""
27+
28+
from decimal import Decimal
29+
30+
print(Decimal("0.45"))
31+
```
32+
33+
## Related Guidelines
34+
35+
|||
36+
|:---|:---|
37+
|[SEI CERT Oracle Coding Standard for Java](https://wiki.sei.cmu.edu/confluence/display/java/SEI+CERT+Oracle+Coding+Standard+for+Java?src=breadcrumbs)|[NUM10-J. Do not construct BigDecimal objects from floating-point literals](https://wiki.sei.cmu.edu/confluence/display/java/NUM10-J.+Do+not+construct+BigDecimal+objects+from+floating-point+literals)|
38+
|[MITRE CWE Base](http://cwe.mitre.org/)| [CWE-681](https://cwe.mitre.org/data/definitions/681.html)|
39+
|[MITRE CWE Pillar](http://cwe.mitre.org/)|[CWE-664: Improper Control of a Resource Through its Lifetime](https://cwe.mitre.org/data/definitions/664.html)|
40+
41+
## Automated Detection
42+
43+
|Tool|Version|Checker|Description|
44+
|:----|:----|:----|:----|
45+
|[Bandit](https://bandit.readthedocs.io/en/latest/)|1.7.4 on python 3.10.4|Not Available||
46+
|[Flake8](https://flake8.pycqa.org/en/latest/)|8-4.0.1 on python 3.10.4|Not Available||
47+
48+
## Biblography
49+
50+
|||
51+
|:---|:---|
52+
|[Wikipedia 2025](en.wikipedia.org)|IEEE 754 [online]. Available from: [https://en.wikipedia.org/wiki/IEEE_754](https://en.wikipedia.org/wiki/IEEE_754)|
53+
|[Python docs](https://docs.python.org/3/)|decimal — Decimal fixed-point and floating-point arithmetic [online]. Available from: [https://docs.python.org/3/library/decimal.html](https://docs.python.org/3/library/decimal.html) [accessed 2 February 2025]|
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-FileCopyrightText: OpenSSF project contributors
2+
# SPDX-License-Identifier: MIT
3+
"""Compliant Code Example"""
4+
5+
from decimal import Decimal
6+
7+
print(Decimal("0.45"))
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-FileCopyrightText: OpenSSF project contributors
2+
# SPDX-License-Identifier: MIT
3+
"""Non-compliant Code Example"""
4+
5+
from decimal import Decimal
6+
7+
print(Decimal(0.45))

docs/Secure-Coding-Guide-for-Python/readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ It is __not production code__ and requires code-style or python best practices t
5454
|[CWE-532: Insertion of Sensitive Information into Log File](CWE-664/CWE-532/README.md)|[CVE-2023-45585](https://www.cvedetails.com/cve/CVE-2023-45585),<br/>CVSSv3.1: __9.8__,<br/>EPSS: __0.04__ (01.11.2024)|
5555
|[CWE-665: Improper Initialization](CWE-664/CWE-665/README.md)||
5656
|[CWE-681: Incorrect Conversion between Numeric Types](CWE-664/CWE-681/README.md)||
57+
|[CWE-681: Avoid an uncontrolled loss of precision when passing floating-point literals to a Decimal constructor.](CWE-664/CWE-681/01/README.md)||
5758
|[CWE-833: Deadlock](CWE-664/CWE-833/README.md)||
5859
|[CWE-843: Access of Resource Using Incompatible Type ('Type Confusion')](CWE-664/CWE-843/.)|[CVE-2021-29513](https://www.cvedetails.com/cve/CVE-2021-29513),<br/>CVSSv3.1: __7.8__,<br/>EPSS: __00.05__ (05.11.2024)|
5960
|[XXX-005: Consider hash-based integrity verification of byte code files against their source code files](CWE-664/XXX-005/.)||

0 commit comments

Comments
 (0)