Skip to content
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
12 changes: 6 additions & 6 deletions src/dpp/etf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -492,12 +492,12 @@ json etf_parser::decode_tuple_large() {

json etf_parser::decode_compressed() {
const uint32_t uncompressedSize = read_32_bits();
unsigned long sourceSize = uncompressedSize;
std::vector<uint8_t> outBuffer;
outBuffer.reserve(uncompressedSize);
const int ret = uncompress((Bytef*)outBuffer.data(), &sourceSize, (const unsigned char*)(data + offset), (uLong)(size - offset));
/* zlib takes this as the capacity of outBuffer and returns the number of bytes it actually wrote */
unsigned long destinationSize = uncompressedSize;
std::vector<uint8_t> outBuffer(uncompressedSize);
const int ret = uncompress((Bytef*)outBuffer.data(), &destinationSize, (const unsigned char*)(data + offset), (uLong)(size - offset));

offset += sourceSize;
offset += destinationSize;
Comment thread
braindigitalis marked this conversation as resolved.
if (ret != Z_OK) {
throw dpp::parse_exception(err_etf, "ETF compressed value: decompresson error");
}
Expand All @@ -506,7 +506,7 @@ json etf_parser::decode_compressed() {
size_t old_size = size;
size_t old_offset = offset;
data = outBuffer.data();
size = uncompressedSize;
size = destinationSize;
offset = 0;
json j = inner_parse();
data = old_data;
Expand Down
26 changes: 26 additions & 0 deletions src/unittest/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,32 @@ Markdown lol \\|\\|spoiler\\|\\| \\~\\~strikethrough\\~\\~ \\`small \\*code\\* b
dpp::base64_encode(reinterpret_cast<unsigned char const *>("vwxyz12"), 7) == "dnd4eXoxMg=="
);

set_test(ETF_COMPRESSED_SHORT, false);
{
/* Version, ett_compressed, a declared uncompressed size of 4096, then a
* deflate stream that only inflates to five bytes: an ett_binary announcing
* 4080 bytes of payload that were never encoded.
*/
const char truncated_term[]{
(char)131, 'P', 0x00, 0x00, 0x10, 0x00,
(char)0x78, (char)0x9c, (char)0xcb, 0x65, 0x60, (char)0xe0,
(char)0xff, 0x00, 0x00, 0x03, 0x34, 0x01, 0x6d
};

/* The announced payload is not there, so decoding must yield null rather
* than a 4080 character string assembled from memory that was never written.
*/
bool etf_result;
dpp::etf_parser etf;
try {
etf_result = etf.parse(std::string(truncated_term, sizeof(truncated_term))).is_null();
}
catch (const dpp::parse_exception&) {
etf_result = false;
}
set_test(ETF_COMPRESSED_SHORT, etf_result);
}

dpp::http_connect_info hci;
set_test(HOSTINFO, false);

Expand Down
1 change: 1 addition & 0 deletions src/unittest/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ DPP_TEST(MD_ESC_1, "Markdown escaping (ignore code block contents)", tf_offline)
DPP_TEST(MD_ESC_2, "Markdown escaping (escape code block contents)", tf_offline);
DPP_TEST(URLENC, "URL encoding", tf_offline);
DPP_TEST(BASE64ENC, "Base 64 encoding", tf_offline);
DPP_TEST(ETF_COMPRESSED_SHORT, "etf_parser: compressed term shorter than its declared size", tf_offline);
DPP_TEST(COMPARISON, "manged object comparison", tf_offline);
DPP_TEST(CHANNELCACHE, "find_channel()", tf_online);
DPP_TEST(CHANNELTYPES, "channel type flags", tf_online);
Expand Down
Loading