Skip to content

Commit 82356e2

Browse files
github-actions[bot]sallaigyghislainpiot
authored
Create rule S7461: Conflicting Borrow and Hash implementations should be avoided (#4847)
* Create rule S7461 * Update metadata.json * Update rule.adoc --------- Co-authored-by: sallaigy <sallaigy@users.noreply.github.com> Co-authored-by: Gyula Sallai <gyula.sallai@sonarsource.com> Co-authored-by: Ghislain Piot <ghislain.piot@sonarsource.com>
1 parent 2f14fe4 commit 82356e2

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

rules/S7461/metadata.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{
2+
}

rules/S7461/rust/metadata.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"title": "Conflicting `Borrow` and `Hash` implementations should be avoided",
3+
"type": "BUG",
4+
"status": "ready",
5+
"remediation": {
6+
"func": "Constant\/Issue",
7+
"constantCost": "5min"
8+
},
9+
"tags": [
10+
"clippy"
11+
],
12+
"defaultSeverity": "Critical",
13+
"ruleSpecification": "RSPEC-7461",
14+
"sqKey": "S7461",
15+
"scope": "All",
16+
"defaultQualityProfiles": ["Sonar way"],
17+
"quickfix": "unknown",
18+
"code": {
19+
"impacts": {
20+
"RELIABILITY": "HIGH"
21+
},
22+
"attribute": "LOGICAL"
23+
}
24+
}

rules/S7461/rust/rule.adoc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
== Why is this an issue?
3+
4+
When a type implements `Borrow<T>`, it should provide consistent behavior between the borrowed and owned values, especially regarding `Eq`, `Ord`, and `Hash`. However, `str` and `[u8]` have different Hash implementations, leading to inconsistent hash values for the same underlying data when accessed through different Borrow implementations. This violates the principle that `hash(x) == hash((x as Borrow<[u8]>).borrow()) == hash((x as Borrow<str>).borrow())` must hold, and can cause issues with hash-based collections and comparisons.
5+
6+
=== Code examples
7+
8+
==== Noncompliant code example
9+
10+
[source,rust]
11+
----
12+
use std::borrow::Borrow;
13+
use std::hash::{Hash, Hasher};
14+
15+
struct ExampleType {
16+
data: String,
17+
}
18+
19+
impl Hash for ExampleType {
20+
fn hash<H: Hasher>(&self, state: &mut H) {
21+
self.data.hash(state); // Noncompliant: Inconsistent Hash
22+
}
23+
}
24+
25+
impl Borrow<str> for ExampleType {
26+
fn borrow(&self) -> &str {
27+
&self.data
28+
}
29+
}
30+
31+
impl Borrow<[u8]> for ExampleType {
32+
fn borrow(&self) -> &[u8] {
33+
self.data.as_bytes()
34+
}
35+
}
36+
----
37+
38+
== Resources
39+
=== Documentation
40+
41+
* Clippy Lints - https://rust-lang.github.io/rust-clippy/master/index.html#impl_hash_borrow_with_str_and_bytes

0 commit comments

Comments
 (0)