History

Merge pull request #2332 from cruessler/make-sha-1-optional

Make sha1 optional in `gix-hash`

Sebastian Thiel committed 10 months ago

Commit 41502032 parents 9e1ba5e aed5b669 files · +81 −12Browse files

Unified · Split

9 files
  1. gix-hash/Cargo.toml +2 −2
  2. gix-hash/src/hasher.rs +9 −0
  3. gix-hash/src/io.rs +1 −0
  4. gix-hash/src/kind.rs +13 −1
  5. gix-hash/src/lib.rs +9 −5
  6. gix-hash/src/object_id.rs +24 −2
  7. gix-hash/src/oid.rs +21 −1
  8. gix-hash/tests/hash/kind.rs +0 −1
  9. justfile +2 −0
gix-hash/Cargo.toml+2−2
@@ -18,7 +18,7 @@ test = false · 17 unmodified lines
1818 [features]
1919 default = ["sha1"]
2020 ## Support for SHA1 hashes and digests.
21−sha1 = []
21+sha1 = ["dep:sha1-checked"]
2222 ## Support for SHA256 hashes and digests.
2323 sha256 = ["dep:sha2"]
2424 ## Data structures implement `serde::Serialize` and `serde::Deserialize`.
@@ -30,7 +30,7 @@ gix-features = { version = "^0.45.1", path = "../gix-features", features = ["pro · 5 unmodified lines
3030 thiserror = "2.0.17"
3131 faster-hex = { version = "0.10.0", default-features = false, features = ["std"] }
3232 serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] }
33−sha1-checked = { version = "0.10.0", default-features = false }
33+sha1-checked = { version = "0.10.0", optional = true, default-features = false }
3434 sha2 = { version = "0.10.0", optional = true, default-features = false }
3535
3636 document-features = { version = "0.2.0", optional = true }
gix-hash/src/hasher.rs+9−0
@@ -7,8 +7,12 @@ pub enum Error { · 6 unmodified lines
77 }
88
99 pub(super) mod _impl {
10+ #[cfg(feature = "sha1")]
1011 use sha1_checked::{CollisionResult, Digest};
1112
13+ #[cfg(all(not(feature = "sha1"), feature = "sha256"))]
14+ use sha2::Digest;
15+
1216 use crate::hasher::Error;
1317
1418 /// Hash implementations that can be used once.
@@ -17,6 +21,7 @@ pub(super) mod _impl { · 2 unmodified lines
1721 /// An implementation of the SHA1 hash.
1822 ///
1923 /// We use [`sha1_checked`] to implement the same collision detection algorithm as Git.
24+ #[cfg(feature = "sha1")]
2025 Sha1(sha1_checked::Sha1),
2126 /// An implementation of the SHA256 hash.
2227 #[cfg(feature = "sha256")]
@@ -25,6 +30,7 @@ pub(super) mod _impl { · 2 unmodified lines
2530
2631 impl Hasher {
2732 /// Let's not make this public to force people to go through [`hasher()`].
33+ #[cfg(feature = "sha1")]
2834 fn new_sha1() -> Self {
2935 // This matches the configuration used by Git, which only uses
3036 // the collision detection to bail out, rather than computing
@@ -44,6 +50,7 @@ pub(super) mod _impl { · 13 unmodified lines
4450 /// Digest the given `bytes`.
4551 pub fn update(&mut self, bytes: &[u8]) {
4652 match self {
53+ #[cfg(feature = "sha1")]
4754 Hasher::Sha1(sha1) => sha1.update(bytes),
4855 #[cfg(feature = "sha256")]
4956 Hasher::Sha256(sha256) => sha256.update(bytes),
@@ -59,6 +66,7 @@ pub(super) mod _impl { · 9 unmodified lines
5966 #[inline]
6067 pub fn try_finalize(self) -> Result<crate::ObjectId, Error> {
6168 match self {
69+ #[cfg(feature = "sha1")]
6270 Hasher::Sha1(sha1) => match sha1.try_finalize() {
6371 CollisionResult::Ok(digest) => Ok(crate::ObjectId::Sha1(digest.into())),
6472 CollisionResult::Mitigated(_) => {
@@ -89,6 +97,7 @@ pub(super) mod _impl { · 24 unmodified lines
8997 #[inline]
9098 pub fn hasher(kind: crate::Kind) -> Hasher {
9199 match kind {
100+ #[cfg(feature = "sha1")]
92101 crate::Kind::Sha1 => Hasher::new_sha1(),
93102 #[cfg(feature = "sha256")]
94103 crate::Kind::Sha256 => Hasher::new_sha256(),
gix-hash/src/io.rs+1−0
@@ -114,6 +114,7 @@ pub(super) mod _impl { · 113 unmodified lines
114114 /// Create a new hash writer which hashes all bytes written to `inner` with a hash of `kind`.
115115 pub fn new(inner: T, object_hash: crate::Kind) -> Self {
116116 match object_hash {
117+ #[cfg(feature = "sha1")]
117118 crate::Kind::Sha1 => Write {
118119 inner,
119120 hash: crate::hasher(object_hash),
gix-hash/src/kind.rs+13−1
@@ -1,6 +1,9 @@
11 use std::str::FromStr;
22
3−use crate::{oid, Kind, ObjectId, SIZE_OF_SHA1_DIGEST, SIZE_OF_SHA1_HEX_DIGEST};
3+use crate::{oid, Kind, ObjectId};
4+
5+#[cfg(feature = "sha1")]
6+use crate::{SIZE_OF_SHA1_DIGEST, SIZE_OF_SHA1_HEX_DIGEST};
47
58 #[cfg(feature = "sha256")]
69 use crate::{SIZE_OF_SHA256_DIGEST, SIZE_OF_SHA256_HEX_DIGEST};
@@ -10,6 +13,7 @@ impl TryFrom<u8> for Kind { · 3 unmodified lines
1013
1114 fn try_from(value: u8) -> Result<Self, Self::Error> {
1215 Ok(match value {
16+ #[cfg(feature = "sha1")]
1317 1 => Kind::Sha1,
1418 #[cfg(feature = "sha256")]
1519 2 => Kind::Sha256,
@@ -23,6 +27,7 @@ impl FromStr for Kind { · 7 unmodified lines
2327
2428 fn from_str(s: &str) -> Result<Self, Self::Err> {
2529 Ok(match s {
30+ #[cfg(feature = "sha1")]
2631 "sha1" | "SHA1" | "SHA-1" => Kind::Sha1,
2732 #[cfg(feature = "sha256")]
2833 "sha256" | "SHA256" | "SHA-256" => Kind::Sha256,
@@ -34,6 +39,7 @@ impl FromStr for Kind { · 5 unmodified lines
3439 impl std::fmt::Display for Kind {
3540 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3641 match self {
42+ #[cfg(feature = "sha1")]
3743 Kind::Sha1 => f.write_str("sha1"),
3844 #[cfg(feature = "sha256")]
3945 Kind::Sha256 => f.write_str("sha256"),
@@ -84,6 +90,7 @@ impl Kind { · 44 unmodified lines
8490 #[inline]
8591 pub const fn len_in_hex(&self) -> usize {
8692 match self {
93+ #[cfg(feature = "sha1")]
8794 Kind::Sha1 => SIZE_OF_SHA1_HEX_DIGEST,
8895 #[cfg(feature = "sha256")]
8996 Kind::Sha256 => SIZE_OF_SHA256_HEX_DIGEST,
@@ -94,6 +101,7 @@ impl Kind { · 4 unmodified lines
94101 #[inline]
95102 pub const fn len_in_bytes(&self) -> usize {
96103 match self {
104+ #[cfg(feature = "sha1")]
97105 Kind::Sha1 => SIZE_OF_SHA1_DIGEST,
98106 #[cfg(feature = "sha256")]
99107 Kind::Sha256 => SIZE_OF_SHA256_DIGEST,
@@ -106,6 +114,7 @@ impl Kind { · 6 unmodified lines
106114 #[inline]
107115 pub const fn from_hex_len(hex_len: usize) -> Option<Self> {
108116 Some(match hex_len {
117+ #[cfg(feature = "sha1")]
109118 0..=SIZE_OF_SHA1_HEX_DIGEST => Kind::Sha1,
110119 #[cfg(feature = "sha256")]
111120 0..=SIZE_OF_SHA256_HEX_DIGEST => Kind::Sha256,
@@ -124,6 +133,7 @@ impl Kind { · 12 unmodified lines
124133 #[inline]
125134 pub(crate) fn from_len_in_bytes(bytes: usize) -> Self {
126135 match bytes {
136+ #[cfg(feature = "sha1")]
127137 SIZE_OF_SHA1_DIGEST => Kind::Sha1,
128138 #[cfg(feature = "sha256")]
129139 SIZE_OF_SHA256_DIGEST => Kind::Sha256,
@@ -135,6 +145,7 @@ impl Kind { · 5 unmodified lines
135145 #[inline]
136146 pub fn null_ref(&self) -> &'static oid {
137147 match self {
148+ #[cfg(feature = "sha1")]
138149 Kind::Sha1 => oid::null_sha1(),
139150 #[cfg(feature = "sha256")]
140151 Kind::Sha256 => oid::null_sha256(),
@@ -145,6 +156,7 @@ impl Kind { · 4 unmodified lines
145156 #[inline]
146157 pub const fn null(&self) -> ObjectId {
147158 match self {
159+ #[cfg(feature = "sha1")]
148160 Kind::Sha1 => ObjectId::null_sha1(),
149161 #[cfg(feature = "sha256")]
150162 Kind::Sha256 => ObjectId::null_sha256(),
gix-hash/src/lib.rs+9−5
@@ -9,10 +9,8 @@ · 8 unmodified lines
99 #![cfg_attr(all(doc, feature = "document-features"), feature(doc_cfg))]
1010 #![deny(missing_docs, rust_2018_idioms, unsafe_code)]
1111
12−// Remove this once other hashes (e.g., SHA256, and potentially others)
13−// are supported, and this crate can build without [`ObjectId::Sha1`].
14−#[cfg(not(feature = "sha1"))]
15−compile_error!("Please set the `sha1` feature flag");
12+#[cfg(all(not(feature = "sha1"), not(feature = "sha256")))]
13+compile_error!("Please set either the `sha1` or the `sha256` feature flag");
1614
1715 #[path = "oid.rs"]
1816 mod borrowed;
@@ -47,8 +45,10 @@ pub struct Prefix { · 28 unmodified lines
4745 }
4846
4947 /// The size of a SHA1 hash digest in bytes.
48+#[cfg(feature = "sha1")]
5049 const SIZE_OF_SHA1_DIGEST: usize = 20;
5150 /// The size of a SHA1 hash digest in hex.
51+#[cfg(feature = "sha1")]
5252 const SIZE_OF_SHA1_HEX_DIGEST: usize = 2 * SIZE_OF_SHA1_DIGEST;
5353
5454 /// The size of a SHA256 hash digest in bytes.
@@ -58,8 +58,10 @@ const SIZE_OF_SHA256_DIGEST: usize = 32; · 3 unmodified lines
5858 #[cfg(feature = "sha256")]
5959 const SIZE_OF_SHA256_HEX_DIGEST: usize = 2 * SIZE_OF_SHA256_DIGEST;
6060
61+#[cfg(feature = "sha1")]
6162 const EMPTY_BLOB_SHA1: &[u8; SIZE_OF_SHA1_DIGEST] =
6263 b"\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91";
64+#[cfg(feature = "sha1")]
6365 const EMPTY_TREE_SHA1: &[u8; SIZE_OF_SHA1_DIGEST] =
6466 b"\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04";
6567
@@ -74,9 +76,11 @@ const EMPTY_TREE_SHA256: &[u8; SIZE_OF_SHA256_DIGEST] = b"\x6e\xf1\x9b\x41\x22\x · 8 unmodified lines
7476 #[non_exhaustive]
7577 pub enum Kind {
7678 /// The SHA1 hash with 160 bits.
77− #[default]
79+ #[cfg_attr(feature = "sha1", default)]
80+ #[cfg(feature = "sha1")]
7881 Sha1 = 1,
7982 /// The SHA256 hash with 256 bits.
83+ #[cfg_attr(all(not(feature = "sha1"), feature = "sha256"), default)]
8084 #[cfg(feature = "sha256")]
8185 Sha256 = 2,
8286 }
gix-hash/src/object_id.rs+24−2
@@ -4,7 +4,10 @@ use std::{ · 3 unmodified lines
44 ops::Deref,
55 };
66
7−use crate::{borrowed::oid, Kind, EMPTY_BLOB_SHA1, EMPTY_TREE_SHA1, SIZE_OF_SHA1_DIGEST};
7+use crate::{borrowed::oid, Kind};
8+
9+#[cfg(feature = "sha1")]
10+use crate::{EMPTY_BLOB_SHA1, EMPTY_TREE_SHA1, SIZE_OF_SHA1_DIGEST};
811
912 #[cfg(feature = "sha256")]
1013 use crate::{EMPTY_BLOB_SHA256, EMPTY_TREE_SHA256, SIZE_OF_SHA256_DIGEST};
@@ -15,6 +18,7 @@ use crate::{EMPTY_BLOB_SHA256, EMPTY_TREE_SHA256, SIZE_OF_SHA256_DIGEST}; · 4 unmodified lines
1518 #[non_exhaustive]
1619 pub enum ObjectId {
1720 /// A SHA1 hash digest
21+ #[cfg(feature = "sha1")]
1822 Sha1([u8; SIZE_OF_SHA1_DIGEST]),
1923 /// A SHA256 hash digest
2024 #[cfg(feature = "sha256")]
@@ -38,7 +42,10 @@ impl Hash for ObjectId { · 17 unmodified lines
3842 pub mod decode {
3943 use std::str::FromStr;
4044
41− use crate::{object_id::ObjectId, SIZE_OF_SHA1_DIGEST, SIZE_OF_SHA1_HEX_DIGEST};
45+ use crate::object_id::ObjectId;
46+
47+ #[cfg(feature = "sha1")]
48+ use crate::{SIZE_OF_SHA1_DIGEST, SIZE_OF_SHA1_HEX_DIGEST};
4249
4350 #[cfg(feature = "sha256")]
4451 use crate::{SIZE_OF_SHA256_DIGEST, SIZE_OF_SHA256_HEX_DIGEST};
@@ -62,6 +69,7 @@ pub mod decode { · 17 unmodified lines
6269 /// Such a buffer can be obtained using [`oid::write_hex_to(buffer)`][super::oid::write_hex_to()]
6370 pub fn from_hex(buffer: &[u8]) -> Result<ObjectId, Error> {
6471 match buffer.len() {
72+ #[cfg(feature = "sha1")]
6573 SIZE_OF_SHA1_HEX_DIGEST => Ok({
6674 ObjectId::Sha1({
6775 let mut buf = [0; SIZE_OF_SHA1_DIGEST];
@@ -107,6 +115,7 @@ impl ObjectId { · 39 unmodified lines
107115 #[inline]
108116 pub fn kind(&self) -> Kind {
109117 match self {
118+ #[cfg(feature = "sha1")]
110119 ObjectId::Sha1(_) => Kind::Sha1,
111120 #[cfg(feature = "sha256")]
112121 ObjectId::Sha256(_) => Kind::Sha256,
@@ -116,6 +125,7 @@ impl ObjectId { · 3 unmodified lines
116125 #[inline]
117126 pub fn as_slice(&self) -> &[u8] {
118127 match self {
128+ #[cfg(feature = "sha1")]
119129 Self::Sha1(b) => b.as_ref(),
120130 #[cfg(feature = "sha256")]
121131 Self::Sha256(b) => b.as_ref(),
@@ -125,6 +135,7 @@ impl ObjectId { · 3 unmodified lines
125135 #[inline]
126136 pub fn as_mut_slice(&mut self) -> &mut [u8] {
127137 match self {
138+ #[cfg(feature = "sha1")]
128139 Self::Sha1(b) => b.as_mut(),
129140 #[cfg(feature = "sha256")]
130141 Self::Sha256(b) => b.as_mut(),
@@ -135,6 +146,7 @@ impl ObjectId { · 4 unmodified lines
135146 #[inline]
136147 pub const fn empty_blob(hash: Kind) -> ObjectId {
137148 match hash {
149+ #[cfg(feature = "sha1")]
138150 Kind::Sha1 => ObjectId::Sha1(*EMPTY_BLOB_SHA1),
139151 #[cfg(feature = "sha256")]
140152 Kind::Sha256 => ObjectId::Sha256(*EMPTY_BLOB_SHA256),
@@ -145,6 +157,7 @@ impl ObjectId { · 4 unmodified lines
145157 #[inline]
146158 pub const fn empty_tree(hash: Kind) -> ObjectId {
147159 match hash {
160+ #[cfg(feature = "sha1")]
148161 Kind::Sha1 => ObjectId::Sha1(*EMPTY_TREE_SHA1),
149162 #[cfg(feature = "sha256")]
150163 Kind::Sha256 => ObjectId::Sha256(*EMPTY_TREE_SHA256),
@@ -156,6 +169,7 @@ impl ObjectId { · 5 unmodified lines
156169 #[doc(alias = "zero", alias = "git2")]
157170 pub const fn null(kind: Kind) -> ObjectId {
158171 match kind {
172+ #[cfg(feature = "sha1")]
159173 Kind::Sha1 => Self::null_sha1(),
160174 #[cfg(feature = "sha256")]
161175 Kind::Sha256 => Self::null_sha256(),
@@ -167,6 +181,7 @@ impl ObjectId { · 5 unmodified lines
167181 #[doc(alias = "is_zero", alias = "git2")]
168182 pub fn is_null(&self) -> bool {
169183 match self {
184+ #[cfg(feature = "sha1")]
170185 ObjectId::Sha1(digest) => &digest[..] == oid::null_sha1().as_bytes(),
171186 #[cfg(feature = "sha256")]
172187 ObjectId::Sha256(digest) => &digest[..] == oid::null_sha256().as_bytes(),
@@ -193,6 +208,7 @@ impl ObjectId { · 20 unmodified lines
193208 /// Use `Self::try_from(bytes)` for a fallible version.
194209 pub fn from_bytes_or_panic(bytes: &[u8]) -> Self {
195210 match bytes.len() {
211+ #[cfg(feature = "sha1")]
196212 SIZE_OF_SHA1_DIGEST => Self::Sha1(bytes.try_into().expect("prior length validation")),
197213 #[cfg(feature = "sha256")]
198214 SIZE_OF_SHA256_DIGEST => Self::Sha256(bytes.try_into().expect("prior length validation")),
@@ -205,6 +221,7 @@ impl ObjectId { · 6 unmodified lines
205221 impl ObjectId {
206222 /// Instantiate an `ObjectId` from a 20 bytes SHA1 digest.
207223 #[inline]
224+ #[cfg(feature = "sha1")]
208225 fn new_sha1(id: [u8; SIZE_OF_SHA1_DIGEST]) -> Self {
209226 ObjectId::Sha1(id)
210227 }
@@ -220,6 +237,7 @@ impl ObjectId { · 9 unmodified lines
220237 ///
221238 /// Panics if the slice doesn't have a length of 20.
222239 #[inline]
240+ #[cfg(feature = "sha1")]
223241 pub(crate) fn from_20_bytes(b: &[u8]) -> ObjectId {
224242 let mut id = [0; SIZE_OF_SHA1_DIGEST];
225243 id.copy_from_slice(b);
@@ -239,6 +257,7 @@ impl ObjectId { · 13 unmodified lines
239257
240258 /// Returns an `ObjectId` representing a SHA1 whose memory is zeroed.
241259 #[inline]
260+ #[cfg(feature = "sha1")]
242261 pub(crate) const fn null_sha1() -> ObjectId {
243262 ObjectId::Sha1([0u8; SIZE_OF_SHA1_DIGEST])
244263 }
@@ -254,6 +273,7 @@ impl ObjectId { · 9 unmodified lines
254273 impl std::fmt::Debug for ObjectId {
255274 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
256275 match self {
276+ #[cfg(feature = "sha1")]
257277 ObjectId::Sha1(_hash) => f.write_str("Sha1(")?,
258278 #[cfg(feature = "sha256")]
259279 ObjectId::Sha256(_) => f.write_str("Sha256(")?,
@@ -265,6 +285,7 @@ impl std::fmt::Debug for ObjectId { · 5 unmodified lines
265285 }
266286 }
267287
288+#[cfg(feature = "sha1")]
268289 impl From<[u8; SIZE_OF_SHA1_DIGEST]> for ObjectId {
269290 fn from(v: [u8; SIZE_OF_SHA1_DIGEST]) -> Self {
270291 Self::new_sha1(v)
@@ -281,6 +302,7 @@ impl From<[u8; SIZE_OF_SHA256_DIGEST]> for ObjectId { · 10 unmodified lines
281302 impl From<&oid> for ObjectId {
282303 fn from(v: &oid) -> Self {
283304 match v.kind() {
305+ #[cfg(feature = "sha1")]
284306 Kind::Sha1 => ObjectId::from_20_bytes(v.as_bytes()),
285307 #[cfg(feature = "sha256")]
286308 Kind::Sha256 => ObjectId::from_32_bytes(v.as_bytes()),
gix-hash/src/oid.rs+21−1
@@ -1,6 +1,9 @@
11 use std::hash;
22
3−use crate::{Kind, ObjectId, EMPTY_BLOB_SHA1, EMPTY_TREE_SHA1, SIZE_OF_SHA1_DIGEST};
3+use crate::{Kind, ObjectId};
4+
5+#[cfg(feature = "sha1")]
6+use crate::{EMPTY_BLOB_SHA1, EMPTY_TREE_SHA1, SIZE_OF_SHA1_DIGEST};
47
58 #[cfg(feature = "sha256")]
69 use crate::{EMPTY_BLOB_SHA256, EMPTY_TREE_SHA256, SIZE_OF_SHA256_DIGEST};
@@ -59,6 +62,7 @@ impl std::fmt::Debug for oid { · 52 unmodified lines
5962 f,
6063 "{}({})",
6164 match self.kind() {
65+ #[cfg(feature = "sha1")]
6266 Kind::Sha1 => "Sha1",
6367 #[cfg(feature = "sha256")]
6468 Kind::Sha256 => "Sha256",
@@ -82,6 +86,7 @@ impl oid { · 17 unmodified lines
8286 #[inline]
8387 pub fn try_from_bytes(digest: &[u8]) -> Result<&Self, Error> {
8488 match digest.len() {
89+ #[cfg(feature = "sha1")]
8590 SIZE_OF_SHA1_DIGEST => Ok(
8691 #[allow(unsafe_code)]
8792 unsafe {
@@ -178,6 +183,7 @@ impl oid { · 90 unmodified lines
178183 #[doc(alias = "is_zero", alias = "git2")]
179184 pub fn is_null(&self) -> bool {
180185 match self.kind() {
186+ #[cfg(feature = "sha1")]
181187 Kind::Sha1 => &self.bytes == oid::null_sha1().as_bytes(),
182188 #[cfg(feature = "sha256")]
183189 Kind::Sha256 => &self.bytes == oid::null_sha256().as_bytes(),
@@ -188,6 +194,7 @@ impl oid { · 4 unmodified lines
188194 #[inline]
189195 pub fn is_empty_blob(&self) -> bool {
190196 match self.kind() {
197+ #[cfg(feature = "sha1")]
191198 Kind::Sha1 => &self.bytes == oid::empty_blob_sha1().as_bytes(),
192199 #[cfg(feature = "sha256")]
193200 Kind::Sha256 => &self.bytes == oid::empty_blob_sha256().as_bytes(),
@@ -198,6 +205,7 @@ impl oid { · 4 unmodified lines
198205 #[inline]
199206 pub fn is_empty_tree(&self) -> bool {
200207 match self.kind() {
208+ #[cfg(feature = "sha1")]
201209 Kind::Sha1 => &self.bytes == oid::empty_tree_sha1().as_bytes(),
202210 #[cfg(feature = "sha256")]
203211 Kind::Sha256 => &self.bytes == oid::empty_tree_sha256().as_bytes(),
@@ -209,6 +217,7 @@ impl oid { · 5 unmodified lines
209217 impl oid {
210218 /// Returns a SHA1 digest with all bytes being initialized to zero.
211219 #[inline]
220+ #[cfg(feature = "sha1")]
212221 pub(crate) fn null_sha1() -> &'static Self {
213222 oid::from_bytes([0u8; SIZE_OF_SHA1_DIGEST].as_ref())
214223 }
@@ -222,6 +231,7 @@ impl oid { · 7 unmodified lines
222231
223232 /// Returns an `oid` representing the SHA1 hash of an empty blob.
224233 #[inline]
234+ #[cfg(feature = "sha1")]
225235 pub(crate) fn empty_blob_sha1() -> &'static Self {
226236 oid::from_bytes(EMPTY_BLOB_SHA1)
227237 }
@@ -235,6 +245,7 @@ impl oid { · 7 unmodified lines
235245
236246 /// Returns an `oid` representing the SHA1 hash of an empty tree.
237247 #[inline]
248+ #[cfg(feature = "sha1")]
238249 pub(crate) fn empty_tree_sha1() -> &'static Self {
239250 oid::from_bytes(EMPTY_TREE_SHA1)
240251 }
@@ -266,6 +277,7 @@ impl ToOwned for oid { · 25 unmodified lines
266277
267278 fn to_owned(&self) -> Self::Owned {
268279 match self.kind() {
280+ #[cfg(feature = "sha1")]
269281 Kind::Sha1 => ObjectId::Sha1(self.bytes.try_into().expect("no bug in hash detection")),
270282 #[cfg(feature = "sha256")]
271283 Kind::Sha256 => ObjectId::Sha256(self.bytes.try_into().expect("no bug in hash detection")),
@@ -273,12 +285,20 @@ impl ToOwned for oid { · 1 unmodified line
273285 }
274286 }
275287
288+#[cfg(feature = "sha1")]
276289 impl<'a> From<&'a [u8; SIZE_OF_SHA1_DIGEST]> for &'a oid {
277290 fn from(v: &'a [u8; SIZE_OF_SHA1_DIGEST]) -> Self {
278291 oid::from_bytes(v.as_ref())
279292 }
280293 }
281294
295+#[cfg(feature = "sha256")]
296+impl<'a> From<&'a [u8; SIZE_OF_SHA256_DIGEST]> for &'a oid {
297+ fn from(v: &'a [u8; SIZE_OF_SHA256_DIGEST]) -> Self {
298+ oid::from_bytes(v.as_ref())
299+ }
300+}
301+
282302 impl std::fmt::Display for &oid {
283303 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
284304 let mut buf = Kind::hex_buf();
gix-hash/tests/hash/kind.rs+0−1
@@ -90,7 +90,6 @@ fn longest_sha1() { · 89 unmodified lines
9090 assert_eq!(longest, Kind::Sha1);
9191 }
9292
93−// TODO: make sure to test all permutations once `sha1` is fully optional
9493 #[test]
9594 #[cfg(all(not(feature = "sha1"), feature = "sha256"))]
9695 fn longest_sha256() {
justfile+2−0
@@ -71,6 +71,7 @@ check: · 70 unmodified lines
7171 cargo check -p gix-hash --all-features
7272 cargo check -p gix-hash
7373 cargo check -p gix-hash --features sha256
74+ cargo check -p gix-hash --no-default-features --features sha256
7475 cargo check -p gix-object --all-features
7576 cargo check -p gix-object --features verbose-object-parsing-errors
7677 cargo check -p gix-attributes --features serde
@@ -158,6 +159,7 @@ unit-tests: · 81 unmodified lines
158159 cargo nextest run -p gix-worktree-tests --features gix-features-parallel --no-fail-fast
159160 cargo nextest run -p gix-hash --no-fail-fast
160161 cargo nextest run -p gix-hash --features sha256 --no-fail-fast
162+ cargo nextest run -p gix-hash --no-default-features --features sha256 --no-fail-fast # TODO: make this actually work by removing 'sha1' from default features.
161163 cargo nextest run -p gix-object --no-fail-fast
162164 cargo nextest run -p gix-object --features verbose-object-parsing-errors --no-fail-fast
163165 cargo nextest run -p gix-tempfile --features signals --no-fail-fast

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t