Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions indra/llmath/llvolume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, bool flat, F3
mProfile[i] = pt[j--];
}

for (S32 i=0;i<(S32)mFaces.size();i++)
for (U8 i=0;i<mFaces.size();i++)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm changing almost all of the "face count" variables to use U8 instead of a mix of types (S32, U32, size_t). There are a few places I didn't change because in context the logic was expecting invalid values (-1).

{
if (mFaces[i].mCap)
{
Expand Down Expand Up @@ -752,7 +752,6 @@ bool LLProfile::generate(const LLProfileParams& params, bool path_open,F32 detai
mFaces.resize(0);

// Generate the face data
S32 i;
F32 begin = params.getBegin();
F32 end = params.getEnd();
F32 hollow = params.getHollow();
Expand All @@ -776,14 +775,14 @@ bool LLProfile::generate(const LLProfileParams& params, bool path_open,F32 detai
addCap (LL_FACE_PATH_BEGIN);
}

for (i = llfloor(begin * 4.f); i < llfloor(end * 4.f + .999f); i++)
for (S32 i = llfloor(begin * 4.f); i < llfloor(end * 4.f + .999f); i++)
{
addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, true);
}

LLVector4a scale(1,1,4,1);

for (i = 0; i <(S32) mProfile.size(); i++)
for (S32 i = 0; i <(S32) mProfile.size(); i++)
{
// Scale by 4 to generate proper tex coords.
mProfile[i].mul(scale);
Expand Down Expand Up @@ -821,7 +820,7 @@ bool LLProfile::generate(const LLProfileParams& params, bool path_open,F32 detai
{
genNGon(params, 3,0, 0, 1, split);
LLVector4a scale(1,1,3,1);
for (i = 0; i <(S32) mProfile.size(); i++)
for (S32 i = 0; i <(S32) mProfile.size(); i++)
{
// Scale by 3 to generate proper tex coords.
mProfile[i].mul(scale);
Expand All @@ -833,7 +832,7 @@ bool LLProfile::generate(const LLProfileParams& params, bool path_open,F32 detai
addCap(LL_FACE_PATH_BEGIN);
}

for (i = llfloor(begin * 3.f); i < llfloor(end * 3.f + .999f); i++)
for (S32 i = llfloor(begin * 3.f); i < llfloor(end * 3.f + .999f); i++)
{
addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, true);
}
Expand Down Expand Up @@ -2769,9 +2768,9 @@ bool LLVolume::cacheOptimize(bool gen_tangents)
}


S32 LLVolume::getNumFaces() const
U8 LLVolume::getNumFaces() const
{
return mIsMeshAssetLoaded ? getNumVolumeFaces() : (S32)mProfilep->mFaces.size();
return mIsMeshAssetLoaded ? getNumVolumeFaces() : static_cast<U8>(mProfilep->mFaces.size());
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential data loss when mFaces.size() exceeds 255. The vector size is being cast to U8, which can only hold values 0-255. If mFaces.size() is greater than 255, the cast will silently truncate the value, leading to incorrect face count.

Suggested change
return mIsMeshAssetLoaded ? getNumVolumeFaces() : static_cast<U8>(mProfilep->mFaces.size());
// Clamp face count to maximum value representable by U8 to avoid truncation.
U32 num_faces = mIsMeshAssetLoaded
? static_cast<U32>(getNumVolumeFaces())
: static_cast<U32>(mProfilep->mFaces.size());
if (num_faces > 255u)
{
num_faces = 255u;
}
return static_cast<U8>(num_faces);

Copilot uses AI. Check for mistakes.
}


Expand All @@ -2785,15 +2784,15 @@ void LLVolume::createVolumeFaces()
}
else
{
S32 num_faces = getNumFaces();
U8 num_faces = getNumFaces();
bool partial_build = true;
if (num_faces != mVolumeFaces.size())
{
partial_build = false;
mVolumeFaces.resize(num_faces);
}
// Initialize volume faces with parameter data
for (S32 i = 0; i < (S32)mVolumeFaces.size(); i++)
for (U8 i = 0; i < mVolumeFaces.size(); i++)
{
LLVolumeFace& vf = mVolumeFaces[i];
LLProfile::Face& face = mProfilep->mFaces[i];
Expand Down Expand Up @@ -3714,7 +3713,7 @@ S32 LLVolume::getNumTriangles(S32* vcount) const
U32 triangle_count = 0;
U32 vertex_count = 0;

for (S32 i = 0; i < getNumVolumeFaces(); ++i)
for (U8 i = 0; i < getNumVolumeFaces(); ++i)
{
const LLVolumeFace& face = getVolumeFace(i);
triangle_count += face.mNumIndices/3;
Expand Down Expand Up @@ -4227,7 +4226,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
if (face == -1) // ALL_SIDES
{
start_face = 0;
end_face = getNumVolumeFaces() - 1;
end_face = static_cast<S32>(getNumVolumeFaces()) - 1;
}
else
{
Expand All @@ -4240,7 +4239,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en

F32 closest_t = 2.f; // must be larger than 1

end_face = llmin(end_face, getNumVolumeFaces()-1);
end_face = llmin(end_face, static_cast<S32>(getNumVolumeFaces())-1);

for (S32 i = start_face; i <= end_face; i++)
{
Expand Down Expand Up @@ -4792,7 +4791,7 @@ LLFaceID LLVolume::generateFaceMask()
bool LLVolume::isFaceMaskValid(LLFaceID face_mask)
{
LLFaceID test_mask = 0;
for(S32 i = 0; i < getNumFaces(); i++)
for(U8 i = 0; i < getNumFaces(); i++)
{
test_mask |= mProfilep->mFaces[i].mFaceID;
}
Expand Down
10 changes: 5 additions & 5 deletions indra/llmath/llvolume.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class LLVolumeOctree;

//============================================================================

constexpr S32 MIN_DETAIL_FACES = 6;
constexpr U8 MIN_DETAIL_FACES = 6;
constexpr S32 MIN_LOD = 0;
constexpr S32 MAX_LOD = 3;

Expand Down Expand Up @@ -201,7 +201,7 @@ constexpr U8 LL_SCULPT_FLAG_INVERT = 64;
constexpr U8 LL_SCULPT_FLAG_MIRROR = 128;
constexpr U8 LL_SCULPT_FLAG_MASK = LL_SCULPT_FLAG_INVERT | LL_SCULPT_FLAG_MIRROR;

constexpr S32 LL_SCULPT_MESH_MAX_FACES = 8;
constexpr U8 LL_SCULPT_MESH_MAX_FACES = 8;

extern bool gDebugGL;

Expand Down Expand Up @@ -699,7 +699,7 @@ class LLProfile

S32 getTotal() const { return mTotal; }
S32 getTotalOut() const { return mTotalOut; } // Total number of outside points
bool isFlat(S32 face) const { return (mFaces[face].mCount == 2); }
bool isFlat(U8 face) const { return (mFaces[face].mCount == 2); }
bool isOpen() const { return mOpen; }
void setDirty() { mDirty = true; }

Expand Down Expand Up @@ -1027,8 +1027,8 @@ class LLVolume : public LLRefCount

U8 getProfileType() const { return mParams.getProfileParams().getCurveType(); }
U8 getPathType() const { return mParams.getPathParams().getCurveType(); }
S32 getNumFaces() const;
S32 getNumVolumeFaces() const { return static_cast<S32>(mVolumeFaces.size()); }
U8 getNumFaces() const;
U8 getNumVolumeFaces() const { return static_cast<U8>(mVolumeFaces.size()); }
F32 getDetail() const { return mDetail; }
F32 getSurfaceArea() const { return mSurfaceArea; }
const LLVolumeParams& getParams() const { return mParams; }
Expand Down
Loading