Skip to content
This repository was archived by the owner on Aug 19, 2025. It is now read-only.

Commit 6e36748

Browse files
japaricdjc
authored andcommitted
introduce an Error enum
1 parent b3c85f1 commit 6e36748

File tree

3 files changed

+51
-18
lines changed

3 files changed

+51
-18
lines changed

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ mod tests;
5151

5252
/// --- Main crate APIs:
5353
mod pemfile;
54-
pub use pemfile::{read_all, read_one, Item};
54+
pub use pemfile::{read_all, read_one, Error, Item};
5555
use pki_types::PrivateKeyDer;
5656
use pki_types::{
5757
CertificateDer, CertificateRevocationListDer, PrivatePkcs1KeyDer, PrivatePkcs8KeyDer,

src/pemfile.rs

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,25 @@ pub enum Item {
4141
Crl(CertificateRevocationListDer<'static>),
4242
}
4343

44+
/// Errors that may arise when parsing the contents of a PEM file
45+
#[derive(Debug, PartialEq)]
46+
pub enum Error {
47+
/// a section is missing its "END marker" line
48+
MissingSectionEnd {
49+
/// the expected "END marker" line that was not found
50+
end_marker: Vec<u8>,
51+
},
52+
53+
/// syntax error found in the line that starts a new section
54+
IllegalSectionStart {
55+
/// line that contains the syntax error
56+
line: Vec<u8>,
57+
},
58+
59+
/// base64 decode error
60+
Base64Decode(String),
61+
}
62+
4463
/// Extract and decode the next PEM section from `rd`.
4564
///
4665
/// - Ok(None) is returned if there is no PEM section read from `rd`.
@@ -64,9 +83,30 @@ pub fn read_one(rd: &mut dyn io::BufRead) -> Result<Option<Item>, io::Error> {
6483
Some(line.as_slice())
6584
};
6685

67-
match read_one_impl(next_line, &mut section, &mut b64buf)? {
68-
ControlFlow::Break(opt) => return Ok(opt),
69-
ControlFlow::Continue(()) => continue,
86+
match read_one_impl(next_line, &mut section, &mut b64buf) {
87+
Ok(ControlFlow::Break(opt)) => return Ok(opt),
88+
Ok(ControlFlow::Continue(())) => continue,
89+
Err(e) => {
90+
return Err(match e {
91+
Error::MissingSectionEnd { end_marker } => io::Error::new(
92+
ErrorKind::InvalidData,
93+
format!(
94+
"section end {:?} missing",
95+
String::from_utf8_lossy(&end_marker)
96+
),
97+
),
98+
99+
Error::IllegalSectionStart { line } => io::Error::new(
100+
ErrorKind::InvalidData,
101+
format!(
102+
"illegal section start: {:?}",
103+
String::from_utf8_lossy(&line)
104+
),
105+
),
106+
107+
Error::Base64Decode(err) => io::Error::new(ErrorKind::InvalidData, err),
108+
});
109+
}
70110
}
71111
}
72112
}
@@ -75,19 +115,13 @@ fn read_one_impl(
75115
next_line: Option<&[u8]>,
76116
section: &mut Option<(Vec<u8>, Vec<u8>)>,
77117
b64buf: &mut Vec<u8>,
78-
) -> Result<ControlFlow<Option<Item>, ()>, io::Error> {
118+
) -> Result<ControlFlow<Option<Item>, ()>, Error> {
79119
let line = if let Some(line) = next_line {
80120
line
81121
} else {
82122
// EOF
83123
return match section.take() {
84-
Some((_, end_marker)) => Err(io::Error::new(
85-
ErrorKind::InvalidData,
86-
format!(
87-
"section end {:?} missing",
88-
String::from_utf8_lossy(&end_marker)
89-
),
90-
)),
124+
Some((_, end_marker)) => Err(Error::MissingSectionEnd { end_marker }),
91125
None => Ok(ControlFlow::Break(None)),
92126
};
93127
};
@@ -106,10 +140,9 @@ fn read_one_impl(
106140
}
107141

108142
if trailer != 5 {
109-
return Err(io::Error::new(
110-
ErrorKind::InvalidData,
111-
format!("illegal section start: {:?}", String::from_utf8_lossy(line)),
112-
));
143+
return Err(Error::IllegalSectionStart {
144+
line: line.to_vec(),
145+
});
113146
}
114147

115148
let ty = &line[11..pos];
@@ -125,7 +158,7 @@ fn read_one_impl(
125158
if line.starts_with(end_marker) {
126159
let der = base64::ENGINE
127160
.decode(&b64buf)
128-
.map_err(|err| io::Error::new(ErrorKind::InvalidData, err))?;
161+
.map_err(|err| Error::Base64Decode(format!("{err:?}")))?;
129162

130163
let item = match section_type.as_slice() {
131164
b"CERTIFICATE" => Some(Item::X509Certificate(der.into())),

src/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ mod unit {
5959
-----END RSA PRIVATE KEY-----\n"
6060
)
6161
),
62-
"Err(Custom { kind: InvalidData, error: InvalidByte(1, 61) })"
62+
"Err(Custom { kind: InvalidData, error: \"InvalidByte(1, 61)\" })"
6363
);
6464
}
6565

0 commit comments

Comments
 (0)