improve handling of olm_session_describe when buffer is too short
This commit is contained in:
parent
2dbeea2f1d
commit
c23ce70fc6
2 changed files with 48 additions and 13 deletions
|
@ -387,7 +387,10 @@ OLM_EXPORT int olm_session_has_received_message(
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a null-terminated string describing the internal state of an olm
|
* Write a null-terminated string describing the internal state of an olm
|
||||||
* session to the buffer provided for debugging and logging purposes.
|
* session to the buffer provided for debugging and logging purposes. If the
|
||||||
|
* buffer is not large enough to hold the entire string, it will be truncated
|
||||||
|
* and will end with "...". A buffer length of 600 will be enough to hold any
|
||||||
|
* output.
|
||||||
*/
|
*/
|
||||||
OLM_EXPORT void olm_session_describe(OlmSession * session, char *buf, size_t buflen);
|
OLM_EXPORT void olm_session_describe(OlmSession * session, char *buf, size_t buflen);
|
||||||
|
|
||||||
|
|
|
@ -398,39 +398,71 @@ std::size_t olm::Session::decrypt(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make the description end with "..." instead of stopping abruptly with no
|
||||||
|
// warning
|
||||||
|
void elide_description(char *end) {
|
||||||
|
end[-3] = '.';
|
||||||
|
end[-2] = '.';
|
||||||
|
end[-1] = '.';
|
||||||
|
end[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
void olm::Session::describe(char *describe_buffer, size_t buflen) {
|
void olm::Session::describe(char *describe_buffer, size_t buflen) {
|
||||||
if (buflen == 0) return;
|
// how much of the buffer is remaining (this is an int rather than a size_t
|
||||||
|
// because it will get compared to the return value from snprintf)
|
||||||
|
int remaining = buflen;
|
||||||
|
// do nothing if we have a zero-length buffer, or if buflen > INT_MAX,
|
||||||
|
// resulting in an overflow
|
||||||
|
if (remaining <= 0) return;
|
||||||
|
|
||||||
describe_buffer[0] = '\0';
|
describe_buffer[0] = '\0';
|
||||||
char *buf_pos = describe_buffer;
|
// we need at least 23 characters to get any sort of meaningful
|
||||||
|
// information, so bail if we don't have that. (But more importantly, we
|
||||||
|
// need it to be at least 4 so that elide_description doesn't go out of
|
||||||
|
// bounds.)
|
||||||
|
if (remaining < 23) return;
|
||||||
|
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
|
// check that snprintf didn't return an error or reach the end of the buffer
|
||||||
|
#define CHECK_SIZE_AND_ADVANCE \
|
||||||
|
if (size > remaining) { \
|
||||||
|
return elide_description(describe_buffer + remaining - 1); \
|
||||||
|
} else if (size > 0) { \
|
||||||
|
describe_buffer += size; \
|
||||||
|
remaining -= size; \
|
||||||
|
} else { \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
size = snprintf(
|
size = snprintf(
|
||||||
buf_pos, buflen - (buf_pos - describe_buffer),
|
describe_buffer, remaining,
|
||||||
"sender chain index: %d ", ratchet.sender_chain[0].chain_key.index
|
"sender chain index: %d ", ratchet.sender_chain[0].chain_key.index
|
||||||
);
|
);
|
||||||
if (size > 0) buf_pos += size;
|
CHECK_SIZE_AND_ADVANCE;
|
||||||
|
|
||||||
|
size = snprintf(describe_buffer, remaining, "receiver chain indices:");
|
||||||
|
CHECK_SIZE_AND_ADVANCE;
|
||||||
|
|
||||||
size = snprintf(buf_pos, buflen - (buf_pos - describe_buffer), "receiver chain indices:");
|
|
||||||
if (size > 0) buf_pos += size;
|
|
||||||
for (size_t i = 0; i < ratchet.receiver_chains.size(); ++i) {
|
for (size_t i = 0; i < ratchet.receiver_chains.size(); ++i) {
|
||||||
size = snprintf(
|
size = snprintf(
|
||||||
buf_pos, buflen - (buf_pos - describe_buffer),
|
describe_buffer, remaining,
|
||||||
" %d", ratchet.receiver_chains[i].chain_key.index
|
" %d", ratchet.receiver_chains[i].chain_key.index
|
||||||
);
|
);
|
||||||
if (size > 0) buf_pos += size;
|
CHECK_SIZE_AND_ADVANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = snprintf(buf_pos, buflen - (buf_pos - describe_buffer), " skipped message keys:");
|
size = snprintf(describe_buffer, remaining, " skipped message keys:");
|
||||||
if (size >= 0) buf_pos += size;
|
CHECK_SIZE_AND_ADVANCE;
|
||||||
|
|
||||||
for (size_t i = 0; i < ratchet.skipped_message_keys.size(); ++i) {
|
for (size_t i = 0; i < ratchet.skipped_message_keys.size(); ++i) {
|
||||||
size = snprintf(
|
size = snprintf(
|
||||||
buf_pos, buflen - (buf_pos - describe_buffer),
|
describe_buffer, remaining,
|
||||||
" %d", ratchet.skipped_message_keys[i].message_key.index
|
" %d", ratchet.skipped_message_keys[i].message_key.index
|
||||||
);
|
);
|
||||||
if (size > 0) buf_pos += size;
|
CHECK_SIZE_AND_ADVANCE;
|
||||||
}
|
}
|
||||||
|
#undef CHECK_SIZE_AND_ADVANCE
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
Loading…
Reference in a new issue