summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-09-29 17:16:14 +0200
committerJustus Winter <justus@sequoia-pgp.org>2023-09-29 17:16:14 +0200
commit20b7c634b216d3ce4ae136bc032bb117ece390b1 (patch)
tree88c20502dc77dff20914369f8f04703b47fa6770
parent06b13acc10164f5bd651e4eb00facce4fa15beb2 (diff)
openpgp: Change the hex parsing to accept odd number of nibbles.
- This came up as the new leak tests use our hex parsing functions to parse /proc/self/maps and apparently Linux will drop leading zeros from addresses. - Fix this by allowing these functions to operate on an odd number of nibbles. I see no reason no reason not to do that, except for the fact that we don't want to establish that it is okay to drop leading zeros from key IDs and fingerprints, hence I preserved the behavior of parsing key IDs and fingerprints.
-rw-r--r--openpgp/src/fingerprint.rs5
-rw-r--r--openpgp/src/fmt.rs17
-rw-r--r--openpgp/src/keyid.rs5
3 files changed, 18 insertions, 9 deletions
diff --git a/openpgp/src/fingerprint.rs b/openpgp/src/fingerprint.rs
index 36cc8662..114366de 100644
--- a/openpgp/src/fingerprint.rs
+++ b/openpgp/src/fingerprint.rs
@@ -89,6 +89,11 @@ impl std::str::FromStr for Fingerprint {
type Err = anyhow::Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
+ if s.chars().filter(|c| ! c.is_whitespace()).count() % 2 == 1 {
+ return Err(crate::Error::InvalidArgument(
+ "Odd number of nibbles".into()).into());
+ }
+
Ok(Self::from_bytes(&crate::fmt::hex::decode_pretty(s)?[..]))
}
}
diff --git a/openpgp/src/fmt.rs b/openpgp/src/fmt.rs
index ea9eec3d..082b92de 100644
--- a/openpgp/src/fmt.rs
+++ b/openpgp/src/fmt.rs
@@ -269,8 +269,7 @@ pub(crate) fn from_hex(hex: &str, pretty: bool) -> Result<Vec<u8>> {
// We need an even number of nibbles.
if nibbles.len() % 2 != 0 {
- return
- Err(Error::InvalidArgument("Odd number of nibbles".into()).into());
+ nibbles.insert(0, 0);
}
let bytes = nibbles.chunks(2).map(|nibbles| {
@@ -337,20 +336,20 @@ mod test {
fn from_hex() {
use super::from_hex as fh;
assert_eq!(fh("", false).ok(), Some(vec![]));
- assert_eq!(fh("0", false).ok(), None);
+ assert_eq!(fh("0", false).ok(), Some(vec![0x00]));
assert_eq!(fh("00", false).ok(), Some(vec![0x00]));
assert_eq!(fh("09", false).ok(), Some(vec![0x09]));
assert_eq!(fh("0f", false).ok(), Some(vec![0x0f]));
assert_eq!(fh("99", false).ok(), Some(vec![0x99]));
assert_eq!(fh("ff", false).ok(), Some(vec![0xff]));
- assert_eq!(fh("000", false).ok(), None);
+ assert_eq!(fh("000", false).ok(), Some(vec![0x00, 0x00]));
assert_eq!(fh("0000", false).ok(), Some(vec![0x00, 0x00]));
assert_eq!(fh("0009", false).ok(), Some(vec![0x00, 0x09]));
assert_eq!(fh("000f", false).ok(), Some(vec![0x00, 0x0f]));
assert_eq!(fh("0099", false).ok(), Some(vec![0x00, 0x99]));
assert_eq!(fh("00ff", false).ok(), Some(vec![0x00, 0xff]));
assert_eq!(fh("\t\n\x0c\r ", false).ok(), None);
- assert_eq!(fh("a", false).ok(), None);
+ assert_eq!(fh("a", false).ok(), Some(vec![0x0a]));
assert_eq!(fh("0x", false).ok(), None);
assert_eq!(fh("0x0", false).ok(), None);
assert_eq!(fh("0x00", false).ok(), None);
@@ -360,13 +359,13 @@ mod test {
fn from_pretty_hex() {
use super::from_hex as fh;
assert_eq!(fh(" ", true).ok(), Some(vec![]));
- assert_eq!(fh(" 0", true).ok(), None);
+ assert_eq!(fh(" 0", true).ok(), Some(vec![0x00]));
assert_eq!(fh(" 00", true).ok(), Some(vec![0x00]));
assert_eq!(fh(" 09", true).ok(), Some(vec![0x09]));
assert_eq!(fh(" 0f", true).ok(), Some(vec![0x0f]));
assert_eq!(fh(" 99", true).ok(), Some(vec![0x99]));
assert_eq!(fh(" ff", true).ok(), Some(vec![0xff]));
- assert_eq!(fh(" 00 0", true).ok(), None);
+ assert_eq!(fh(" 00 0", true).ok(), Some(vec![0x00, 0x00]));
assert_eq!(fh(" 00 00", true).ok(), Some(vec![0x00, 0x00]));
assert_eq!(fh(" 00 09", true).ok(), Some(vec![0x00, 0x09]));
assert_eq!(fh(" 00 0f", true).ok(), Some(vec![0x00, 0x0f]));
@@ -375,9 +374,9 @@ mod test {
assert_eq!(fh("\t\n\x0c\r ", true).ok(), Some(vec![]));
// Fancy Unicode spaces are ok too:
assert_eq!(fh("     23", true).ok(), Some(vec![0x23]));
- assert_eq!(fh("a", true).ok(), None);
+ assert_eq!(fh("a", true).ok(), Some(vec![0x0a]));
assert_eq!(fh(" 0x", true).ok(), Some(vec![]));
- assert_eq!(fh(" 0x0", true).ok(), None);
+ assert_eq!(fh(" 0x0", true).ok(), Some(vec![0x00]));
assert_eq!(fh(" 0x00", true).ok(), Some(vec![0x00]));
}
diff --git a/openpgp/src/keyid.rs b/openpgp/src/keyid.rs
index 1c83c63b..2d880706 100644
--- a/openpgp/src/keyid.rs
+++ b/openpgp/src/keyid.rs
@@ -97,6 +97,11 @@ impl std::str::FromStr for KeyID {
type Err = anyhow::Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
+ if s.chars().filter(|c| ! c.is_whitespace()).count() % 2 == 1 {
+ return Err(Error::InvalidArgument(
+ "Odd number of nibbles".into()).into());
+ }
+
let bytes = crate::fmt::hex::decode_pretty(s)?;
// A KeyID is exactly 8 bytes long.