* Bug 16135 fixed: now base2dec detects invalid numbers 33/21033/3
Stéphane MOTTELET [Wed, 10 Jul 2019 20:58:45 +0000 (22:58 +0200)]
https://bugzilla.scilab.org/show_bug.cgi?id=16135

Change-Id: I989bf9fe2834463d95d0afda9bd62a43d8eac1c7

scilab/CHANGES.md
scilab/modules/elementary_functions/Makefile.am
scilab/modules/elementary_functions/includes/elem_func_gw.hxx
scilab/modules/elementary_functions/includes/gw_elementary_functions.h
scilab/modules/elementary_functions/sci_gateway/c/sci_base2dec.c [deleted file]
scilab/modules/elementary_functions/sci_gateway/cpp/elem_func_gw/elem_func_gw.vcxproj
scilab/modules/elementary_functions/sci_gateway/cpp/elem_func_gw/elem_func_gw.vcxproj.filters
scilab/modules/elementary_functions/sci_gateway/cpp/sci_base2dec.cpp [new file with mode: 0644]
scilab/modules/elementary_functions/tests/nonreg_tests/bug_16135.tst [new file with mode: 0644]

index bb8127b..0d26c2f 100644 (file)
@@ -243,6 +243,7 @@ Bug Fixes
 * [#16104](http://bugzilla.scilab.org/show_bug.cgi?id=16104): `assert_checkequal()` did not support properly or at all Nan and void in lists, Nan in sparse, implicit lists, macros, libraries, built-in functions, graphical handles. For input arrays or lists of matching typeof and sizes, the failure message did not display neither the index nor the values of the first mismatching elements.
 * [#16111](http://bugzilla.scilab.org/show_bug.cgi?id=16111): `isglobal` was not supporting non-scalar array of strings as input.
 * [#16118](http://bugzilla.scilab.org/show_bug.cgi?id=16118): `%s <> (1+%s)` returned %F.
+* [#16135](http://bugzilla.scilab.org/show_bug.cgi?id=16135): base2dec did not detect invalid numbers.
 * [#16139](http://bugzilla.scilab.org/show_bug.cgi?id=16139): `auread()` and `auwrite()` kept the sound file open and locked when returning on errors. They poorly handled the default .au sound file extension.
 * [#16143](http://bugzilla.scilab.org/show_bug.cgi?id=16143): `clc(n)` cleared n+1 lines instead of n>0. Thus, it was not possible to clear only one line. 
 * [#16144](http://bugzilla.scilab.org/show_bug.cgi?id=16144): Addition of sparse matrices gave incorrect results.
index a9af454..2b02516 100644 (file)
@@ -280,8 +280,8 @@ GATEWAY_C_SOURCES = \
     sci_gateway/c/sci_number_properties.c \
     sci_gateway/c/sci_testmatrix.c \
     sci_gateway/c/sci_isequalbitwise.c \
-    sci_gateway/c/sci_base2dec.c \
-    sci_gateway/c/sci_dec2base.c
+    sci_gateway/c/sci_dec2base.c \
+    sci_gateway/c/sci_log10.c
 
 GATEWAY_CXX_SOURCES =  \
     sci_gateway/cpp/sci_isequal.cpp \
@@ -335,11 +335,12 @@ GATEWAY_CXX_SOURCES =  \
     sci_gateway/cpp/sci_sign.cpp \
     sci_gateway/cpp/sci_sqrt.cpp \
     sci_gateway/cpp/sci_issquare.cpp \
-    sci_gateway/cpp/sci_isvector.cpp \
-    sci_gateway/cpp/sci_nearfloat.cpp \
-    sci_gateway/cpp/sci_permute.cpp \
-    sci_gateway/cpp/sci_bitstring.cpp \
-    sci_gateway/cpp/sci_linspace.cpp
+    sci_gateway/cpp/sci_linspace.cpp \
+    sci_gateway/cpp/sci_isvector.cpp\
+    sci_gateway/cpp/sci_nearfloat.cpp\
+    sci_gateway/cpp/sci_permute.cpp\
+    sci_gateway/cpp/sci_bitstring.cpp\
+    sci_gateway/cpp/sci_base2dec.cpp    
 
 EISPACK_SOURCES = src/fortran/eispack/balbak.f
 
index 5673a12..86c5326 100644 (file)
@@ -48,6 +48,7 @@ CPP_GATEWAY_PROTOTYPE(sci_asin);
 CPP_GATEWAY_PROTOTYPE(sci_asinh);
 CPP_GATEWAY_PROTOTYPE(sci_atan);
 CPP_GATEWAY_PROTOTYPE(sci_atanh);
+CPP_GATEWAY_PROTOTYPE(sci_base2dec);
 CPP_GATEWAY_PROTOTYPE(sci_bitstring);
 CPP_GATEWAY_PROTOTYPE(sci_ceil);
 CPP_GATEWAY_PROTOTYPE(sci_clean);
index d42d796..4c0d693 100644 (file)
@@ -66,7 +66,7 @@ STACK_GATEWAY_PROTOTYPE(sci_number_properties);
 STACK_GATEWAY_PROTOTYPE(sci_testmatrix);
 //STACK_GATEWAY_PROTOTYPE(sci_tril);
 //STACK_GATEWAY_PROTOTYPE(sci_triu);
-STACK_GATEWAY_PROTOTYPE(sci_base2dec);
+//STACK_GATEWAY_PROTOTYPE(sci_base2dec);
 STACK_GATEWAY_PROTOTYPE(sci_dec2base);
 //STACK_GATEWAY_PROTOTYPE(sci_log10);
 C_GATEWAY_PROTOTYPE(sci_isvector);
diff --git a/scilab/modules/elementary_functions/sci_gateway/c/sci_base2dec.c b/scilab/modules/elementary_functions/sci_gateway/c/sci_base2dec.c
deleted file mode 100644 (file)
index 0ddfdfb..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2011 - DIGITEO - Allan CORNET
- *
- * Copyright (C) 2012 - 2016 - Scilab Enterprises
- *
- * This file is hereby licensed under the terms of the GNU GPL v2.0,
- * pursuant to article 5.3.4 of the CeCILL v.2.1.
- * This file was originally licensed under the terms of the CeCILL v2.1,
- * and continues to be available under such terms.
- * For more information, see the COPYING file which you should have received
- * along with this program.
- *
- */
-/*--------------------------------------------------------------------------*/
-#include <math.h>
-#include "gw_elementary_functions.h"
-#include "sci_malloc.h"
-#include "api_scilab.h"
-#include "Scierror.h"
-#include "localization.h"
-#include "convertbase.h"
-/*--------------------------------------------------------------------------*/
-
-int sci_base2dec(char *fname, void* pvApiCtx)
-{
-    SciErr sciErr;
-    int *piAddressVarOne = NULL;
-    int *piAddressVarTwo = NULL;
-    int iValue = 0;
-    double dValue = 0.;
-    char **pStrs = NULL;
-    int m = 0;
-    int n = 0;
-    double *dResults = NULL;
-    int i = 0;
-
-    CheckInputArgument(pvApiCtx, 2, 2);
-    CheckOutputArgument(pvApiCtx, 0, 1);
-
-    sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVarOne);
-    if (sciErr.iErr)
-    {
-        printError(&sciErr, 0);
-        Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
-        return 1;
-    }
-
-    if (!isStringType(pvApiCtx, piAddressVarOne))
-    {
-        Scierror(999, _("%s: Wrong type for input argument #%d: A matrix of string expected.\n"), fname, 1);
-        return 1;
-    }
-
-    sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddressVarTwo);
-    if (sciErr.iErr)
-    {
-        Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
-        printError(&sciErr, 0);
-        return 1;
-    }
-
-    if (!isDoubleType(pvApiCtx, piAddressVarTwo))
-    {
-        Scierror(999, _("%s: Wrong type for input argument #%d: An integer value expected.\n"), fname, 2);
-        return 1;
-    }
-
-    if (!isScalar(pvApiCtx, piAddressVarTwo))
-    {
-        Scierror(999, _("%s: Wrong size for input argument #%d.\n"), fname, 2);
-        return 1;
-    }
-
-    if (getScalarDouble(pvApiCtx, piAddressVarTwo, &dValue) != 0)
-    {
-        Scierror(999, _("%s: No more memory.\n"), fname);
-        return 1;
-    }
-
-    iValue = (int)dValue;
-    if (dValue != (double)iValue)
-    {
-        Scierror(999, _("%s: Wrong value for input argument #%d: An integer value expected.\n"), fname, 2);
-        return 1;
-    }
-
-    if (iValue < 2 || iValue > 36)
-    {
-        Scierror(999, _("%s: Wrong value for input argument #%d: Must be between %d and %d."), fname, 2, 2, 36);
-        return 1;
-    }
-
-    if (getAllocatedMatrixOfString(pvApiCtx, piAddressVarOne, &m, &n, &pStrs) != 0)
-    {
-        if (pStrs)
-        {
-            freeAllocatedMatrixOfString(m, n, pStrs);
-        }
-
-        Scierror(999, _("%s: No more memory.\n"), fname);
-        return 1;
-    }
-
-    dResults = (double*)MALLOC(sizeof(double) * (m * n));
-    if (dResults == NULL)
-    {
-        freeAllocatedMatrixOfString(m, n, pStrs);
-        pStrs = NULL;
-
-        Scierror(999, _("%s: No more memory.\n"), fname);
-        return 1;
-    }
-
-    for (i = 0; i < m * n; i++)
-    {
-        error_convertbase err = ERROR_CONVERTBASE_NOK;
-        dResults[i] = convertBase2Dec(pStrs[i], iValue, &err);
-        if (err != ERROR_CONVERTBASE_OK)
-        {
-            freeAllocatedMatrixOfString(m, n, pStrs);
-            pStrs = NULL;
-
-            FREE(dResults);
-            dResults = NULL;
-
-            Scierror(999, _("%s: Wrong value for input argument #%d: Valid base %d representations expected.\n"), fname, 1, iValue);
-            return 1;
-        }
-    }
-
-    freeAllocatedMatrixOfString(m, n, pStrs);
-    pStrs = NULL;
-
-    sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, m, n, dResults);
-
-    FREE(dResults);
-    dResults = NULL;
-
-    if (sciErr.iErr)
-    {
-        printError(&sciErr, 0);
-        Scierror(999, _("%s: Memory allocation error.\n"), fname);
-        return 1;
-    }
-
-    AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1;
-    ReturnArguments(pvApiCtx);
-    return 0;
-}
-/*--------------------------------------------------------------------------*/
index be79334..b4c1730 100644 (file)
@@ -205,7 +205,6 @@ lib /DEF:"$(ProjectDir)elementary_functions_Import.def" /SUBSYSTEM:WINDOWS /MACH
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\..\src\cpp\getmode.cpp" />
-    <ClCompile Include="..\..\c\sci_base2dec.c" />
     <ClCompile Include="..\..\c\sci_dec2base.c" />
     <ClCompile Include="..\..\c\sci_isequalbitwise.c" />
     <ClCompile Include="..\..\c\sci_number_properties.c" />
@@ -218,6 +217,7 @@ lib /DEF:"$(ProjectDir)elementary_functions_Import.def" /SUBSYSTEM:WINDOWS /MACH
     <ClCompile Include="..\sci_asinh.cpp" />
     <ClCompile Include="..\sci_atan.cpp" />
     <ClCompile Include="..\sci_atanh.cpp" />
+    <ClCompile Include="..\sci_base2dec.cpp" />
     <ClCompile Include="..\sci_bitstring.cpp" />
     <ClCompile Include="..\sci_ceil.cpp" />
     <ClCompile Include="..\sci_clean.cpp" />
index e98acf5..c0c34ae 100644 (file)
     <ClCompile Include="..\sci_isequal.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\c\sci_base2dec.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\c\sci_dec2base.c">
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClCompile Include="..\sci_linspace.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\sci_base2dec.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\..\includes\elem_func_gw.hxx">
diff --git a/scilab/modules/elementary_functions/sci_gateway/cpp/sci_base2dec.cpp b/scilab/modules/elementary_functions/sci_gateway/cpp/sci_base2dec.cpp
new file mode 100644 (file)
index 0000000..c75d3ab
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2019 - Stéphane MOTTELET
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
+ *
+/*--------------------------------------------------------------------------*/
+
+#include <string>
+#include "function.hxx"
+#include "double.hxx"
+#include "string.hxx"
+#include "overload.hxx"
+#include "elem_func_gw.hxx"
+
+extern "C"
+{
+#include "Scierror.h"
+}
+
+/*--------------------------------------------------------------------------*/
+types::Function::ReturnValue sci_base2dec(types::typed_list &in, int _iRetCount, types::typed_list &out)
+{
+    if (in.size() != 2)
+    {
+        Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "base2dec", 2);
+        return types::Function::Error;
+    }
+
+    if (_iRetCount > 1)
+    {
+        Scierror(77, _("%s: Wrong number of output argument(s): %d expected.\n"), "base2dec", 1);
+        return types::Function::Error;
+    }
+
+    if (in[1]->isDouble() == false || in[1]->getAs<types::Double>()->isComplex() == true)
+    {
+        Scierror(999, _("%s: Wrong type for input argument #%d: A scalar integer value expected.\n"), "base2dec", 2);
+        return types::Function::Error;
+    }
+
+    if (in[1]->getAs<types::Double>()->isScalar() == false)
+    {
+        Scierror(999, _("%s: Wrong size for input argument #%d: A scalar integer value expected.\n"), "base2dec", 2);
+        return types::Function::Error;
+    }
+
+    double dBaseUsed = in[1]->getAs<types::Double>()->get(0);
+    if (dBaseUsed != trunc(dBaseUsed))
+    {
+        Scierror(999, _("%s: Wrong value for input argument #%d: An integer value expected.\n"), "base2dec", 2);
+        return types::Function::Error;
+    }
+
+    if (dBaseUsed < 2 || dBaseUsed > 36)
+    {
+        Scierror(999, _("%s: Wrong value for input argument #%d: Must be between %d and %d."), "base2dec", 2, 2, 36);
+        return types::Function::Error;
+    }
+
+    if (in[0]->isString())
+    {
+        types::String* pS = in[0]->getAs<types::String>();
+        types::Double* pOut = new types::Double(pS->getDims(), pS->getDimsArray());
+
+        int iBaseUsed = (unsigned int)dBaseUsed;
+        double dblValue;
+
+        for (int i = 0; i < pS->getSize(); i++)
+        {
+            size_t iPos;
+            try
+            {
+                dblValue = (double)std::stoll(pS->get(i), &iPos, iBaseUsed);
+                // manually throw exceptions when not thrown by std::stoll but error should be triggered
+                if (dblValue > pow(2, 53))
+                {
+                    throw std::out_of_range("");
+                }
+
+                if (iPos < wcslen(pS->get(i)))
+                {
+                    throw std::invalid_argument("");
+                }
+            }
+            catch (std::out_of_range)
+            {
+                Scierror(999, _("%s: Wrong value for input argument #%d: converted value is out of range.\n"), "base2dec", 1);
+                pOut->killMe();
+                return types::Function::Error;
+            }
+            catch (std::invalid_argument)
+            {
+                Scierror(999, _("%s: Wrong value for input argument #%d: Valid base %d representations expected.\n"), "base2dec", 1, iBaseUsed);
+                pOut->killMe();
+                return types::Function::Error;
+            }
+
+            pOut->set(i, dblValue);
+        }
+
+        out.push_back(pOut);
+        return types::Function::OK;
+    }
+    else
+    {
+        Scierror(999, _("%s: Wrong type for input argument #%d: a string expected.\n"), "base2dec", 2);
+        return types::Function::Error;
+    }
+
+}
+/*--------------------------------------------------------------------------*/
diff --git a/scilab/modules/elementary_functions/tests/nonreg_tests/bug_16135.tst b/scilab/modules/elementary_functions/tests/nonreg_tests/bug_16135.tst
new file mode 100644 (file)
index 0000000..f9c360e
--- /dev/null
@@ -0,0 +1,20 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2019 - 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 16135 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/16135
+//
+// <-- Short Description -->
+// base2dec does not detect invalid numbers
+
+message = msprintf(_("%s: Wrong value for input argument #%d: Valid base %d representations expected.\n"), "base2dec", 1, 2);
+assert_checkerror("base2dec(""3"",2)", message)
\ No newline at end of file