CTR57-CPP. 提供一个有效排序的谓词
原文链接:
CTR57-CPP. Provide a valid ordering predicate
https://wiki.sei.cmu.edu/confluence/display/cplusplus/CTR57-CPP.+Provide+a+valid+ordering+predicate
关联容器在他们的键比较谓词上设置了严格的弱排序要求 [ISO/IEC 14882-2014]。一个严格的弱排序具有以下特性:
- 对于所有的
x
:x < x == false
(非自反性) - 对于所有的
x
,y
: 如果x < y
那么!(y < x)
(不对称性) - 对于所有的
x
,y
,z
: 如果x < y && y < z
那么x < z
(传递性)
提供无效排序的谓词给对关联容器 (e.g., sets, maps, multisets, and multimaps),或者作为排序算法的比较准测,会导致奇怪的行为或者无线循环 [Meyers 01]。当关联容器或者通用标准模板库算法需要一个排序谓词时,谓词必须满足严格的弱排序要求。
Associative containers place a strict weak ordering requirement on their key comparison predicates [ISO/IEC 14882-2014]. A strict weak ordering has the following properties:
- for all
x
:x < x == false
(irreflexivity) - for all
x
,y
: ifx < y
then!(y < x)
(asymmetry) - for all
x
,y
,z
: ifx < y && y < z
thenx < z
(transitivity)
Providing an invalid ordering predicate for an associative container (e.g., sets, maps, multisets, and multimaps), or as a comparison criterion with the sorting algorithms, can result in erratic behavior or infinite loops [Meyers 01]. When an ordering predicate is required for an associative container or a generic standard template library algorithm, the predicate must meet the requirements for inducing a strict weak ordering.
不合规的代码示例 Noncompliant Code Example
在这个不合规的代码示例中,通过使用不遵循严格弱排序要求的比较器来创建 std::set
对象。特别地,对于相等的值这不会返回 false。因此,遍历来自 std::set::equal_range
返回的结果将造成 unspecified behavior。
In this noncompliant code example, the std::set
object is created with a comparator that does not adhere to the strict weak ordering requirement. Specifically, it fails to return false for equivalent values. As a result, the behavior of iterating over the results from std::set::equal_range
results in unspecified behavior.
1 |
|
合规方案 Compliant Solution
这个合规方案使用 std::set
默认比较器替换提供的不合理的比较器。
This compliant solution uses the default comparator with std::set
instead of providing an invalid one.
1 |
|
不合规的代码示例 Noncompliant Code Example
在这个不合规的代码示例中,被存储在 std::set
的对象有一个重载 operator<
的实现,允许对象通过 std::less
来比较。然而,比较运算没有提供严格的弱排序。特别地,两个 sets,x 和 y,值均为 1, 但是 j 的值不一样,会导致 comp(x, y)
和 comp(y, x)
均返回 false 的场景。不满足非对称要求。
In this noncompliant code example, the objects stored in the std::set have an overloaded operator< implementation, allowing the objects to be compared with std::less. However, the comparison operation does not provide a strict weak ordering. Specifically, two sets, x and y, whose i values are both 1, but have differing j values can result in a situation where comp(x, y) and comp(y, x) are both false, failing the asymmetry requirements.
1 |
|
合规方案 Compliant Solution
这个合规方案使用 std::tie()
来实现 operator<
严格的弱排序谓词。
This compliant solution uses std::tie() to properly implement the strict weak ordering operator< predicate.
1 |
|
风险评估 Risk Assessment
使用一个无效排序规则会导致怪异的行为或无限循环。
Using an invalid ordering rule can lead to erratic behavior or infinite loops.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
CTR57-CPP | Low | Probable | High | P2 | L3 |
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
Parasoft C/C++test | CERT_CPP-CTR57-a | For associative containers never use comparison function returning true for equal values |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT Oracle Coding Standard for Java | MET10-J. Follow the general contract when implementing the compareTo() method |
---|---|
Bibliography
[ISO/IEC 14882-2014] | Subclause 23.2.4, “Associative Containers” |
---|---|
[Meyers 2001] | Item 21, “Always Have Comparison Functions Return False for Equal Values” |
[Sutter 2004] | Item 83, “Use a Checked STL Implementation” |
备注,这里评论区提出了质疑,需要注意的。
Timmy Weerwag 发表:
The list of requirements at the top do not correctly specify a strict weak ordering. In fact, these only specify a strict partial ordering (note that asymetry is already implied by irreflexivity and transitivity). One also needs transitivity of incomparability.
The explanation for the second non-compliant example is also wrong. The relation is assymetric but fails the transitivity of incomparability. Consider P = (0, 2), Q = (2, 0) and R = (1, 3). Observe that P and Q are incomparable (neither P < Q nor Q < P), and Q and R are incomparable. However, P < R and hence, P and R are comparable.
本文标题:CTR57-CPP. 提供一个有效排序的谓词
文章作者:xwnb
发布时间:2020-06-25
最后更新:2023-04-17
原始链接:https://xwnb.github.io/posts/2368459165/
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!并保留本声明。感谢您的阅读和支持!
分享