fix: sanitizer sweep across all generators; bound signed shifts/division/overflow at coordinate limits (L61); R31
New verify.py sanitize tier (Clang address,undefined,float-cast-overflow; GCC address,undefined; -fno-sanitize-recover) runs 19 cases per compiler at LOD0-8 across every generator, passages and the crossing: 0 runtime reports; a planted signed-overflow control is caught by both. A static scan fixed INT_MIN negation in floor division, unbounded signed LOD shifts and coordinate-times-extent overflow in VoxelClipmapDesiredTiles.h and VoxelTypes.h (plugin and standalone), and VoxelWorld.cpp, VoxelContentManager.cpp and VoxelDensityVolume.cpp (plugin only, uncompiled here). Supported-input output unchanged (version 211). fast/medium/full PASS. Research R31 (self-checked): far-LOD 4-8 cut plan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
1 parent
c0c204ba50
commit
135957831b
13 files changed
+760
-132
No files matched your search
@@ -155,9 +155,11 @@ int32 UVoxelDensityVolume::NumLevels() const
|
||||
|
||||
FORCEINLINE int32 UVoxelDensityVolume::FloorDiv(int32 A, int32 B)
|
||||
{
|
||||
// True floor division (B > 0). FMath::DivideAndRoundDown truncates toward zero for negatives —
|
||||
// a footgun the content manager hit too (see FloorDivPos there). Cells span the origin, so floor.
|
||||
return (A >= 0) ? (A / B) : -(((-A) + B - 1) / B);
|
||||
// True floor division (B > 0). Remainder adjustment handles INT_MIN without negating it.
|
||||
if (B <= 0) { return 0; }
|
||||
const int32 Quotient = A / B;
|
||||
const int32 Remainder = A % B;
|
||||
return Remainder < 0 ? Quotient - 1 : Quotient;
|
||||
}
|
||||
|
||||
FORCEINLINE uint8 UVoxelDensityVolume::Quantize(float MCDensity)
|
||||
@@ -180,7 +182,8 @@ void UVoxelDensityVolume::EnsureAllocated()
|
||||
for (int32 L = 0; L < N; ++L)
|
||||
{
|
||||
FClipLevel& Lv = Levels[L];
|
||||
Lv.Step = 1 << L;
|
||||
Lv.Step = static_cast<int32>(uint32{1}
|
||||
<< static_cast<uint32>(FMath::Clamp(L, 0, 8)));
|
||||
Lv.OriginCells = FIntVector(INT32_MAX, INT32_MAX, INT32_MAX);
|
||||
Lv.bHasData = false;
|
||||
Lv.Density.SetNumZeroed(Count); // start all-air (0)
|
||||
@@ -632,7 +635,8 @@ void UVoxelDensityVolume::ProcessOneFill(const FPendingFill& F)
|
||||
if (!Gen) return;
|
||||
if (bShuttingDown.load(std::memory_order_relaxed) || bFillThreadStop.load(std::memory_order_relaxed)) return;
|
||||
|
||||
const int32 Step = 1 << F.Level;
|
||||
const int32 Step = static_cast<int32>(uint32{1}
|
||||
<< static_cast<uint32>(FMath::Clamp(F.Level, 0, 8)));
|
||||
FFillResult R;
|
||||
R.Level = F.Level;
|
||||
R.Epoch = F.Epoch;
|
||||
|
||||
Reference in new issue
Block a user