From 4349cb6165e983ff6bdd45ad1b82bb98bfc0436f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Sat, 12 Nov 2022 18:59:21 -1000 Subject: DRTVWR-575: Address review comments on Xcode 14.1 type tweaks. Introduce LLSD template constructors and assignment operators to disambiguate construction or assignment from any integer type to Integer, likewise any floating point type to Real. Use new narrow() function to validate conversions. For LLSD method parameters converted from LLSD::Integer to size_t, where the method previously checked for a negative argument, make it now check for size_t converted from negative: in other words, more than S32_MAX. The risk of having a parameter forced from negative to unsigned exceeds the risk of a valid length or index over that max. In lltracerecording.cpp's PeriodicRecording, now that mCurPeriod and mNumRecordedPeriods are size_t instead of S32, defend against subtracting 1 from 0. Use narrow() to validate newly-introduced narrowing conversions. Make llclamp() return the type of the raw input value, even if the types of the boundary values differ. std::ostream::tellp() no longer returns a value we can directly report as a number. Cast to U64. --- indra/llcommon/llsd.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'indra/llcommon/llsd.cpp') diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 8772178b05..a645e624f8 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -36,6 +36,18 @@ #include "llsdserialize.h" #include "stringize.h" +#include + +// Defend against a caller forcibly passing a negative number into an unsigned +// size_t index param +inline +bool was_negative(size_t i) +{ + return (i > std::numeric_limits::max()); +} +#define NEGATIVE_EXIT(i) if (was_negative(i)) return +#define NEGATIVE_RETURN(i, result) NEGATIVE_EXIT(i) (result) + #ifndef LL_RELEASE_FOR_DOWNLOAD #define NAME_UNNAMED_NAMESPACE #endif @@ -555,6 +567,7 @@ namespace LLSD ImplArray::get(size_t i) const { + NEGATIVE_RETURN(i, LLSD()); DataVector::size_type index = i; return (index < mData.size()) ? mData[index] : LLSD(); @@ -562,6 +575,7 @@ namespace void ImplArray::set(size_t i, const LLSD& v) { + NEGATIVE_EXIT(i); DataVector::size_type index = i; if (index >= mData.size()) @@ -574,6 +588,7 @@ namespace void ImplArray::insert(size_t i, const LLSD& v) { + NEGATIVE_EXIT(i); DataVector::size_type index = i; if (index >= mData.size()) // tbd - sanity check limit for index ? @@ -592,6 +607,7 @@ namespace void ImplArray::erase(size_t i) { + NEGATIVE_EXIT(i); DataVector::size_type index = i; if (index < mData.size()) @@ -602,7 +618,7 @@ namespace LLSD& ImplArray::ref(size_t i) { - DataVector::size_type index = i; + DataVector::size_type index = was_negative(i)? 0 : i; if (index >= mData.size()) { @@ -614,6 +630,7 @@ namespace const LLSD& ImplArray::ref(size_t i) const { + NEGATIVE_RETURN(i, undef()); DataVector::size_type index = i; if (index >= mData.size()) @@ -833,9 +850,6 @@ LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } -// Convenience Constructors -LLSD::LLSD(F32 v) : impl(0) { ALLOC_LLSD_OBJECT; assign((Real)v); } - // Scalar Assignment void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); } void LLSD::assign(Integer v) { safe(impl).assign(impl, v); } -- cgit v1.2.3