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
55 changes: 33 additions & 22 deletions src/librepgp/stream-common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,20 +603,31 @@
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) {
RNP_LOG("allocation failed");
throw rnp::rnp_exception(RNP_ERROR_OUT_OF_MEMORY);

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

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-common.cpp#L616

Added line #L616 was not covered by tests
}
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 622 in src/librepgp/stream-common.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-common.cpp#L622

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

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

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-common.cpp#L625-L627

Added lines #L625 - L627 were not covered by tests
}

return true;

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

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-common.cpp#L630

Added line #L630 was not covered by tests
}

void
Expand All @@ -625,26 +636,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 @@ -672,7 +683,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 @@ -758,11 +769,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 @@ -1008,7 +1017,9 @@
{
pgp_dest_mem_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 1022 in src/librepgp/stream-common.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-common.cpp#L1022

Added line #L1022 was not covered by tests
return RNP_ERROR_OUT_OF_MEMORY;
}

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 @@ -275,7 +275,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 280 in src/librepgp/stream-dump.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-dump.cpp#L280

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

Expand Down Expand Up @@ -1289,7 +1291,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 @@ -232,7 +232,9 @@
{
pgp_dest_partial_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 237 in src/librepgp/stream-write.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-write.cpp#L237

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

Expand Down Expand Up @@ -988,7 +990,9 @@
}
}

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

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

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-write.cpp#L995

Added line #L995 was not covered by tests
return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE
}
try {
Expand Down Expand Up @@ -1495,7 +1499,9 @@
/* LCOV_EXCL_END */
}

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

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

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-write.cpp#L1504

Added line #L1504 was not covered by tests
return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE
}
try {
Expand Down Expand Up @@ -1731,7 +1737,9 @@
uint8_t buf;
int zret;

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

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

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-write.cpp#L1742

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

Expand Down Expand Up @@ -1860,7 +1868,9 @@
{
pgp_dest_packet_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 1873 in src/librepgp/stream-write.cpp

View check run for this annotation

Codecov / codecov/patch

src/librepgp/stream-write.cpp#L1873

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

Expand Down
Loading