Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use vector for pgp_dest_t cache #2299

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/librepgp/stream-armor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,9 @@
rnp_result_t
init_armored_dst(pgp_dest_t *dst, pgp_dest_t *writedst, pgp_armored_msg_t msgtype)
{
if (!init_dst_common(dst, 0)) {
try {
*dst = pgp_dest_t(0);
} catch (const std::exception &e) {

Check warning on line 1079 in src/librepgp/stream-armor.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-armor.cpp#L1079

Added line #L1079 was not covered by tests
return RNP_ERROR_OUT_OF_MEMORY;
}
pgp_dest_armored_param_t *param = new (std::nothrow) pgp_dest_armored_param_t();
Expand Down
59 changes: 36 additions & 23 deletions src/librepgp/stream-common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,20 +604,33 @@
return param->memory;
}

bool
init_dst_common(pgp_dest_t *dst, size_t paramsize)
pgp_dest_t::pgp_dest_t(size_t paramsize)
{
memset(dst, 0, sizeof(*dst));
dst->werr = RNP_SUCCESS;
werr = RNP_SUCCESS;
if (!paramsize) {
return true;
return;
}
/* allocate param */
dst->param = calloc(1, paramsize);
if (!dst->param) {
param = calloc(1, paramsize);

Check warning

Code scanning / CodeQL

Resource not released in destructor Warning

Resource param is acquired by class pgp_dest_t but not released anywhere in this class.
if (!param) {
/* LCOV_EXCL_START */
RNP_LOG("allocation failed");
throw rnp::rnp_exception(RNP_ERROR_OUT_OF_MEMORY);
/* LCOV_EXCL_END */
}
return dst->param;
}

// pgp_dest_t constructor do the same job, but we keep this function to preserve api
bool
init_dst_common(pgp_dest_t *dst, size_t paramsize)

Check warning on line 625 in src/librepgp/stream-common.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-common.cpp#L625

Added line #L625 was not covered by tests
{
try {
*dst = pgp_dest_t(paramsize);
} catch (const std::exception &e) {

Check warning on line 629 in src/librepgp/stream-common.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-common.cpp#L628-L629

Added lines #L628 - L629 were not covered by tests
return false; // LCOV_EXCL_LINE
}

return true;

Check warning on line 633 in src/librepgp/stream-common.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-common.cpp#L633

Added line #L633 was not covered by tests
}

void
Expand All @@ -626,26 +639,26 @@
/* we call write function only if all previous calls succeeded */
if ((len > 0) && (dst->write) && (dst->werr == RNP_SUCCESS)) {
/* if cache non-empty and len will overflow it then fill it and write out */
if ((dst->clen > 0) && (dst->clen + len > sizeof(dst->cache))) {
memcpy(dst->cache + dst->clen, buf, sizeof(dst->cache) - dst->clen);
buf = (uint8_t *) buf + sizeof(dst->cache) - dst->clen;
len -= sizeof(dst->cache) - dst->clen;
dst->werr = dst->write(dst, dst->cache, sizeof(dst->cache));
dst->writeb += sizeof(dst->cache);
if ((dst->clen > 0) && (dst->clen + len > dst->cache.size())) {
memcpy(dst->cache.data() + dst->clen, buf, dst->cache.size() - dst->clen);
buf = (uint8_t *) buf + dst->cache.size() - dst->clen;
len -= dst->cache.size() - dst->clen;
dst->werr = dst->write(dst, dst->cache.data(), dst->cache.size());
dst->writeb += dst->cache.size();
dst->clen = 0;
if (dst->werr != RNP_SUCCESS) {
return;
}
}

/* here everything will fit into the cache or cache is empty */
if (dst->no_cache || (len > sizeof(dst->cache))) {
if (dst->no_cache || (len > dst->cache.size())) {
dst->werr = dst->write(dst, buf, len);
if (!dst->werr) {
dst->writeb += len;
}
} else {
memcpy(dst->cache + dst->clen, buf, len);
memcpy(dst->cache.data() + dst->clen, buf, len);
dst->clen += len;
}
}
Expand Down Expand Up @@ -673,7 +686,7 @@
dst_flush(pgp_dest_t *dst)
{
if ((dst->clen > 0) && (dst->write) && (dst->werr == RNP_SUCCESS)) {
dst->werr = dst->write(dst, dst->cache, dst->clen);
dst->werr = dst->write(dst, dst->cache.data(), dst->clen);
dst->writeb += dst->clen;
dst->clen = 0;
}
Expand Down Expand Up @@ -759,11 +772,9 @@
static rnp_result_t
init_fd_dest(pgp_dest_t *dst, int fd, const char *path)
{
if (!init_dst_common(dst, 0)) {
return RNP_ERROR_OUT_OF_MEMORY;
}

try {
*dst = pgp_dest_t(0);

std::unique_ptr<pgp_dest_file_param_t> param(new pgp_dest_file_param_t());
param->path = path;
param->fd = fd;
Expand Down Expand Up @@ -1009,8 +1020,10 @@
{
pgp_dest_mem_param_t *param;

if (!init_dst_common(dst, sizeof(*param))) {
return RNP_ERROR_OUT_OF_MEMORY;
try {
*dst = pgp_dest_t(sizeof(*param));
} catch (const std::exception &e) {

Check warning on line 1025 in src/librepgp/stream-common.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-common.cpp#L1025

Added line #L1025 was not covered by tests
return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE
}

param = (pgp_dest_mem_param_t *) dst->param;
Expand Down
30 changes: 18 additions & 12 deletions src/librepgp/stream-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,18 +236,24 @@ rnp_result_t read_mem_src(pgp_source_t *src, pgp_source_t *readsrc);
const void *mem_src_get_memory(pgp_source_t *src, bool own = false);

typedef struct pgp_dest_t {
pgp_dest_write_func_t * write;
pgp_dest_finish_func_t *finish;
pgp_dest_close_func_t * close;
pgp_stream_type_t type;
rnp_result_t werr; /* write function may set this to some error code */

size_t writeb; /* number of bytes written */
void * param; /* source-specific additional data */
bool no_cache; /* disable write caching */
uint8_t cache[PGP_OUTPUT_CACHE_SIZE];
unsigned clen; /* number of bytes in cache */
bool finished; /* whether dst_finish was called on dest or not */
pgp_dest_write_func_t * write = nullptr;
pgp_dest_finish_func_t *finish = nullptr;
pgp_dest_close_func_t * close = nullptr;
pgp_stream_type_t type = PGP_STREAM_NULL;
rnp_result_t werr = RNP_SUCCESS; /* write function may set this to some error code */

size_t writeb = 0; /* number of bytes written */
void * param = nullptr; /* source-specific additional data */
bool no_cache = 0; /* disable write caching */
std::vector<uint8_t> cache = std::vector<uint8_t>(PGP_OUTPUT_CACHE_SIZE);
unsigned clen = 0; /* number of bytes in cache */
bool finished = 0; /* whether dst_finish was called on dest or not */

pgp_dest_t(size_t paramsize = 0);

pgp_dest_t &operator=(const pgp_dest_t &) = delete;
pgp_dest_t(const pgp_dest_t &) = delete;
pgp_dest_t &operator=(pgp_dest_t &&) = default;
} pgp_dest_t;

/** @brief helper function to allocate memory for dest's param.
Expand Down
6 changes: 4 additions & 2 deletions src/librepgp/stream-dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,9 @@
{
pgp_dest_indent_param_t *param;

if (!init_dst_common(dst, sizeof(*param))) {
try {
*dst = pgp_dest_t(sizeof(*param));
} catch (const std::exception &e) {

Check warning on line 281 in src/librepgp/stream-dump.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-dump.cpp#L281

Added line #L281 was not covered by tests
return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE
}

Expand Down Expand Up @@ -1306,7 +1308,7 @@
static bool
stream_dump_get_aead_hdr(pgp_source_t *src, pgp_aead_hdr_t *hdr)
{
pgp_dest_t encdst = {};
pgp_dest_t encdst;
uint8_t encpkt[64] = {};

if (init_mem_dest(&encdst, &encpkt, sizeof(encpkt))) {
Expand Down
20 changes: 15 additions & 5 deletions src/librepgp/stream-write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,9 @@
{
pgp_dest_partial_param_t *param = NULL;

if (!init_dst_common(&dst, sizeof(*param))) {
try {
dst = pgp_dest_t(sizeof(*param));
} catch (const std::exception &e) {

Check warning on line 240 in src/librepgp/stream-write.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-write.cpp#L240

Added line #L240 was not covered by tests
return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE
}

Expand Down Expand Up @@ -1008,7 +1010,9 @@
return RNP_ERROR_BAD_PARAMETERS;
}

if (!init_dst_common(&dst, 0)) {
try {
dst = pgp_dest_t(0);
} catch (const std::exception &e) {

Check warning on line 1015 in src/librepgp/stream-write.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-write.cpp#L1015

Added line #L1015 was not covered by tests
return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE
}
auto param = new (std::nothrow) pgp_dest_encrypted_param_t(ctx);
Expand Down Expand Up @@ -1483,7 +1487,9 @@
pgp_dest_signed_param_t *param = NULL;
rnp_result_t ret = RNP_ERROR_GENERIC;

if (!init_dst_common(&dst, 0)) {
try {
dst = pgp_dest_t(0);
} catch (const std::exception &e) {

Check warning on line 1492 in src/librepgp/stream-write.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-write.cpp#L1492

Added line #L1492 was not covered by tests
return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE
}
try {
Expand Down Expand Up @@ -1719,7 +1725,9 @@
uint8_t buf = 0;
int zret = 0;

if (!init_dst_common(&dst, sizeof(*param))) {
try {
dst = pgp_dest_t(sizeof(*param));
} catch (const std::exception &e) {

Check warning on line 1730 in src/librepgp/stream-write.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-write.cpp#L1730

Added line #L1730 was not covered by tests
return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE
}

Expand Down Expand Up @@ -1846,7 +1854,9 @@
{
pgp_dest_packet_param_t *param = NULL;

if (!init_dst_common(&dst, sizeof(*param))) {
try {
dst = pgp_dest_t(sizeof(*param));
} catch (const std::exception &e) {

Check warning on line 1859 in src/librepgp/stream-write.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-write.cpp#L1859

Added line #L1859 was not covered by tests
return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE
}

Expand Down
Loading