* Bug #15758 fixed: sparse([0 0],1) does not crash scilab any more 92/20492/14
Stéphane Mottelet [Mon, 10 Sep 2018 11:25:48 +0000 (13:25 +0200)]
http://bugzilla.scilab.org/show_bug.cgi?id=15758
http://bugzilla.scilab.org/show_bug.cgi?id=15750

Change-Id: I503426e5b4900e7f5523ac3b74e9f3d046e9a308

scilab/CHANGES.md
scilab/modules/sparse/sci_gateway/cpp/sci_sparse.cpp
scilab/modules/sparse/tests/nonreg_tests/bug_15750.tst [new file with mode: 0644]
scilab/modules/sparse/tests/nonreg_tests/bug_15758.tst [new file with mode: 0644]

index 120f97b..74cd374 100644 (file)
@@ -563,6 +563,7 @@ Known issues
 * [#15693](http://bugzilla.scilab.org/show_bug.cgi?id=15693): listvarinfile() misses displaying the size of polynomial variables (regression)
 * [#15733](http://bugzilla.scilab.org/show_bug.cgi?id=15733): Some fixes after deg(0*%s) => -%inf.
 * [#15735](http://bugzilla.scilab.org/show_bug.cgi?id=15735): `interp1` yielded some []+n warnings.
+* [#15758](http://bugzilla.scilab.org/show_bug.cgi?id=15758): sparse([0 0],1) crashes scilab (regression)
 * [#15762](http://bugzilla.scilab.org/show_bug.cgi?id=15762): `error()` refused multiline error messages.
 
 
index ce19050..fe9df07 100644 (file)
@@ -18,6 +18,7 @@
 #include "sparse_gw.hxx"
 #include "function.hxx"
 #include "sparse.hxx"
+#include "double.hxx"
 
 extern "C"
 {
@@ -116,78 +117,88 @@ types::Function::ReturnValue sci_sparse(types::typed_list &in, int _piRetCount,
             }
         }
     }
-    else if (in.size() == 2 || in.size() == 3)
+    else // 2 or 3 arguments
     {
-        // if two arguments are given the first is a 'n x 2' matrix of the non zero indices and the second is a 'n x 1' vector of the values
-        for (int i = 0 ; i < in.size() ; i++)
+        types::Double* pDij = in[0]->getAs<types::Double>(); // arg 2 necessarily *Double
+        types::GenericType* pGT2 = in[1]->getAs<types::GenericType>();
+        int size = pGT2->getSize();
+
+        if ( ((size !=0) || (pDij->getSize() != 0)) && ((pDij->getCols() != 2) || (pDij->getRows() != size)))
         {
-            if (in[i]->isDouble() == false && !(in[i]->isBool() && i == 1))
+            if (size > 0)
             {
-                Scierror(999, _("%s: Wrong type for input argument #%d: Real or Complex matrix expected.\n"), "sparse", i + 1);
-                return types::Function::Error;
+                Scierror(999, _("%s: Wrong size for input argument #%d: A matrix of size %d x %d expected.\n"), "sparse", 1, size, 2);
+            }
+            else
+            {
+                Scierror(999, _("%s: Wrong size for input argument #%d: An empty matrix expected.\n"), "sparse", 1);
             }
+            return types::Function::Error;
         }
 
-        //Double* pDims( (in.size()==3) ? in[2]->getAs<Double>() : 0);
-        types::Double* pDims = NULL;
+        //Double* pDdims( (in.size()==3) ? in[2]->getAs<Double>() : 0);
+        types::Double* pDdims = NULL;
         if (in.size() == 3)
         {
-            pDims = in[2]->getAs<types::Double>();
-            if (pDims->getRows() != 1 || pDims->getCols() != 2)
+            pDdims = in[2]->getAs<types::Double>();
+            if (pDdims->getSize() != 2)
             {
                 Scierror(999, _("%s: Wrong size for input argument #%d: A matrix of size %d x %d expected.\n"), "sparse", 3, 1, 2);
                 return types::Function::Error;
             }
 
-            if (pDims->get(0) != (double) ( (unsigned int) pDims->get(0) ) || pDims->get(1) != (double) ( (unsigned int) pDims->get(1) ))
+            if (pDdims->get(0) != (double) ( (unsigned int) pDdims->get(0) ) || pDdims->get(1) != (double) ( (unsigned int) pDdims->get(1) ))
             {
                 Scierror(999, _("%s: Wrong values for input argument #%d: Positive integers expected.\n"), "sparse", 3);
                 return types::Function::Error;
             }
-
-
-            if (pDims->get(0) * pDims->get(1) == 0)
-            {
-                out.push_back(types::Double::Empty());
-                return types::Function::OK;
-            }
         }
 
-        types::Double* ij = in[0]->getAs<types::Double>();
-        types::GenericType* pGT2 = in[1]->getAs<types::GenericType>();
+        bool alloc = false;
+        double* i = pDij->get();
+        double* j = i + size;
 
-        if (pGT2->getSize() != ij->getRows())
+        if ( (size > 0) && ((*std::min_element(i, i + size) <= 0) || (*std::min_element(j, j + size) <= 0)) )
         {
-            Scierror(999, _("%s: Wrong size for input argument #%d: A matrix of size %d expected.\n"), "sparse", 2, ij->getRows());
+            Scierror(999, _("%s: Invalid index.\n"), "sparse");
             return types::Function::Error;
         }
 
-        bool alloc = false;
-        if (pDims == nullptr)
+        if (pDdims == nullptr)
         {
-            int size = ij->getRows();
-            double* i = ij->get();
-            double* j = i + ij->getRows();
-            pDims = new types::Double(1, 2, false);
-            pDims->set(0, *std::max_element(i, i + size));
-            pDims->set(1, *std::max_element(j, j + size));
+            pDdims = new types::Double(1, 2, false);
+            pDdims->setZeros();
+            if (size > 0)
+            {
+                pDdims->set(0, *std::max_element(i, i + size));
+                pDdims->set(1, *std::max_element(j, j + size));
+            }
             alloc = true;
         }
+        else if ( (size > 0) && ((pDdims->get(0) < *std::max_element(i, i + size)) || (pDdims->get(1) < *std::max_element(j, j + size))) )
+        {
+            Scierror(999, _("%s: Invalid index.\n"),"sparse");
+            return types::Function::Error;
+        }
 
-        if (in[1]->isDouble())
+        if ((pDdims->get(0) == 0) || (pDdims->get(1) == 0))
+        {
+            pRetVal = new types::Sparse(0,0,false);
+        }
+        else if (in[1]->isDouble())
         {
-            types::Double* dbl = pGT2->getAs<types::Double>();
-            pRetVal = new types::Sparse(*dbl, *ij, *pDims);
+            types::Double* pDbl = pGT2->getAs<types::Double>();
+            pRetVal = new types::Sparse(*pDbl, *pDij, *pDdims);
         }
         else
         {
-            types::Bool* b = pGT2->getAs<types::Bool>();
-            pRetVal = new types::SparseBool(*b, *ij, *pDims);
+            types::Bool* pBb = pGT2->getAs<types::Bool>();
+            pRetVal = new types::SparseBool(*pBb, *pDij, *pDdims);
         }
 
         if (alloc)
         {
-            delete pDims;
+            delete pDdims;
         }
     }
 
diff --git a/scilab/modules/sparse/tests/nonreg_tests/bug_15750.tst b/scilab/modules/sparse/tests/nonreg_tests/bug_15750.tst
new file mode 100644 (file)
index 0000000..5413655
--- /dev/null
@@ -0,0 +1,22 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2018 - Stéphane Mottelet
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+// <-- Non-regression test for bug 15750 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=15750
+//
+// <-- Short Description -->
+// sparse(0,0) crashes Scilab 6
+
+msg = sprintf(_("%s: Wrong size for input argument #%d: A matrix of size %d x %d expected.\n"), "sparse", 1, 1, 2);
+
+assert_checkerror("sparse(0,0)", msg);
+assert_checkerror("sparse(1,1)", msg);
+
diff --git a/scilab/modules/sparse/tests/nonreg_tests/bug_15758.tst b/scilab/modules/sparse/tests/nonreg_tests/bug_15758.tst
new file mode 100644 (file)
index 0000000..c97abf7
--- /dev/null
@@ -0,0 +1,24 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2018 - Stéphane Mottelet
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+// <-- Non-regression test for bug 15758 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=15758
+//
+// <-- Short Description -->
+// sparse([0 0],1) crashes scilab (regression)
+
+msg = sprintf(_("%s: Invalid index.\n"), "sparse");
+assert_checkerror("sparse([0 0],1,[1 1])", msg);
+assert_checkerror("sparse([0 1],1,[1 1])", msg);
+assert_checkerror("sparse([1 0],1,[1 1])", msg);
+assert_checkerror("sparse([2 1],1,[1 1])", msg);
+assert_checkerror("sparse([1 2],1,[1 1])", msg);
+assert_checkerror("sparse([2 2],1,[1 1])", msg);