From a1349c14dd073078ad73f7dff35402547445b7eb Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Thu, 25 Nov 2021 00:00:29 +0200
Subject: [PATCH] SL-16413 Handle out of memory llface allocations

---
 indra/llmath/llvolume.cpp | 47 +++++++++++++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 4 deletions(-)

diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index e085fa6ada7..62b39d29a4a 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2414,7 +2414,14 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
 			
 
 			//copy out indices
-			face.resizeIndices(idx.size()/2);
+            S32 num_indices = idx.size() / 2;
+            face.resizeIndices(num_indices);
+
+            if (num_indices > 2 && !face.mIndices)
+            {
+                LL_WARNS() << "Failed to allocate " << num_indices << " indices for face index: " << i << " Total: " << face_count << LL_ENDL;
+                continue;
+            }
 			
 			if (idx.empty() || face.mNumIndices < 3)
 			{ //why is there an empty index list?
@@ -2433,6 +2440,13 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
 			U32 num_verts = pos.size()/(3*2);
 			face.resizeVertices(num_verts);
 
+            if (num_verts > 0 && !face.mPositions)
+            {
+                LL_WARNS() << "Failed to allocate " << num_verts << " vertices for face index: " << i << " Total: " << face_count << LL_ENDL;
+                face.resizeIndices(0);
+                continue;
+            }
+
 			LLVector3 minp;
 			LLVector3 maxp;
 			LLVector2 min_tc; 
@@ -2534,6 +2548,13 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
 			if (mdl[i].has("Weights"))
 			{
 				face.allocateWeights(num_verts);
+                if (!face.mWeights && num_verts)
+                {
+                    LL_WARNS() << "Failed to allocate " << num_verts << " weights for face index: " << i << " Total: " << face_count << LL_ENDL;
+                    face.resizeIndices(0);
+                    face.resizeVertices(0);
+                    continue;
+                }
 
 				LLSD::Binary weights = mdl[i]["Weights"];
 
@@ -6342,8 +6363,18 @@ void LLVolumeFace::resizeVertices(S32 num_verts)
 		mTexCoords = NULL;
 	}
 
-	mNumVertices = num_verts;
-	mNumAllocatedVertices = num_verts;
+
+    if (mPositions)
+    {
+        mNumVertices = num_verts;
+        mNumAllocatedVertices = num_verts;
+    }
+    else
+    {
+        // Either num_verts is zero or allocation failure
+        mNumVertices = 0;
+        mNumAllocatedVertices = 0;
+    }
 
     // Force update
     mJointRiggingInfoTab.clear();
@@ -6444,7 +6475,15 @@ void LLVolumeFace::resizeIndices(S32 num_indices)
 		mIndices = NULL;
 	}
 
-	mNumIndices = num_indices;
+    if (mIndices)
+    {
+        mNumIndices = num_indices;
+    }
+    else
+    {
+        // Either num_indices is zero or allocation failure
+        mNumIndices = 0;
+    }
 }
 
 void LLVolumeFace::pushIndex(const U16& idx)
-- 
GitLab