Skip to content

Commit db7e730

Browse files
Improve checks for sequence lengths (#327)
* Refs #24566. Improve tests. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #24566. Check sequence length in XCDR2 path. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #24566. Check dheader and improve error state. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #24566. Remove unused variables. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> * Refs #24566. Uncrustify. Signed-off-by: Miguel Company <miguelcompany@eprosima.com> --------- Signed-off-by: Miguel Company <miguelcompany@eprosima.com>
1 parent a6c31c0 commit db7e730

2 files changed

Lines changed: 1773 additions & 1609 deletions

File tree

include/fastcdr/Cdr.h

Lines changed: 139 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,21 +1830,41 @@ class Cdr
18301830
Cdr& deserialize(
18311831
std::array<_T, _Size>& array_t)
18321832
{
1833+
state state_before_error(*this);
1834+
18331835
if (CdrVersion::XCDRv2 == cdr_version_ && !is_multi_array_primitive(&array_t))
18341836
{
18351837
uint32_t dheader {0};
18361838
deserialize(dheader);
18371839

1840+
if ((end_ - offset_) < dheader)
1841+
{
1842+
set_state(state_before_error);
1843+
throw exception::NotEnoughMemoryException(
1844+
exception::NotEnoughMemoryException::NOT_ENOUGH_MEMORY_MESSAGE_DEFAULT);
1845+
}
1846+
18381847
uint32_t count {0};
1839-
auto offset = offset_;
1840-
while (offset_ - offset < dheader && count < _Size)
1848+
auto last_offset = offset_;
1849+
last_offset += dheader;
1850+
1851+
try
1852+
{
1853+
while (last_offset - offset_ > 0 && count < _Size)
1854+
{
1855+
deserialize_array(&array_t.data()[count], 1);
1856+
++count;
1857+
}
1858+
}
1859+
catch (exception::Exception& ex)
18411860
{
1842-
deserialize_array(&array_t.data()[count], 1);
1843-
++count;
1861+
set_state(state_before_error);
1862+
ex.raise();
18441863
}
18451864

1846-
if (offset_ - offset != dheader)
1865+
if (last_offset - offset_ != 0)
18471866
{
1867+
set_state(state_before_error);
18481868
throw exception::BadParamException("Member size greater than size specified by DHEADER");
18491869
}
18501870
}
@@ -1868,42 +1888,64 @@ class Cdr
18681888
std::vector<_T>& vector_t)
18691889
{
18701890
uint32_t sequence_length {0};
1891+
state state_before_error(*this);
18711892

18721893
if (CdrVersion::XCDRv2 == cdr_version_)
18731894
{
18741895
uint32_t dheader {0};
18751896
deserialize(dheader);
18761897

1877-
auto offset = offset_;
1898+
if (((end_ - offset_) < dheader) || (dheader < 4))
1899+
{
1900+
set_state(state_before_error);
1901+
throw exception::NotEnoughMemoryException(
1902+
exception::NotEnoughMemoryException::NOT_ENOUGH_MEMORY_MESSAGE_DEFAULT);
1903+
}
1904+
1905+
auto last_offset = offset_;
1906+
last_offset += dheader;
18781907

18791908
deserialize(sequence_length);
18801909

18811910
if (0 == sequence_length)
18821911
{
18831912
vector_t.clear();
1884-
return *this;
18851913
}
18861914
else
18871915
{
1888-
vector_t.resize(sequence_length);
1889-
}
1916+
if ((last_offset - offset_) < sequence_length)
1917+
{
1918+
set_state(state_before_error);
1919+
throw exception::NotEnoughMemoryException(
1920+
exception::NotEnoughMemoryException::NOT_ENOUGH_MEMORY_MESSAGE_DEFAULT);
1921+
}
18901922

1891-
uint32_t count {0};
1892-
while (offset_ - offset < dheader && count < sequence_length)
1893-
{
1894-
deserialize(vector_t.data()[count]);
1895-
++count;
1923+
try
1924+
{
1925+
vector_t.resize(sequence_length);
1926+
1927+
uint32_t count {0};
1928+
while (last_offset - offset_ > 0 && count < sequence_length)
1929+
{
1930+
deserialize(vector_t.data()[count]);
1931+
++count;
1932+
}
1933+
}
1934+
catch (exception::Exception& ex)
1935+
{
1936+
set_state(state_before_error);
1937+
ex.raise();
1938+
}
18961939
}
18971940

1898-
if (offset_ - offset != dheader)
1941+
if (last_offset - offset_ != 0)
18991942
{
1943+
set_state(state_before_error);
19001944
throw exception::BadParamException("Member size differs from the size specified by DHEADER");
19011945
}
19021946
}
19031947
else
19041948
{
1905-
state state_before_error(*this);
1906-
19071949
deserialize(sequence_length);
19081950

19091951
if (sequence_length == 0)
@@ -2001,38 +2043,56 @@ class Cdr
20012043
Cdr& deserialize(
20022044
std::map<_K, _T>& map_t)
20032045
{
2046+
state state_before_error(*this);
2047+
20042048
if (CdrVersion::XCDRv2 == cdr_version_)
20052049
{
20062050
uint32_t dheader {0};
20072051
deserialize(dheader);
20082052

2009-
auto offset = offset_;
2053+
if (((end_ - offset_) < dheader) || (dheader < 4))
2054+
{
2055+
set_state(state_before_error);
2056+
throw exception::NotEnoughMemoryException(
2057+
exception::NotEnoughMemoryException::NOT_ENOUGH_MEMORY_MESSAGE_DEFAULT);
2058+
}
2059+
2060+
auto last_offset = offset_;
2061+
last_offset += dheader;
20102062

20112063
uint32_t map_length {0};
20122064
deserialize(map_length);
20132065

20142066
map_t.clear();
20152067

2016-
uint32_t count {0};
2017-
while (offset_ - offset < dheader && count < map_length)
2068+
try
20182069
{
2019-
_K key;
2020-
_T val;
2021-
deserialize(key);
2022-
deserialize(val);
2023-
map_t.emplace(std::pair<_K, _T>(std::move(key), std::move(val)));
2024-
++count;
2070+
uint32_t count {0};
2071+
while (last_offset - offset_ > 0 && count < map_length)
2072+
{
2073+
_K key;
2074+
_T val;
2075+
deserialize(key);
2076+
deserialize(val);
2077+
map_t.emplace(std::pair<_K, _T>(std::move(key), std::move(val)));
2078+
++count;
2079+
}
2080+
}
2081+
catch (exception::Exception& ex)
2082+
{
2083+
set_state(state_before_error);
2084+
ex.raise();
20252085
}
20262086

2027-
if (offset_ - offset != dheader)
2087+
if (last_offset - offset_ != 0)
20282088
{
2089+
set_state(state_before_error);
20292090
throw exception::BadParamException("Member size greater than size specified by DHEADER");
20302091
}
20312092
}
20322093
else
20332094
{
20342095
uint32_t sequence_length = 0;
2035-
state state_(*this);
20362096

20372097
deserialize(sequence_length);
20382098

@@ -2051,7 +2111,7 @@ class Cdr
20512111
}
20522112
catch (exception::Exception& ex)
20532113
{
2054-
set_state(state_);
2114+
set_state(state_before_error);
20552115
ex.raise();
20562116
}
20572117
}
@@ -2407,21 +2467,40 @@ class Cdr
24072467
Cdr& deserialize_array(
24082468
std::vector<_T>& value)
24092469
{
2470+
state state_before_error(*this);
2471+
24102472
if (CdrVersion::XCDRv2 == cdr_version_)
24112473
{
24122474
uint32_t dheader {0};
24132475
deserialize(dheader);
24142476

2477+
if ((end_ - offset_) < dheader)
2478+
{
2479+
set_state(state_before_error);
2480+
throw exception::NotEnoughMemoryException(
2481+
exception::NotEnoughMemoryException::NOT_ENOUGH_MEMORY_MESSAGE_DEFAULT);
2482+
}
2483+
24152484
uint32_t count {0};
2416-
auto offset = offset_;
2417-
while (offset_ - offset < dheader && count < value.size())
2485+
auto last_offset = offset_;
2486+
last_offset += dheader;
2487+
try
24182488
{
2419-
deserialize_array(&value.data()[count], 1);
2420-
++count;
2489+
while (last_offset - offset_ > 0 && count < value.size())
2490+
{
2491+
deserialize_array(&value.data()[count], 1);
2492+
++count;
2493+
}
2494+
}
2495+
catch (exception::Exception& ex)
2496+
{
2497+
set_state(state_before_error);
2498+
ex.raise();
24212499
}
24222500

2423-
if (offset_ - offset != dheader)
2501+
if (offset_ != last_offset)
24242502
{
2503+
set_state(state_before_error);
24252504
throw exception::BadParamException("Member size greater than size specified by DHEADER");
24262505
}
24272506
}
@@ -2502,28 +2581,50 @@ class Cdr
25022581
size_t& num_elements)
25032582
{
25042583
uint32_t sequence_length {0};
2584+
state state_before_error(*this);
25052585

25062586
if (CdrVersion::XCDRv2 == cdr_version_)
25072587
{
25082588
uint32_t dheader {0};
25092589
deserialize(dheader);
25102590

2511-
auto offset = offset_;
2591+
if (((end_ - offset_) < dheader) || (dheader < 4))
2592+
{
2593+
set_state(state_before_error);
2594+
throw exception::NotEnoughMemoryException(
2595+
exception::NotEnoughMemoryException::NOT_ENOUGH_MEMORY_MESSAGE_DEFAULT);
2596+
}
2597+
2598+
auto last_offset = offset_;
2599+
last_offset += dheader;
25122600

25132601
deserialize(sequence_length);
2602+
if (0 == sequence_length)
2603+
{
2604+
sequence_t = NULL;
2605+
num_elements = 0;
2606+
return *this;
2607+
}
2608+
2609+
if ((last_offset - offset_) < sequence_length)
2610+
{
2611+
set_state(state_before_error);
2612+
throw exception::NotEnoughMemoryException(
2613+
exception::NotEnoughMemoryException::NOT_ENOUGH_MEMORY_MESSAGE_DEFAULT);
2614+
}
25142615

25152616
try
25162617
{
25172618
sequence_t = reinterpret_cast<_T*>(calloc(sequence_length, sizeof(_T)));
25182619

25192620
uint32_t count {0};
2520-
while (offset_ - offset < dheader && count < sequence_length)
2621+
while (last_offset - offset_ > 0 && count < sequence_length)
25212622
{
25222623
deserialize(sequence_t[count]);
25232624
++count;
25242625
}
25252626

2526-
if (offset_ - offset != dheader)
2627+
if (last_offset - offset_ != 0)
25272628
{
25282629
throw exception::BadParamException("Member size greater than size specified by DHEADER");
25292630
}
@@ -2532,13 +2633,12 @@ class Cdr
25322633
{
25332634
free(sequence_t);
25342635
sequence_t = NULL;
2636+
set_state(state_before_error);
25352637
ex.raise();
25362638
}
25372639
}
25382640
else
25392641
{
2540-
state state_before_error(*this);
2541-
25422642
deserialize(sequence_length);
25432643

25442644
if ((end_ - offset_) < sequence_length)

0 commit comments

Comments
 (0)