From 2254d36fc547fa83cc7a83d7f3b616547b9b2614 Mon Sep 17 00:00:00 2001 From: Denys Date: Wed, 11 Dec 2024 00:55:07 +0200 Subject: [PATCH] Add constructor for pgp_dest_t --- src/librepgp/stream-armor.cpp | 4 ++- src/librepgp/stream-common.cpp | 55 ++++++++++++++++++++-------------- src/librepgp/stream-common.h | 30 +++++++++++-------- src/librepgp/stream-dump.cpp | 6 ++-- src/librepgp/stream-write.cpp | 20 +++++++++---- 5 files changed, 73 insertions(+), 42 deletions(-) diff --git a/src/librepgp/stream-armor.cpp b/src/librepgp/stream-armor.cpp index dc1e12e84..ec4dea5af 100644 --- a/src/librepgp/stream-armor.cpp +++ b/src/librepgp/stream-armor.cpp @@ -1074,7 +1074,9 @@ armored_dst_close(pgp_dest_t *dst, bool discard) 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) { return RNP_ERROR_OUT_OF_MEMORY; } pgp_dest_armored_param_t *param = new (std::nothrow) pgp_dest_armored_param_t(); diff --git a/src/librepgp/stream-common.cpp b/src/librepgp/stream-common.cpp index c7ba9326d..aff138fb9 100644 --- a/src/librepgp/stream-common.cpp +++ b/src/librepgp/stream-common.cpp @@ -603,20 +603,31 @@ mem_src_get_memory(pgp_source_t *src, bool own) 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); + if (!param) { RNP_LOG("allocation failed"); + throw rnp::rnp_exception(RNP_ERROR_OUT_OF_MEMORY); } - 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) +{ + try { + *dst = pgp_dest_t(paramsize); + } catch (const std::exception &e) { + return false; + } + + return true; } void @@ -625,12 +636,12 @@ dst_write(pgp_dest_t *dst, const void *buf, size_t len) /* 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; @@ -638,13 +649,13 @@ dst_write(pgp_dest_t *dst, const void *buf, size_t len) } /* 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; } } @@ -672,7 +683,7 @@ void 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; } @@ -758,11 +769,9 @@ file_dst_close(pgp_dest_t *dst, bool discard) 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 param(new pgp_dest_file_param_t()); param->path = path; param->fd = fd; @@ -1008,7 +1017,9 @@ init_mem_dest(pgp_dest_t *dst, void *mem, unsigned len) { 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) { return RNP_ERROR_OUT_OF_MEMORY; } diff --git a/src/librepgp/stream-common.h b/src/librepgp/stream-common.h index 51d762158..78a748f78 100644 --- a/src/librepgp/stream-common.h +++ b/src/librepgp/stream-common.h @@ -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 cache = std::vector(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. diff --git a/src/librepgp/stream-dump.cpp b/src/librepgp/stream-dump.cpp index 93d5f43e7..693194bf8 100644 --- a/src/librepgp/stream-dump.cpp +++ b/src/librepgp/stream-dump.cpp @@ -275,7 +275,9 @@ init_indent_dest(pgp_dest_t *dst, pgp_dest_t *origdst) { 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) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } @@ -1289,7 +1291,7 @@ stream_dump_sk_session_key(pgp_source_t *src, pgp_dest_t *dst) 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))) { diff --git a/src/librepgp/stream-write.cpp b/src/librepgp/stream-write.cpp index f50cd3601..cd42f06f6 100644 --- a/src/librepgp/stream-write.cpp +++ b/src/librepgp/stream-write.cpp @@ -232,7 +232,9 @@ init_partial_pkt_dst(pgp_dest_t *dst, pgp_dest_t *writedst) { 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) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } @@ -988,7 +990,9 @@ init_encrypted_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *wr } } - if (!init_dst_common(dst, 0)) { + try { + *dst = pgp_dest_t(0); + } catch (const std::exception &e) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } try { @@ -1495,7 +1499,9 @@ init_signed_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *write /* LCOV_EXCL_END */ } - if (!init_dst_common(dst, 0)) { + try { + *dst = pgp_dest_t(0); + } catch (const std::exception &e) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } try { @@ -1731,7 +1737,9 @@ init_compressed_dst(pgp_write_handler_t *handler, pgp_dest_t *dst, pgp_dest_t *w uint8_t buf; int zret; - if (!init_dst_common(dst, sizeof(*param))) { + try { + *dst = pgp_dest_t(sizeof(*param)); + } catch (const std::exception &e) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } @@ -1860,7 +1868,9 @@ init_literal_dst(pgp_literal_hdr_t &hdr, pgp_dest_t *dst, pgp_dest_t *writedst) { 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) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE }