From b0f47b66c1c79a996989b2c08448ebe1d4379949 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 | 59 +++++++++++++++++++++------------- src/librepgp/stream-common.h | 30 ++++++++++------- src/librepgp/stream-dump.cpp | 6 ++-- src/librepgp/stream-write.cpp | 20 +++++++++--- 5 files changed, 76 insertions(+), 43 deletions(-) diff --git a/src/librepgp/stream-armor.cpp b/src/librepgp/stream-armor.cpp index dc1e12e842..ec4dea5afb 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 392bd8f673..6db418a1d2 100644 --- a/src/librepgp/stream-common.cpp +++ b/src/librepgp/stream-common.cpp @@ -604,20 +604,33 @@ 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) { + /* 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) +{ + try { + *dst = pgp_dest_t(paramsize); + } catch (const std::exception &e) { + return false; // LCOV_EXCL_LINE + } + + return true; } void @@ -626,12 +639,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; @@ -639,13 +652,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; } } @@ -673,7 +686,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; } @@ -759,11 +772,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; @@ -1009,8 +1020,10 @@ init_mem_dest(pgp_dest_t *dst, void *mem, unsigned len) { 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) { + return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } param = (pgp_dest_mem_param_t *) dst->param; diff --git a/src/librepgp/stream-common.h b/src/librepgp/stream-common.h index 91f72bac30..ae10612891 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 3a2ad60d81..03a4022ef3 100644 --- a/src/librepgp/stream-dump.cpp +++ b/src/librepgp/stream-dump.cpp @@ -276,7 +276,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 } @@ -1306,7 +1308,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 56e95f1e55..156db9b031 100644 --- a/src/librepgp/stream-write.cpp +++ b/src/librepgp/stream-write.cpp @@ -235,7 +235,9 @@ init_partial_pkt_dst(pgp_dest_t &dst, pgp_dest_t &writedst) { 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) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } @@ -1008,7 +1010,9 @@ init_encrypted_dst(rnp_ctx_t &ctx, pgp_dest_t &dst, pgp_dest_t &writedst) return RNP_ERROR_BAD_PARAMETERS; } - 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 } auto param = new (std::nothrow) pgp_dest_encrypted_param_t(ctx); @@ -1483,7 +1487,9 @@ init_signed_dst(rnp_ctx_t &ctx, pgp_dest_t &dst, pgp_dest_t &writedst) 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) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } try { @@ -1719,7 +1725,9 @@ init_compressed_dst(rnp_ctx_t &ctx, pgp_dest_t &dst, pgp_dest_t &writedst) 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) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE } @@ -1846,7 +1854,9 @@ init_literal_dst(pgp_literal_hdr_t &hdr, pgp_dest_t &dst, pgp_dest_t &writedst) { 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) { return RNP_ERROR_OUT_OF_MEMORY; // LCOV_EXCL_LINE }