stream: check for address overflows in memory_stream
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
406d14746f
commit
191f3bb2f9
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023-2025 Amebis
|
||||
*/
|
||||
@ -73,7 +73,8 @@ namespace stdex
|
||||
constexpr fsize_t fsize_max = UINT64_MAX;
|
||||
|
||||
constexpr size_t iterate_count = 0x10;
|
||||
constexpr size_t default_block_size = 0x10000; ///< Amount of space used by copy or reallocation increments
|
||||
constexpr int default_block_pow = 16; ///< Copy or reallocation increments use 2^default_block_pow blocks
|
||||
constexpr size_t default_block_size = 1 << default_block_pow; ///< Amount of space used by copy or reallocation increments
|
||||
constexpr utf16_t utf16_bom = u'\ufeff'; ///< Byte-order-mark written at each UTF-16 file start
|
||||
constexpr utf32_t utf32_bom = U'\ufeff'; ///< Byte-order-mark written at each UTF-32 file start
|
||||
constexpr const char utf8_bom[3] = { '\xef', '\xbb', '\xbf' }; ///> UTF-8 byte-order-mark
|
||||
@ -3451,7 +3452,13 @@ namespace stdex
|
||||
m_state = state_t::fail;
|
||||
return;
|
||||
}
|
||||
size_t reserved = tight ? required : ((required + required / 4 + (default_block_size - 1)) / default_block_size) * default_block_size;
|
||||
size_t reserved;
|
||||
if (tight)
|
||||
reserved = required;
|
||||
else {
|
||||
reserved = stdex::add(required, required >> 2);
|
||||
reserved = stdex::align_up(reserved, default_block_pow);
|
||||
}
|
||||
auto data = reinterpret_cast<uint8_t*>(realloc(m_data, reserved));
|
||||
if (!data && reserved) _Unlikely_ {
|
||||
m_state = state_t::fail;
|
||||
@ -3600,7 +3607,7 @@ namespace stdex
|
||||
data = 0;
|
||||
return *this;
|
||||
}
|
||||
size_t end_offset = m_offset + sizeof(T);
|
||||
size_t end_offset = stdex::add(m_offset, sizeof(T));
|
||||
if (end_offset <= m_size) {
|
||||
data = LE2HE(*reinterpret_cast<T*>(&m_data[m_offset]));
|
||||
m_offset = end_offset;
|
||||
@ -3640,7 +3647,7 @@ namespace stdex
|
||||
data.clear();
|
||||
return *this;
|
||||
}
|
||||
size_t end_offset = m_offset + sizeof(uint32_t);
|
||||
size_t end_offset = stdex::add(m_offset, sizeof(uint32_t));
|
||||
if (end_offset <= m_size) {
|
||||
uint32_t num_chars = LE2HE(*reinterpret_cast<uint32_t*>(&m_data[m_offset]));
|
||||
m_offset = end_offset;
|
||||
@ -3669,7 +3676,7 @@ namespace stdex
|
||||
#if SET_FILE_OP_TIMES
|
||||
m_atime = m_mtime = time_point::now();
|
||||
#endif
|
||||
size_t end_offset = m_offset + length;
|
||||
size_t end_offset = stdex::add(m_offset, length);
|
||||
if (end_offset > m_reserved) {
|
||||
reserve(end_offset);
|
||||
if (!ok()) _Unlikely_
|
||||
@ -3691,7 +3698,7 @@ namespace stdex
|
||||
#if SET_FILE_OP_TIMES
|
||||
m_atime = m_mtime = time_point::now();
|
||||
#endif
|
||||
size_t end_offset = m_offset + amount;
|
||||
size_t end_offset = stdex::add(m_offset, amount);
|
||||
if (end_offset > m_reserved) {
|
||||
reserve(end_offset);
|
||||
if (!ok()) _Unlikely_
|
||||
@ -3726,7 +3733,7 @@ namespace stdex
|
||||
#endif
|
||||
if (CHECK_STREAM_STATE && !ok()) _Unlikely_
|
||||
return *this;
|
||||
size_t end_offset = m_offset + sizeof(T);
|
||||
size_t end_offset = stdex::add(m_offset, sizeof(T));
|
||||
if (end_offset > m_reserved) {
|
||||
reserve(end_offset);
|
||||
if (!ok()) _Unlikely_
|
||||
@ -3767,9 +3774,9 @@ namespace stdex
|
||||
size_t num_chars = stdex::strlen(data);
|
||||
if (num_chars > UINT32_MAX)
|
||||
throw std::invalid_argument("string too long");
|
||||
size_t size_chars = num_chars * sizeof(T);
|
||||
size_t size = sizeof(uint32_t) + size_chars;
|
||||
size_t end_offset = m_offset + size;
|
||||
size_t size_chars = stdex::mul(num_chars, sizeof(T));
|
||||
size_t size = stdex::add(sizeof(uint32_t), size_chars);
|
||||
size_t end_offset = stdex::add(m_offset, size);
|
||||
if (end_offset > m_reserved) {
|
||||
reserve(end_offset);
|
||||
if (!ok()) _Unlikely_
|
||||
@ -3812,9 +3819,9 @@ namespace stdex
|
||||
size_t num_chars = data.size();
|
||||
if (num_chars > UINT32_MAX)
|
||||
throw std::invalid_argument("string too long");
|
||||
size_t size_chars = num_chars * sizeof(T);
|
||||
size_t size = sizeof(uint32_t) + size_chars;
|
||||
size_t end_offset = m_offset + size;
|
||||
size_t size_chars = stdex::mul(num_chars, sizeof(T));
|
||||
size_t size = stdex::add(sizeof(uint32_t), size_chars);
|
||||
size_t end_offset = stdex::add(m_offset, size);
|
||||
if (end_offset > m_reserved) {
|
||||
reserve(end_offset);
|
||||
if (!ok()) _Unlikely_
|
||||
|
Loading…
x
Reference in New Issue
Block a user