diff --git a/src/common/varint.h b/src/common/varint.h index 9f8b9a4ab..d544e198a 100644 --- a/src/common/varint.h +++ b/src/common/varint.h @@ -125,4 +125,14 @@ namespace tools { int read_varint(InputIt &&first, InputIt &&last, T &i) { return read_varint::digits>(std::forward(first), std::forward(last), i); } + + template ::value && std::is_unsigned::value>> + constexpr std::size_t get_varint_byte_size(T val) { + std::size_t bytes = 0; + do { + ++bytes; + val >>= 7; + } while (val); + return bytes; + } } diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index ea1508505..a6d7762ff 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -741,15 +741,19 @@ namespace cryptonote { CHECK_AND_ASSERT_MES(extra_nonce.size() <= TX_EXTRA_NONCE_MAX_COUNT, false, "extra nonce could be 255 bytes max"); size_t start_pos = tx_extra.size(); - tx_extra.resize(tx_extra.size() + 2 + extra_nonce.size()); + const std::size_t len_varint_bytes = tools::get_varint_byte_size(extra_nonce.size()); + tx_extra.resize(tx_extra.size() + 1 + len_varint_bytes + extra_nonce.size()); //write tag tx_extra[start_pos] = TX_EXTRA_NONCE; //write len ++start_pos; - tx_extra[start_pos] = static_cast(extra_nonce.size()); + unsigned char * vp = tx_extra.data() + start_pos; + tools::write_varint(vp, extra_nonce.size()); + assert(vp == tx_extra.data() + tx_extra.size() - extra_nonce.size()); //write data - ++start_pos; - memcpy(&tx_extra[start_pos], extra_nonce.data(), extra_nonce.size()); + start_pos += len_varint_bytes; + if (!extra_nonce.empty()) + memcpy(&tx_extra[start_pos], extra_nonce.data(), extra_nonce.size()); return true; } //---------------------------------------------------------------