summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2023-01-04 17:18:31 -0500
committerNat Goodspeed <nat@lindenlab.com>2023-01-04 17:18:31 -0500
commit99c040ea9976e90caec9dedd942badc1c43822e7 (patch)
treebdf19da22da0dcf050656af97132fe0b789f35d6
parent4093d5b1ebe6b0eb50473d5161042ac3a1b7f6b2 (diff)
DRTVWR-575: Fix possible bad indexing in LLSD::operator[](size_t).
One could argue that passing a negative index to an LLSD array should do something other than shrug and reference element [0], but as that's legacy behavior, it seems all too likely that the viewer sometimes relies on it. This specific problem arises if the index passed to operator[]() is negative -- either with the previous Integer parameter or with size_t (which of course reinterprets the negative index as hugely positive). The non-const ImplArray::ref() overload checks parameter 'i' and, if it appears negative, sets internal 'index' to 0. But in the next stanza, if (index >= existing size()), it calls resize() to scale the internal array up to one more than the requested index. The trouble is that it passed resize(i + 1), not the adjusted resize(index + 1). With a requested index of exactly -1, that would pass resize(0), which would result in the ensuing array[0] reference being invalid. With a requested index less than -1, that would pass resize(hugely positive) -- since, whether operator[]() accepts signed LLSD::Integer or size_t, resize() accepts std::vector::size_type. Given that the footprint of an LLSD array element is at least a pointer, the number of bytes required for resize(hugely positive) is likely to exceed available heap storage. Passing the adjusted resize(index + 1) should defend against that case.
-rw-r--r--indra/llcommon/llsd.cpp2
1 files changed, 1 insertions, 1 deletions
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index a645e624f8..590915e9d2 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -622,7 +622,7 @@ namespace
if (index >= mData.size())
{
- mData.resize(i + 1);
+ mData.resize(index + 1);
}
return mData[index];