aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2022-12-09 21:17:44 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-12-09 21:17:44 +0000
commitc4d298b98e30ed664dbfaa5c9b3152f42dffb8f5 (patch)
tree4795bce3ea174233055cb91f0be2e4573c90cf26
parent51818e04c33a94e61d4db0e370a5baa2d609fa2f (diff)
parentc67a48d55f35a95ceb8b5c13437af82603829d5b (diff)
downloadconst-oid-main-16k-with-phones.tar.gz
Merge "Upgrade const-oid to 0.9.1"main-16k-with-phones
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp4
-rw-r--r--CHANGELOG.md8
-rw-r--r--Cargo.toml31
-rw-r--r--Cargo.toml.orig2
-rw-r--r--LICENSE-MIT25
-rw-r--r--METADATA13
-rw-r--r--README.md2
-rw-r--r--src/arcs.rs19
-rw-r--r--src/checked.rs11
-rw-r--r--src/db.rs2
-rw-r--r--src/encoder.rs9
-rw-r--r--src/error.rs18
-rw-r--r--src/lib.rs51
-rw-r--r--src/parser.rs2
15 files changed, 163 insertions, 36 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 65a697a..80de78a 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
{
"git": {
- "sha1": "87223cd4203097729be3fad21d23ef183405991b"
+ "sha1": "252671f5828a6df3c1a31222519cd278c8704e4b"
},
"path_in_vcs": "const-oid"
} \ No newline at end of file
diff --git a/Android.bp b/Android.bp
index c6af18a..334199c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,8 +1,6 @@
// This file is generated by cargo2android.py --config cargo2android.json.
// Do not modify this file as changes will be overridden on upgrade.
-
-
package {
default_applicable_licenses: ["external_rust_crates_const-oid_license"],
}
@@ -37,7 +35,7 @@ rust_library_host {
name: "libconst_oid",
crate_name: "const_oid",
cargo_env_compat: true,
- cargo_pkg_version: "0.9.0",
+ cargo_pkg_version: "0.9.1",
srcs: ["src/lib.rs"],
edition: "2021",
features: ["db"],
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4dcb4fb..f6ea7d3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## 0.9.1 (2022-11-12)
+### Added
+- clippy lints for checked arithmetic and panics ([#561])
+- `DynAssociatedOid` trait ([#758])
+
+[#561]: https://github.com/RustCrypto/formats/pull/561
+[#758]: https://github.com/RustCrypto/formats/pull/758
+
## 0.9.0 (2022-03-11)
### Added
- Fallible `const fn` parser + `::new_unwrap` ([#458], [#459])
diff --git a/Cargo.toml b/Cargo.toml
index d45e11e..0080b6f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,19 +13,38 @@
edition = "2021"
rust-version = "1.57"
name = "const-oid"
-version = "0.9.0"
+version = "0.9.1"
authors = ["RustCrypto Developers"]
-description = "Const-friendly implementation of the ISO/IEC Object Identifier (OID) standard\nas defined in ITU X.660, with support for BER/DER encoding/decoding as well as\nheapless no_std (i.e. embedded) support\n"
+description = """
+Const-friendly implementation of the ISO/IEC Object Identifier (OID) standard
+as defined in ITU X.660, with support for BER/DER encoding/decoding as well as
+heapless no_std (i.e. embedded) support
+"""
documentation = "https://docs.rs/const-oid"
readme = "README.md"
-keywords = ["iso", "iec", "itu", "oid"]
-categories = ["cryptography", "data-structures", "encoding", "no-std", "parser-implementations"]
+keywords = [
+ "iso",
+ "iec",
+ "itu",
+ "oid",
+]
+categories = [
+ "cryptography",
+ "data-structures",
+ "encoding",
+ "no-std",
+ "parser-implementations",
+]
license = "Apache-2.0 OR MIT"
repository = "https://github.com/RustCrypto/formats/tree/master/const-oid"
-resolver = "2"
+
[package.metadata.docs.rs]
all-features = true
-rustdoc-args = ["--cfg", "docsrs"]
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
+]
+
[dev-dependencies.hex-literal]
version = "0.3"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 5978809..ffc05e6 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "const-oid"
-version = "0.9.0"
+version = "0.9.1"
authors = ["RustCrypto Developers"]
license = "Apache-2.0 OR MIT"
description = """
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..1b78809
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2020-2022 The RustCrypto Project Developers
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/METADATA b/METADATA
index 6afb80d..c994f5c 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/const-oid
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
name: "const-oid"
description: "Const-friendly implementation of the ISO/IEC Object Identifier (OID) standard as defined in ITU X.660, with support for BER/DER encoding/decoding as well as heapless no_std (i.e. embedded) support"
third_party {
@@ -7,14 +11,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/const-oid/const-oid-0.9.0.crate"
+ value: "https://static.crates.io/crates/const-oid/const-oid-0.9.1.crate"
}
- version: "0.9.0"
- # Dual-licensed, using the least restrictive per go/thirdpartylicenses#same.
+ version: "0.9.1"
license_type: NOTICE
last_upgrade_date {
year: 2022
- month: 8
- day: 19
+ month: 12
+ day: 8
}
}
diff --git a/README.md b/README.md
index bd6dbad..fae3cfc 100644
--- a/README.md
+++ b/README.md
@@ -79,7 +79,7 @@ dual licensed as above, without any additional terms or conditions.
[//]: # (badges)
-[crate-image]: https://img.shields.io/crates/v/const-oid.svg
+[crate-image]: https://buildstats.info/crate/const-oid
[crate-link]: https://crates.io/crates/const-oid
[docs-image]: https://docs.rs/const-oid/badge.svg
[docs-link]: https://docs.rs/const-oid/
diff --git a/src/arcs.rs b/src/arcs.rs
index b3f9f24..7bf7a9a 100644
--- a/src/arcs.rs
+++ b/src/arcs.rs
@@ -66,9 +66,15 @@ impl<'a> Arcs<'a> {
let mut arc_bytes = 0;
loop {
- match self.oid.as_bytes().get(offset + arc_bytes).cloned() {
+ let len = checked_add!(offset, arc_bytes);
+
+ match self.oid.as_bytes().get(len).cloned() {
+ // The arithmetic below includes advance checks
+ // against `ARC_MAX_BYTES` and `ARC_MAX_LAST_OCTET`
+ // which ensure the operations will not overflow.
+ #[allow(clippy::integer_arithmetic)]
Some(byte) => {
- arc_bytes += 1;
+ arc_bytes = checked_add!(arc_bytes, 1);
if (arc_bytes > ARC_MAX_BYTES) && (byte & ARC_MAX_LAST_OCTET != 0) {
return Err(Error::ArcTooBig);
@@ -77,7 +83,7 @@ impl<'a> Arcs<'a> {
result = result << 7 | (byte & 0b1111111) as Arc;
if byte & 0b10000000 == 0 {
- self.cursor = Some(offset + arc_bytes);
+ self.cursor = Some(checked_add!(offset, arc_bytes));
return Ok(Some(result));
}
}
@@ -123,16 +129,21 @@ impl RootArcs {
return Err(Error::ArcInvalid { arc: second_arc });
}
+ // The checks above ensure this operation will not overflow
+ #[allow(clippy::integer_arithmetic)]
let byte = (first_arc * (ARC_MAX_SECOND + 1)) as u8 + second_arc as u8;
+
Ok(Self(byte))
}
/// Get the value of the first arc
+ #[allow(clippy::integer_arithmetic)]
pub(crate) const fn first_arc(self) -> Arc {
self.0 as Arc / (ARC_MAX_SECOND + 1)
}
/// Get the value of the second arc
+ #[allow(clippy::integer_arithmetic)]
pub(crate) const fn second_arc(self) -> Arc {
self.0 as Arc % (ARC_MAX_SECOND + 1)
}
@@ -141,6 +152,8 @@ impl RootArcs {
impl TryFrom<u8> for RootArcs {
type Error = Error;
+ // Ensured not to overflow by constructor invariants
+ #[allow(clippy::integer_arithmetic)]
fn try_from(octet: u8) -> Result<Self> {
let first = octet as Arc / (ARC_MAX_SECOND + 1);
let second = octet as Arc % (ARC_MAX_SECOND + 1);
diff --git a/src/checked.rs b/src/checked.rs
new file mode 100644
index 0000000..7ff16a2
--- /dev/null
+++ b/src/checked.rs
@@ -0,0 +1,11 @@
+//! Checked arithmetic helpers.
+
+/// `const fn`-friendly checked addition helper.
+macro_rules! checked_add {
+ ($a:expr, $b:expr) => {
+ match $a.checked_add($b) {
+ Some(n) => n,
+ None => return Err(Error::Length),
+ }
+ };
+}
diff --git a/src/db.rs b/src/db.rs
index 9491d2f..971990d 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -9,7 +9,7 @@
//! [RFC 5280]: https://datatracker.ietf.org/doc/html/rfc5280
//! [Object Identifier Descriptors]: https://www.iana.org/assignments/ldap-parameters/ldap-parameters.xhtml#ldap-parameters-3
-#![allow(missing_docs)]
+#![allow(clippy::integer_arithmetic, missing_docs)]
mod gen;
diff --git a/src/encoder.rs b/src/encoder.rs
index 877b6ed..4df3aab 100644
--- a/src/encoder.rs
+++ b/src/encoder.rs
@@ -61,6 +61,8 @@ impl Encoder {
self.state = State::FirstArc(arc);
Ok(self)
}
+ // Ensured not to overflow by `ARC_MAX_SECOND` check
+ #[allow(clippy::integer_arithmetic)]
State::FirstArc(first_arc) => {
if arc > ARC_MAX_SECOND {
return Err(Error::ArcInvalid { arc });
@@ -71,10 +73,13 @@ impl Encoder {
self.cursor = 1;
Ok(self)
}
+ // TODO(tarcieri): finer-grained overflow safety / checked arithmetic
+ #[allow(clippy::integer_arithmetic)]
State::Body => {
// Total number of bytes in encoded arc - 1
let nbytes = base128_len(arc);
+ // Shouldn't overflow on any 16-bit+ architectures
if self.cursor + nbytes + 1 >= ObjectIdentifier::MAX_SIZE {
return Err(Error::Length);
}
@@ -109,8 +114,10 @@ impl Encoder {
const fn encode_base128_byte(mut self, mut n: u32, i: usize, continued: bool) -> Result<Self> {
let mask = if continued { 0b10000000 } else { 0 };
+ // Underflow checked by branch
+ #[allow(clippy::integer_arithmetic)]
if n > 0x80 {
- self.bytes[self.cursor + i] = (n & 0b1111111) as u8 | mask;
+ self.bytes[checked_add!(self.cursor, i)] = (n & 0b1111111) as u8 | mask;
n >>= 7;
if i > 0 {
diff --git a/src/error.rs b/src/error.rs
index 72658f2..528ce78 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -44,6 +44,24 @@ pub enum Error {
TrailingDot,
}
+impl Error {
+ /// Escalate this error into a panic.
+ ///
+ /// This is a workaround until `Result::unwrap` is allowed in `const fn`.
+ #[allow(clippy::panic)]
+ pub(crate) const fn panic(self) -> ! {
+ match self {
+ Error::ArcInvalid { .. } | Error::ArcTooBig => panic!("OID contains invalid arc"),
+ Error::Base128 => panic!("OID contains arc with invalid base 128 encoding"),
+ Error::DigitExpected { .. } => panic!("OID expected to start with digit"),
+ Error::Empty => panic!("OID value is empty"),
+ Error::Length => panic!("OID length invalid"),
+ Error::NotEnoughArcs => panic!("OID requires minimum of 3 arcs"),
+ Error::TrailingDot => panic!("OID ends with invalid trailing '.'"),
+ }
+ }
+}
+
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
diff --git a/src/lib.rs b/src/lib.rs
index 01337e5..d847065 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,12 +2,20 @@
#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc = include_str!("../README.md")]
#![doc(
- html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
- html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
- html_root_url = "https://docs.rs/const-oid/0.9.0"
+ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
+ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
+)]
+#![forbid(unsafe_code)]
+#![warn(
+ clippy::integer_arithmetic,
+ clippy::panic,
+ clippy::panic_in_result_fn,
+ clippy::unwrap_used,
+ missing_docs,
+ rust_2018_idioms,
+ unused_lifetimes,
+ unused_qualifications
)]
-#![forbid(unsafe_code, clippy::unwrap_used)]
-#![warn(missing_docs, rust_2018_idioms)]
/// Local Android change: Use std to allow building as a dylib.
#[cfg(android_dylib)]
@@ -16,6 +24,9 @@ extern crate std;
#[cfg(feature = "std")]
extern crate std;
+#[macro_use]
+mod checked;
+
mod arcs;
mod encoder;
mod error;
@@ -39,6 +50,22 @@ pub trait AssociatedOid {
const OID: ObjectIdentifier;
}
+/// A trait which associates a dynamic, `&self`-dependent OID with a type,
+/// which may change depending on the type's value.
+///
+/// This trait is object safe and auto-impl'd for any types which impl
+/// [`AssociatedOid`].
+pub trait DynAssociatedOid {
+ /// Get the OID associated with this value.
+ fn oid(&self) -> ObjectIdentifier;
+}
+
+impl<T: AssociatedOid> DynAssociatedOid for T {
+ fn oid(&self) -> ObjectIdentifier {
+ T::OID
+ }
+}
+
/// Object identifier (OID).
///
/// OIDs are hierarchical structures consisting of "arcs", i.e. integer
@@ -89,13 +116,7 @@ impl ObjectIdentifier {
pub const fn new_unwrap(s: &str) -> Self {
match Self::new(s) {
Ok(oid) => oid,
- Err(Error::ArcInvalid { .. } | Error::ArcTooBig) => panic!("OID contains invalid arc"),
- Err(Error::Base128) => panic!("OID contains arc with invalid base 128 encoding"),
- Err(Error::DigitExpected { .. }) => panic!("OID expected to start with digit"),
- Err(Error::Empty) => panic!("OID value is empty"),
- Err(Error::Length) => panic!("OID length invalid"),
- Err(Error::NotEnoughArcs) => panic!("OID requires minimum of 3 arcs"),
- Err(Error::TrailingDot) => panic!("OID ends with invalid trailing '.'"),
+ Err(err) => err.panic(),
}
}
@@ -225,8 +246,10 @@ impl fmt::Display for ObjectIdentifier {
for (i, arc) in self.arcs().enumerate() {
write!(f, "{}", arc)?;
- if i < len - 1 {
- write!(f, ".")?;
+ if let Some(j) = i.checked_add(1) {
+ if j < len {
+ write!(f, ".")?;
+ }
}
}
diff --git a/src/parser.rs b/src/parser.rs
index 3554ec6..6f875fa 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -49,6 +49,8 @@ impl Parser {
}
Err(err) => Err(err),
},
+ // TODO(tarcieri): checked arithmetic
+ #[allow(clippy::integer_arithmetic)]
[byte @ b'0'..=b'9', remaining @ ..] => {
let digit = byte.saturating_sub(b'0');
self.current_arc = self.current_arc * 10 + digit as Arc;