[sparse] insertion with negativ or null index fixed 75/21675/5
Cedric Delamarre [Mon, 11 Jan 2021 12:54:40 +0000 (13:54 +0100)]
  * a=spzeros(3,3);a(0) = 1

Change-Id: I0f075a7a22c6e83a67e0b514ea9f17e597134715

scilab/modules/ast/src/cpp/types/sparse.cpp
scilab/modules/ast/tests/unit_tests/insert.tst
scilab/modules/sparse/sci_gateway/cpp/sci_sparse.cpp
scilab/modules/sparse/sci_gateway/cpp/sci_spzeros.cpp

index b57bab9..7b52ea7 100644 (file)
@@ -872,72 +872,21 @@ Sparse* Sparse::resize(int _iNewRows, int _iNewCols)
         return this;
     }
 
+    if (((double)_iNewRows) * ((double)_iNewCols) > INT_MAX)
+    {
+        return NULL;
+    }
+
     Sparse* res = NULL;
     try
     {
         if (matrixReal)
         {
-            //item count
-            size_t iNonZeros = nonZeros();
-            RealSparse_t *newReal = new RealSparse_t(_iNewRows, _iNewCols);
-            newReal->reserve((int)iNonZeros);
-
-
-            //coords
-            int* pRows = new int[iNonZeros * 2];
-            outputRowCol(pRows);
-            int* pCols = pRows + iNonZeros;
-
-            //values
-            double* pNonZeroR = new double[iNonZeros];
-            double* pNonZeroI = new double[iNonZeros];
-            outputValues(pNonZeroR, pNonZeroI);
-
-            std::vector<RealTriplet_t> tripletList;
-            for (size_t i = 0; i < iNonZeros; i++)
-            {
-                tripletList.emplace_back((int)pRows[i] - 1, (int)pCols[i] - 1, pNonZeroR[i]);
-            }
-
-            newReal->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<double>());
-
-            delete matrixReal;
-            matrixReal = newReal;
-            delete[] pRows;
-            delete[] pNonZeroR;
-            delete[] pNonZeroI;
+            matrixReal->conservativeResize(_iNewRows, _iNewCols);
         }
         else
         {
-            //item count
-            size_t iNonZeros = nonZeros();
-            CplxSparse_t *newCplx = new CplxSparse_t(_iNewRows, _iNewCols);
-            newCplx->reserve((int)iNonZeros);
-
-            //coords
-            int* pRows = new int[iNonZeros * 2];
-            outputRowCol(pRows);
-            int* pCols = pRows + iNonZeros;
-
-            //values
-            double* pNonZeroR = new double[iNonZeros];
-            double* pNonZeroI = new double[iNonZeros];
-            outputValues(pNonZeroR, pNonZeroI);
-
-            std::vector<CplxTriplet_t> tripletList;
-            for (size_t i = 0; i < iNonZeros; i++)
-            {
-                tripletList.emplace_back((int)pRows[i] - 1, (int)pCols[i] - 1, std::complex<double>(pNonZeroR[i], pNonZeroI[i]));
-            }
-
-            newCplx->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<std::complex<double>>());
-
-
-            delete matrixCplx;
-            matrixCplx = newCplx;
-            delete[] pRows;
-            delete[] pNonZeroR;
-            delete[] pNonZeroI;
+            matrixCplx->conservativeResize(_iNewRows, _iNewCols);
         }
 
         m_iRows = _iNewRows;
@@ -1158,8 +1107,8 @@ Sparse* Sparse::insert(typed_list* _pArgs, InternalType* _pSource)
 
     typed_list pArg;
 
-    int piMaxDim[2];
-    int piCountDim[2];
+    int* piMaxDim = new int[2];
+    int* piCountDim = new int[2];
 
     //on case of resize
     int iNewRows = 0;
@@ -1170,6 +1119,8 @@ Sparse* Sparse::insert(typed_list* _pArgs, InternalType* _pSource)
     int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
     if (iSeqCount == 0)
     {
+        delete[] piMaxDim;
+        delete[] piCountDim;
         //free pArg content
         cleanIndexesArguments(_pArgs, &pArg);
         return this;
@@ -1202,6 +1153,8 @@ Sparse* Sparse::insert(typed_list* _pArgs, InternalType* _pSource)
         }
         else if ((size_t)getRows() * (size_t)getCols() < (size_t)piMaxDim[0])
         {
+            delete[] piMaxDim;
+            delete[] piCountDim;
             //free pArg content
             cleanIndexesArguments(_pArgs, &pArg);
             //out of range
@@ -1218,6 +1171,9 @@ Sparse* Sparse::insert(typed_list* _pArgs, InternalType* _pSource)
         }
     }
 
+    delete[] piMaxDim;
+    delete[] piCountDim;
+
     //check number of insertion
     if (pSource->isScalar() == false && pSource->getSize() != iSeqCount)
     {
@@ -1553,7 +1509,7 @@ Sparse* Sparse::insert(typed_list* _pArgs, InternalType* _pSource)
                 {
                     int iRow = static_cast<int>(i % iRowSize);
                     int iCol = static_cast<int>(i / iRowSize);
-                    tripletList.emplace_back(static_cast<int>(pI[iRow]) - 1, static_cast<int>(pJ[iCol]) - 1, *src);
+                    tripletList.emplace_back(static_cast<int>(pI[iRow] - 1) , static_cast<int>(pJ[iCol] - 1) , *src);
                     src += inc;
                 }
 
@@ -3176,8 +3132,7 @@ Sparse* Sparse::reshape(int _iNewRows, int _iNewCols)
 
             //values
             double* pNonZeroR = new double[iNonZeros];
-            double* pNonZeroI = new double[iNonZeros];
-            outputValues(pNonZeroR, pNonZeroI);
+            outputValues(pNonZeroR, NULL);
 
             std::vector<RealTriplet_t> tripletList;
             for (size_t i = 0; i < iNonZeros; i++)
@@ -3192,7 +3147,6 @@ Sparse* Sparse::reshape(int _iNewRows, int _iNewCols)
             matrixReal = newReal;
             delete[] pRows;
             delete[] pNonZeroR;
-            delete[] pNonZeroI;
         }
         else
         {
@@ -3436,32 +3390,15 @@ SparseBool* SparseBool::resize(int _iNewRows, int _iNewCols)
         return this;
     }
 
+    if (((double)_iNewRows) * ((double)_iNewCols) > INT_MAX)
+    {
+        return NULL;
+    }
+
     SparseBool* res = NULL;
     try
     {
-        //item count
-        size_t iNonZeros = nbTrue();
-
-        BoolSparse_t *newBool = new BoolSparse_t(_iNewRows, _iNewCols);
-        newBool->reserve((int)iNonZeros);
-
-        //coords
-        int* pRows = new int[iNonZeros * 2];
-        outputRowCol(pRows);
-        int* pCols = pRows + iNonZeros;
-
-        std::vector<BoolTriplet_t> tripletList;
-
-        for (size_t i = 0; i < iNonZeros; i++)
-        {
-            tripletList.emplace_back((int)pRows[i] - 1, (int)pCols[i] - 1, true);
-        }
-
-        newBool->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<bool>());
-
-        delete matrixBool;
-        matrixBool = newBool;
-        delete[] pRows;
+        matrixBool->conservativeResize(_iNewRows, _iNewCols);
 
         m_iRows = _iNewRows;
         m_iCols = _iNewCols;
@@ -3490,8 +3427,8 @@ SparseBool* SparseBool::insert(typed_list* _pArgs, SparseBool* _pSource)
 
     typed_list pArg;
 
-    int piMaxDim[2];
-    int piCountDim[2];
+    int* piMaxDim = new int[2];
+    int* piCountDim = new int[2];
 
     //on case of resize
     int iNewRows = 0;
@@ -3501,6 +3438,8 @@ SparseBool* SparseBool::insert(typed_list* _pArgs, SparseBool* _pSource)
     int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
     if (iSeqCount == 0)
     {
+        delete[] piMaxDim;
+        delete[] piCountDim;
         //free pArg content
         cleanIndexesArguments(_pArgs, &pArg);
         return this;
@@ -3533,6 +3472,8 @@ SparseBool* SparseBool::insert(typed_list* _pArgs, SparseBool* _pSource)
         }
         else if (getRows() * getCols() < piMaxDim[0])
         {
+            delete[] piMaxDim;
+            delete[] piCountDim;
             //free pArg content
             cleanIndexesArguments(_pArgs, &pArg);
             //out of range
@@ -3549,6 +3490,9 @@ SparseBool* SparseBool::insert(typed_list* _pArgs, SparseBool* _pSource)
         }
     }
 
+    delete[] piMaxDim;
+    delete[] piCountDim;
+
     //check number of insertion
     if (_pSource->isScalar() == false && _pSource->getSize() != iSeqCount)
     {
index 8ed3275..316f834 100644 (file)
@@ -548,3 +548,8 @@ twin=origin(1)(1);
 twin.test = 5;
 assert_checkequal(origin(1)(1).test, 1);
 assert_checkequal(twin.test, 5);
+
+// insert in sparse with invalid index
+a=spzeros(3,3);
+errMsg = msprintf(_("Invalid index.\n"));
+assert_checkerror("a(0) = 1", errMsg);
index 1dfead1..69e1028 100644 (file)
@@ -152,6 +152,12 @@ types::Function::ReturnValue sci_sparse(types::typed_list &in, int _piRetCount,
                 Scierror(999, _("%s: Wrong values for input argument #%d: Positive integers expected.\n"), "sparse", 3);
                 return types::Function::Error;
             }
+
+            if (pDdims->get(0) * pDdims->get(1) > INT_MAX)
+            {
+                Scierror(999, _("%s: Wrong value for input argument #%d: The maximum total size expected is %d.\n"), "sparse", 3, INT_MAX);
+                return types::Function::Error;
+            }
         }
 
         bool alloc = false;
@@ -168,7 +174,7 @@ types::Function::ReturnValue sci_sparse(types::typed_list &in, int _piRetCount,
             Scierror(999, _("%s: Invalid index.\n"), "sparse");
             return types::Function::Error;
         }
-        
+
         if (pDdims == nullptr)
         {
             pDdims = new types::Double(1, 2, false);
@@ -180,7 +186,7 @@ types::Function::ReturnValue sci_sparse(types::typed_list &in, int _piRetCount,
             }
             alloc = true;
         }
-        else if ( (size > 0) && ((pDdims->get(0) < *std::max_element(pdbli, pdbli + size)) 
+        else if ( (size > 0) && ((pDdims->get(0) < *std::max_element(pdbli, pdbli + size))
                   || (pDdims->get(1) < *std::max_element(pdblj, pdblj + size))) )
         {
             Scierror(999, _("%s: Invalid index.\n"),"sparse");
index ae18e9a..606347e 100644 (file)
@@ -71,27 +71,33 @@ types::Function::ReturnValue sci_spzeros(types::typed_list &in, int _iRetCount,
             return types::Function::Error;
         }
 
-        if (pDblRows->get(0) != (double) ((unsigned int) pDblRows->get(0)))
+        double dblRows = pDblRows->get(0);
+        double dblCols = pDblCols->get(0);
+        if (dblRows != (double) ((unsigned int) dblRows))
         {
-
             Scierror(999, _("%s: Wrong value for input argument #%d: Scalar positive integer expected.\n"), "spzeros", 1);
             return types::Function::Error;
         }
 
-        if (pDblCols->get(0) != (double) ((unsigned int) pDblCols->get(0)))
+        if (dblCols != (double) ((unsigned int) dblCols))
         {
-
             Scierror(999, _("%s: Wrong value for input argument #%d: Scalar positive integer expected.\n"), "spzeros", 2);
             return types::Function::Error;
         }
 
+        if (dblRows * dblCols > INT_MAX)
+        {
+            Scierror(999, _("%s: Wrong value for input arguments: The maximum total size expected is %d.\n"), "spzeros", INT_MAX);
+            return types::Function::Error;
+        }
+
         if (pDblRows->get(0) == 0. || pDblCols->get(0) == 0.)
         {
             pSpOut = new types::Sparse(0, 0, false);
         }
         else
         {
-            pSpOut = new types::Sparse((int)pDblRows->get(0), (int)pDblCols->get(0), false);            
+            pSpOut = new types::Sparse((int)pDblRows->get(0), (int)pDblCols->get(0), false);
         }
 
     }