Change FileOrStdin::open to return a buffered reader with a cookie.

- `FileOrStdin::open` returns a buffered reader without a cookie,
    i.e., a `BufferedReader<()>`.

  - Sequoia functions that a buffered reader, they expect a
    `BufferedReader<openpgp::parse::Cookie>`.

  - Make it easier to use the Sequoia functions by changing
    `FileOrStdin::open` to return a
    `BufferedReader<openpgp::parse::Cookie>`.
This commit is contained in:
Neal H. Walfield 2024-04-12 11:07:51 +02:00
parent 3a0fc2fdb5
commit c2d5f24782
No known key found for this signature in database
GPG Key ID: 6863C9AD5B4D22D3
2 changed files with 18 additions and 12 deletions

View File

@ -25,6 +25,7 @@ use clap::ValueEnum;
use sequoia_openpgp as openpgp; use sequoia_openpgp as openpgp;
use openpgp::armor; use openpgp::armor;
use openpgp::fmt::hex; use openpgp::fmt::hex;
use openpgp::parse::Cookie;
use openpgp::serialize::stream::Armorer; use openpgp::serialize::stream::Armorer;
use openpgp::serialize::stream::Message; use openpgp::serialize::stream::Message;
use openpgp::types::KeyFlags; use openpgp::types::KeyFlags;
@ -132,13 +133,14 @@ impl FileOrStdin {
/// Get a boxed BufferedReader for the FileOrStdin /// Get a boxed BufferedReader for the FileOrStdin
/// ///
/// Opens a file if there is Some(PathBuf), else opens stdin. /// Opens a file if there is Some(PathBuf), else opens stdin.
pub fn open(&self) -> Result<Box<dyn BufferedReader<()>>> { pub fn open<'a>(&self) -> Result<Box<dyn BufferedReader<Cookie> + 'a>> {
if let Some(path) = self.inner() { if let Some(path) = self.inner() {
Ok(Box::new( Ok(Box::new(
File::open(path) File::with_cookie(path, Default::default())
.with_context(|| format!("Failed to open {}", self))?)) .with_context(|| format!("Failed to open {}", self))?))
} else { } else {
Ok(Box::new(Generic::new(stdin(), None))) Ok(Box::new(
Generic::with_cookie(stdin(), None, Default::default())))
} }
} }
} }

View File

@ -7,6 +7,7 @@ use buffered_reader::Limitor;
use sequoia_openpgp as openpgp; use sequoia_openpgp as openpgp;
use openpgp::Packet; use openpgp::Packet;
use openpgp::armor; use openpgp::armor;
use openpgp::parse::Cookie;
use openpgp::parse::Parse; use openpgp::parse::Parse;
use openpgp::parse::PacketParser; use openpgp::parse::PacketParser;
use openpgp::parse::PacketParserResult; use openpgp::parse::PacketParserResult;
@ -23,11 +24,12 @@ const ARMOR_DETECTION_LIMIT: u64 = 1 << 24;
/// Returns the given reader unchanged. If the detection fails, /// Returns the given reader unchanged. If the detection fails,
/// armor::Kind::File is returned as safe default. /// armor::Kind::File is returned as safe default.
fn detect_armor_kind( fn detect_armor_kind(
input: Box<dyn BufferedReader<()>>, input: Box<dyn BufferedReader<Cookie>>,
) -> (Box<dyn BufferedReader<()>>, armor::Kind) { ) -> (Box<dyn BufferedReader<Cookie>>, armor::Kind) {
let mut dup = let dup = Dup::with_cookie(input, Cookie::default());
Limitor::new(Dup::new(input), ARMOR_DETECTION_LIMIT).into_boxed(); let mut limitor = Limitor::with_cookie(
let kind = match PacketParser::from_reader(&mut dup) { dup, ARMOR_DETECTION_LIMIT, Cookie::default()).into_boxed();
let kind = match PacketParser::from_reader(&mut limitor) {
Ok(PacketParserResult::Some(pp)) => match pp.next() { Ok(PacketParserResult::Some(pp)) => match pp.next() {
Ok((Packet::Signature(_), _)) => armor::Kind::Signature, Ok((Packet::Signature(_), _)) => armor::Kind::Signature,
Ok((Packet::SecretKey(_), _)) => armor::Kind::SecretKey, Ok((Packet::SecretKey(_), _)) => armor::Kind::SecretKey,
@ -38,7 +40,7 @@ fn detect_armor_kind(
}, },
_ => armor::Kind::File, _ => armor::Kind::File,
}; };
(dup.into_inner().unwrap().into_inner().unwrap(), kind) (limitor.into_inner().unwrap().into_inner().unwrap(), kind)
} }
pub fn dispatch(config: Config, command: cli::toolbox::armor::Command) pub fn dispatch(config: Config, command: cli::toolbox::armor::Command)
@ -52,16 +54,18 @@ pub fn dispatch(config: Config, command: cli::toolbox::armor::Command)
// Peek at the data. If it looks like it is armored // Peek at the data. If it looks like it is armored
// data, avoid armoring it again. // data, avoid armoring it again.
let mut dup = Limitor::new(Dup::new(input), ARMOR_DETECTION_LIMIT); let dup = Dup::with_cookie(input, Cookie::default());
let mut limitor = Limitor::with_cookie(
dup, ARMOR_DETECTION_LIMIT, Cookie::default());
let (already_armored, have_kind) = { let (already_armored, have_kind) = {
let mut reader = let mut reader =
armor::Reader::from_reader( armor::Reader::from_reader(
&mut dup, &mut limitor,
armor::ReaderMode::Tolerant(None)); armor::ReaderMode::Tolerant(None));
(reader.data(8).is_ok(), reader.kind()) (reader.data(8).is_ok(), reader.kind())
}; };
let mut input = let mut input =
dup.into_boxed().into_inner().unwrap().into_inner().unwrap(); limitor.into_boxed().into_inner().unwrap().into_inner().unwrap();
if already_armored if already_armored
&& (want_kind.is_none() || want_kind == have_kind) && (want_kind.is_none() || want_kind == have_kind)