diff --git a/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/BaseContactMapper.cpp b/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/BaseContactMapper.cpp index eca24b97aa7..f9e1b0c2e33 100644 --- a/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/BaseContactMapper.cpp +++ b/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/BaseContactMapper.cpp @@ -37,7 +37,7 @@ std::string GenerateStringID::generate(){ std::string result; result.resize(length); for (int i = 0; i < length; i++) - result[i] = alphanum[rand() % length]; + result[i] = alphanum[rand() % alphanum.size()]; return result; } diff --git a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/PrecomputedConstraintCorrection.inl b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/PrecomputedConstraintCorrection.inl index b50aac185e2..d7345d91da1 100644 --- a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/PrecomputedConstraintCorrection.inl +++ b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/PrecomputedConstraintCorrection.inl @@ -43,6 +43,7 @@ #include #include #include +#include #include //#define NEW_METHOD_UNBUILT @@ -50,6 +51,15 @@ namespace sofa::component::constraint::lagrangian::correction { +namespace +{ + inline bool wouldOverflowCompliance(unsigned int a, unsigned int b) + { + if (a == 0 || b == 0) return false; + return a > std::numeric_limits::max() / b; + } +} + template PrecomputedConstraintCorrection::PrecomputedConstraintCorrection(sofa::core::behavior::MechanicalState *mm) : Inherit(mm) @@ -139,6 +149,12 @@ bool PrecomputedConstraintCorrection::loadCompliance(std::string file std::ifstream compFileIn(path, std::ifstream::binary); if (compFileIn.is_open()) { + if (wouldOverflowCompliance(nbRows, nbCols)) + { + msg_error() << "Cannot allocate compliance matrix: size overflow for (" << nbRows << "," << nbCols << ")"; + compFileIn.close(); + return false; + } invM->data = new Real[nbRows * nbCols]; msg_info() << "File " << path << " found. Loading..." ; @@ -156,6 +172,11 @@ bool PrecomputedConstraintCorrection::loadCompliance(std::string file std::stringstream ss; if (sofa::helper::system::DataRepository.findFile(fileName, "", &ss)) { + if (wouldOverflowCompliance(nbRows, nbCols)) + { + msg_error() << "Cannot allocate compliance matrix: size overflow for (" << nbRows << "," << nbCols << ")"; + return false; + } invM->data = new Real[nbRows * nbCols]; std::ifstream compFileIn(fileName.c_str(), std::ifstream::binary); @@ -253,6 +274,11 @@ void PrecomputedConstraintCorrection::bwdInit() msg_info() << "Compliance being built"; // Buffer Allocation + if (wouldOverflowCompliance(nbRows, nbCols)) + { + msg_error() << "Cannot allocate compliance matrix: size overflow for (" << nbRows << "," << nbCols << ")"; + return; + } invM->data = new Real[nbRows * nbCols]; // for the initial computation, the gravity has to be put at 0 diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/TransformPosition.inl b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/TransformPosition.inl index 8f0c6d27911..2aba0bc6c1c 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/TransformPosition.inl +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/TransformPosition.inl @@ -188,7 +188,7 @@ void TransformPosition::getTransfoFromTfm() typedef std::vector vecString; vecString vLine; - char *l = new char[line.size()]; + char *l = new char[line.size() + 1]; strcpy(l, line.c_str()); char* p; for (p = strtok(l, " "); p; p = strtok(nullptr, " ")) @@ -259,7 +259,7 @@ void TransformPosition::getTransfoFromTrm() std::vector vLine; - char *l = new char[line.size()]; + char *l = new char[line.size() + 1]; strcpy(l, line.c_str()); char* p; for (p = strtok(l, " "); p; p = strtok(nullptr, " ")) @@ -337,7 +337,7 @@ void TransformPosition::getTransfoFromTxt() std::vector vLine; - char *l = new char[line.size()]; + char *l = new char[line.size() + 1]; strcpy(l, line.c_str()); char* p; for (p = strtok(l, " "); p; p = strtok(nullptr, " ")) diff --git a/Sofa/framework/Helper/src/sofa/helper/io/MeshOBJ.cpp b/Sofa/framework/Helper/src/sofa/helper/io/MeshOBJ.cpp index 44568d3280f..0a10328160a 100644 --- a/Sofa/framework/Helper/src/sofa/helper/io/MeshOBJ.cpp +++ b/Sofa/framework/Helper/src/sofa/helper/io/MeshOBJ.cpp @@ -262,8 +262,11 @@ void MeshOBJ::readMTL(const char* filename) else msg_error("MeshOBJ") << "fgets function has encountered an error." ; } - sscanf(buf, "%s %s", buf, buf); - mat->name = buf; + { + char matName[128] = {0}; + sscanf(buf, "%*127s %127s", matName); + mat->name = matName; + } break; case 'N': switch (buf[1]) diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BTDMatrix.inl b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BTDMatrix.inl index b8aab20af58..cf83888d768 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BTDMatrix.inl +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BTDMatrix.inl @@ -23,6 +23,9 @@ #include #include +#include +#include +#include namespace sofa::linearalgebra { @@ -35,8 +38,12 @@ BTDMatrix::BTDMatrix() template BTDMatrix::BTDMatrix(Index nbRow, Index nbCol) - : data(new Block[3*(nbRow/BSIZE)]), nTRow(nbRow), nTCol(nbCol), nBRow(nbRow/BSIZE), nBCol(nbCol/BSIZE), allocsize(3*(nbRow/BSIZE)) + : data(nullptr), nTRow(nbRow), nTCol(nbCol), nBRow(nbRow/BSIZE), nBCol(nbCol/BSIZE), allocsize(0) { + if (type::hardening::checkOverflow(nBRow,3)) + throw std::overflow_error("BTDMatrix: allocation size overflow"); + allocsize = 3 * nBRow; + data = new Block[allocsize]; } template @@ -63,9 +70,16 @@ void BTDMatrix::resize(Index nbRow, Index nbCol) { if (nbCol != nTCol || nbRow != nTRow) { + const Index newBRow = nbRow / BSIZE; + if (type::hardening::checkOverflow(nBRow,3)) + { + msg_error("BTDLinearSolver") << "Cannot resize matrix: allocation size overflow for (" << nbRow << "," << nbCol << ")"; + return; + } + const Index newSize = 3 * newBRow; if (allocsize < 0) { - if ((nbRow/BSIZE)*3 > -allocsize) + if (newSize > -allocsize) { msg_error("BTDLinearSolver") << "Cannot resize preallocated matrix to size ("<::resize(Index nbRow, Index nbCol) } else { - if ((nbRow/BSIZE)*3 > allocsize) + if (newSize > allocsize) { if (allocsize > 0) delete[] data; - allocsize = (nbRow/BSIZE)*3; + allocsize = newSize; data = new Block[allocsize]; } } nTCol = nbCol; nTRow = nbRow; nBCol = nbCol/BSIZE; - nBRow = nbRow/BSIZE; + nBRow = newBRow; } clear(); } diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.cpp b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.cpp index 298081bf434..bee50c18eb2 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.cpp +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.cpp @@ -862,7 +862,14 @@ std::istream& operator>>( std::istream& in, sofa::linearalgebra::BaseMatrix& m ) } - m.resize( (Index)lines.size(), (Index)lines[0].size() ); + if (lines.empty()) + { + m.resize(0, 0); + } + else + { + m.resize( (Index)lines.size(), (Index)lines[0].size() ); + } for( size_t i=0; i #include +#include + +#include +#include namespace sofa::linearalgebra { @@ -86,8 +90,12 @@ BlockFullMatrix::BlockFullMatrix() template BlockFullMatrix::BlockFullMatrix(Index nbRow, Index nbCol) - : data(new Block[nbRow*nbCol]), nTRow(nbRow), nTCol(nbCol), nBRow(nbRow/BSIZE), nBCol(nbCol/BSIZE), allocsize((nbCol/BSIZE)*(nbRow/BSIZE)) + : data(nullptr), nTRow(nbRow), nTCol(nbCol), nBRow(nbRow/BSIZE), nBCol(nbCol/BSIZE), allocsize(0) { + if (type::hardening::checkOverflow(nBRow, nBCol)) + throw std::overflow_error("BlockFullMatrix: allocation size overflow"); + allocsize = nBRow * nBCol; + data = new Block[allocsize]; } template @@ -114,9 +122,17 @@ void BlockFullMatrix::resize(Index nbRow, Index nbCol) { if (nbCol != nTCol || nbRow != nTRow) { + const Index newBRow = nbRow / BSIZE; + const Index newBCol = nbCol / BSIZE; + if (type::hardening::checkOverflow(newBRow, newBCol)) + { + msg_error("BTDLinearSolver") << "Cannot resize matrix: allocation size overflow for (" << nbRow << "," << nbCol << ")"; + return; + } + const Index newSize = newBRow * newBCol; if (allocsize < 0) { - if ((nbCol/BSIZE)*(nbRow/BSIZE) > -allocsize) + if (newSize > -allocsize) { msg_error("BTDLinearSolver") << "Cannot resize preallocated matrix to size ("<::resize(Index nbRow, Index nbCol) } else { - if ((nbCol/BSIZE)*(nbRow/BSIZE) > allocsize) + if (newSize > allocsize) { if (allocsize > 0) delete[] data; - allocsize = (nbCol/BSIZE)*(nbRow/BSIZE); + allocsize = newSize; data = new Block[allocsize]; } } nTCol = nbCol; nTRow = nbRow; - nBCol = nbCol/BSIZE; - nBRow = nbRow/BSIZE; + nBCol = newBCol; + nBRow = newBRow; } clear(); } diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/FullMatrix.inl b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/FullMatrix.inl index 2744095bdd8..6882dc4ba92 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/FullMatrix.inl +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/FullMatrix.inl @@ -21,6 +21,10 @@ ******************************************************************************/ #pragma once #include +#include +#include +#include + namespace sofa::linearalgebra { @@ -33,8 +37,12 @@ FullMatrix::FullMatrix() template FullMatrix::FullMatrix(Index nbRow, Index nbCol) - : data(new Real[nbRow*nbCol]), nRow(nbRow), nCol(nbCol), pitch(nbCol), allocsize(nbRow*nbCol) + : data(nullptr), nRow(nbRow), nCol(nbCol), pitch(nbCol), allocsize(0) { + if (type::hardening::checkOverflow(nbRow,nbCol)) + throw std::overflow_error("FullMatrix: allocation size overflow"); + allocsize = nbRow * nbCol; + data = new Real[allocsize]; } template @@ -75,11 +83,17 @@ void FullMatrix::resize(Index nbRow, Index nbCol) { msg_info() << /*this->Name() << */": resize(" << nbRow << "," << nbCol << ")"; } + if (type::hardening::checkOverflow(nbRow,nbCol)) + { + msg_error() << "Cannot resize matrix: allocation size overflow for (" << nbRow << "," << nbCol << ")"; + return; + } if (nbCol != nCol || nbRow != nRow) { + const Index newSize = nbRow * nbCol; if (allocsize < 0) { - if (nbRow*nbCol > -allocsize) + if (newSize > -allocsize) { msg_error() << "Cannot resize preallocated matrix to size (" << nbRow << "," << nbCol << ")"; return; @@ -87,11 +101,11 @@ void FullMatrix::resize(Index nbRow, Index nbCol) } else { - if (nbRow*nbCol > allocsize) + if (newSize > allocsize) { if (allocsize > 0) delete[] data; - allocsize = nbRow*nbCol; + allocsize = newSize; data = new Real[allocsize]; } } diff --git a/Sofa/framework/Type/CMakeLists.txt b/Sofa/framework/Type/CMakeLists.txt index f1025c58fd8..5ba47094a58 100644 --- a/Sofa/framework/Type/CMakeLists.txt +++ b/Sofa/framework/Type/CMakeLists.txt @@ -10,6 +10,7 @@ set(HEADER_FILES ${SOFATYPESRC_ROOT}/DualQuat.h ${SOFATYPESRC_ROOT}/DualQuat.inl ${SOFATYPESRC_ROOT}/Frame.h + ${SOFATYPESRC_ROOT}/hardening.h ${SOFATYPESRC_ROOT}/Mat.h ${SOFATYPESRC_ROOT}/MatSym.h ${SOFATYPESRC_ROOT}/Mat_solve_Cholesky.h diff --git a/Sofa/framework/Type/src/sofa/type/hardening.h b/Sofa/framework/Type/src/sofa/type/hardening.h new file mode 100644 index 00000000000..d0eb262c234 --- /dev/null +++ b/Sofa/framework/Type/src/sofa/type/hardening.h @@ -0,0 +1,40 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include + + +// This file should contain useful function to harden (i.e make safer) the code + +namespace sofa::type::hardening +{ + +template requires std::is_integral_v +constexpr bool checkOverflow(IndexType a, IndexType b) +{ + if (a <= 0) return false; + return a > std::numeric_limits::max() / b; +} + +} //namespace sofa::type::hardening