From bb84ecf5c67ccc21ef636df5f50b92e29638fe9f Mon Sep 17 00:00:00 2001 From: Elias Cohenca Date: Thu, 23 Jan 2025 02:25:08 +0200 Subject: [PATCH] Coding - Fix draco buffer index out of bounds Fixed an exception where the bufferIndex is out of bounds. Happens when Draco compression is combined with SetMergeFaces. --- src/RWGltf/RWGltf_CafWriter.cxx | 86 ++++++++++++++++----------------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/src/RWGltf/RWGltf_CafWriter.cxx b/src/RWGltf/RWGltf_CafWriter.cxx index e33eac3fab..9ec8dd6185 100644 --- a/src/RWGltf/RWGltf_CafWriter.cxx +++ b/src/RWGltf/RWGltf_CafWriter.cxx @@ -746,27 +746,27 @@ bool RWGltf_CafWriter::writeBinData (const Handle(TDocStd_Document)& theDocument continue; } - std::shared_ptr aMeshPtr; -#ifdef HAVE_DRACO - ++aMeshIndex; - if (myDracoParameters.DracoCompression) - { - if (aMeshIndex <= aMeshes.size()) - { - aMeshPtr = aMeshes.at(aMeshIndex - 1); - } - else - { - aMeshes.push_back(std::make_shared(RWGltf_CafWriter::Mesh())); - aMeshPtr = aMeshes.back(); - } - } -#endif - for (RWGltf_GltfFaceList::Iterator aGltfFaceIter (*aGltfFaceList); aGltfFaceIter.More() && aPSentryBin.More(); aGltfFaceIter.Next()) { const Handle(RWGltf_GltfFace)& aGltfFace = aGltfFaceIter.Value(); + std::shared_ptr aMeshPtr; +#ifdef HAVE_DRACO + ++aMeshIndex; + if (myDracoParameters.DracoCompression) + { + if (aMeshIndex <= aMeshes.size()) + { + aMeshPtr = aMeshes.at(aMeshIndex - 1); + } + else + { + aMeshes.push_back(std::make_shared(RWGltf_CafWriter::Mesh())); + aMeshPtr = aMeshes.back(); + } + } +#endif + Handle(RWGltf_GltfFace) anOldGltfFace; if (aWrittenPrimData.Find (aGltfFace->Shape, anOldGltfFace)) { @@ -1899,23 +1899,21 @@ void RWGltf_CafWriter::writeMeshes (const RWGltf_GltfSceneNodeMap& theSceneNodeM for (RWGltf_GltfFaceList::Iterator aFaceGroupIter (*aGltfFaceList); aFaceGroupIter.More(); aFaceGroupIter.Next()) { const Handle(RWGltf_GltfFace)& aGltfFace = aFaceGroupIter.Value(); - const int aPrevSize = aDracoBufIndMap.Size(); - const int aTempDracoBufInd = aDracoBufInd; - if (myDracoParameters.DracoCompression - && !aDracoBufIndMap.FindFromKey (aGltfFace->NodePos.Id, aDracoBufInd)) + int aCurrentDracoBufInd = 0; + + if (myDracoParameters.DracoCompression) { - aDracoBufIndMap.Add (aGltfFace->NodePos.Id, aDracoBufInd); + // Check if we've seen this NodePos.Id before + if (!aDracoBufIndMap.FindFromKey(aGltfFace->NodePos.Id, aCurrentDracoBufInd)) + { + // New Draco buffer entry needed + aCurrentDracoBufInd = aDracoBufInd; + aDracoBufIndMap.Add(aGltfFace->NodePos.Id, aCurrentDracoBufInd); + ++aDracoBufInd; + } } - writePrimArray (*aGltfFace, aNodeName, aDracoBufInd, toStartPrims); - if (aTempDracoBufInd != aDracoBufInd) - { - aDracoBufInd = aTempDracoBufInd; - } - if (!myDracoParameters.DracoCompression || aDracoBufIndMap.Size() > aPrevSize) - { - ++aDracoBufInd; - } + writePrimArray(*aGltfFace, aNodeName, aCurrentDracoBufInd, toStartPrims); } } else @@ -1935,23 +1933,21 @@ void RWGltf_CafWriter::writeMeshes (const RWGltf_GltfSceneNodeMap& theSceneNodeM } const Handle(RWGltf_GltfFace)& aGltfFace = aGltfFaceList->First(); - const int aPrevSize = aDracoBufIndMap.Size(); - const int aTempDracoBufInd = aDracoBufInd; - if (myDracoParameters.DracoCompression - && !aDracoBufIndMap.FindFromKey(aGltfFace->NodePos.Id, aDracoBufInd)) + int aCurrentDracoBufInd = 0; + + if (myDracoParameters.DracoCompression) { - aDracoBufIndMap.Add(aGltfFace->NodePos.Id, aDracoBufInd); + // Check if we've seen this NodePos.Id before + if (!aDracoBufIndMap.FindFromKey(aGltfFace->NodePos.Id, aCurrentDracoBufInd)) + { + // New Draco buffer entry needed + aCurrentDracoBufInd = aDracoBufInd; + aDracoBufIndMap.Add(aGltfFace->NodePos.Id, aCurrentDracoBufInd); + ++aDracoBufInd; + } } - writePrimArray (*aGltfFace, aNodeName, aDracoBufInd, toStartPrims); - if (aTempDracoBufInd != aDracoBufInd) - { - aDracoBufInd = aTempDracoBufInd; - } - if (!myDracoParameters.DracoCompression || aDracoBufIndMap.Size() > aPrevSize) - { - ++aDracoBufInd; - } + writePrimArray(*aGltfFace, aNodeName, aCurrentDracoBufInd, toStartPrims); } }