diff options
author | Neal H. Walfield <neal@pep.foundation> | 2023-01-06 11:39:05 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2023-01-06 12:41:41 +0100 |
commit | 3e188fb312ad4db1395f5e836bffaf2034b88a42 (patch) | |
tree | 9dd82f9c1b845a28b6da8b3ea8616b49bb1aa824 /openpgp/src/armor.rs | |
parent | 81c471292d3b15f48d236f8432aacf2b734f9d1e (diff) |
buffered-reader, openpgp: Fix buffering.
- When `buffered_reader::Generic::data_helper` is called and the
amount of data that is requested exceeds the amount of data that
is available, we read from the underlying reader.
- When determining how much to read from the underlying reader, we
took the maximum of the amount requested and the default buffer
size, and then subtracted the amount of data that is available.
- This means that when the amount requested is greater than the
buffer size, we would read exactly the amount requested. This is
problematic for two reasons. First, it is not unusual for a user
of a `BufferedReader` to not consume the data (e.g., a
`buffer_reader::Dup` never consumes data). In that case, once
calls to `BufferedReader::data` request more than the default
buffer size, the `BufferedReader` would forward any reads to the
underlying reader, and append the result to the available data to
create a single continuous `Vec<u8>`. Second, many of these reads
are for just one more byte than is available. The consequence is
that once the amount requested exceeds the amount available, many
subsequent reads would read from the underlying reader, and
`memcpy` the data held by the `BufferedReader`, which destroyed the
performance.
- Avoid most of the reads and the `memcpy`s by changing the behavior
of `buffered_reader::Generic::data_helper` as follows: if the
amount requested exceeds the amount available, try to read the
amount requested plus the buffer size minus what is available.
- Make the same change to `openpgp::armor::Reader`.
- Fixes #969.
Co-authored-by: Justus Winter <justus@sequoia-pgp.org>
Diffstat (limited to 'openpgp/src/armor.rs')
-rw-r--r-- | openpgp/src/armor.rs | 5 |
1 files changed, 2 insertions, 3 deletions
diff --git a/openpgp/src/armor.rs b/openpgp/src/armor.rs index 144df004..08a16f46 100644 --- a/openpgp/src/armor.rs +++ b/openpgp/src/armor.rs @@ -1554,9 +1554,8 @@ impl<'a> Reader<'a> { // The caller wants more data than we have readily // available. Read some more. - let capacity : usize = cmp::max(cmp::max( - DEFAULT_BUF_SIZE, - 2 * self.preferred_chunk_size), amount); + let capacity : usize = amount + + cmp::max(DEFAULT_BUF_SIZE, 2 * self.preferred_chunk_size); let mut buffer_new = self.unused_buffer.take() .map(|mut v| { |