bug 4807
Allan CORNET [Mon, 21 Sep 2009 08:50:47 +0000 (10:50 +0200)]
scilab/CHANGES_5.2.X
scilab/modules/string/includes/strsubst.h
scilab/modules/string/sci_gateway/c/sci_strsubst.c
scilab/modules/string/src/c/strsubst.c
scilab/modules/string/tests/nonreg_tests/bug_4807.dia.ref [new file with mode: 0644]
scilab/modules/string/tests/nonreg_tests/bug_4807.tst [new file with mode: 0644]

index b73bd10..9eab7e8 100644 (file)
@@ -243,6 +243,8 @@ Linear algebra
 Bug fixes:
 ==========
 
+* bug 415 fixed - wrong order in the roots of a polynomial
+
 * bug 1412 fixed - A(3,3)=%s,A(:)=%z causes scilab to hang
 
 * bug 1628 fixed - with long programs (several hours) I get a negative value for
@@ -436,9 +438,9 @@ Bug fixes:
 
 * bug 4789 fixed - number of input arguments is not checked in ilib_functions (dynamic_link module)
 
-* bug 4795 fixed - CallScilab.h renamed call_scilab.h
+* bug 4792 fixed - macro name too long
 
-* bug 415 fixed - wrong order in the roots of a polynomial
+* bug 4795 fixed - CallScilab.h renamed call_scilab.h
 
-* bug 4792 fixed - macro name too long
+* bug 4807 fixed - strsubst does not check if second argument is a valid patter where fourth argument is 'r'.
 
index 948cc06..03ccc6a 100644 (file)
 * @return substituted string matrix
 */
 STRING_IMPEXP char **strsubst(char **strings_input,int strings_dim,char *string_to_search,char *replacement_string);
-STRING_IMPEXP char **strsubst_reg(char **strings_input,int strings_dim,char *string_to_search,char *replacement_string);
+STRING_IMPEXP char **strsubst_reg(char **strings_input,int strings_dim,char *string_to_search,char *replacement_string, int *ierr);
 
 /**
 * substitute a character string by another in a character string
 * @param[in] string 
 * @param[in] string to search in input_string
 * @param[in] replacement_string
+* @param[out] error returned by pcre_private
 * @return substituted string
 */
 STRING_IMPEXP char *strsub(char* input_string, const char* string_to_search, const char* replacement_string);
-STRING_IMPEXP char *strsub_reg(char* input_string, const char* string_to_search, const char* replacement_string);
+STRING_IMPEXP char *strsub_reg(char* input_string, const char* string_to_search, const char* replacement_string, int *ierr);
 
 #endif /* __STRSUBST_H__ */
index bf3e041..b5b0bdc 100644 (file)
@@ -2,6 +2,7 @@
 /*
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) INRIA - Cong WU , Allan CORNET
+ * Copyright (C) DIGITEO - 2009 - Allan CORNET
  *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
-
-/* desc : substitute a character string by another in a character string  */
 /*------------------------------------------------------------------------*/
 #include <string.h>
-#include <stdio.h>
 #include "gw_string.h"
 #include "stack-c.h"
 #include "MALLOC.h"
+#include "api_common.h"
+#include "api_string.h"
+#include "api_double.h"
 #include "freeArrayOfString.h"
 #include "strsubst.h"
 #include "localization.h"
 #include "Scierror.h"
+#include "pcre_error.h"
+#include "pcre_private.h"
+#include "BOOL.h"
 /*-------------------------------------------------------------------------------------*/
 #define CHAR_R "r"
 #define CHAR_S "s"
 /*-------------------------------------------------------------------------------------*/
 int sci_strsubst(char *fname,unsigned long fname_len)
 {
-       BOOL bStrsubst_with_pattern = FALSE;
+       int *piAddressVarOne = NULL;
+       int mOne = 0, nOne = 0;
+
        CheckRhs(3,4);
        CheckLhs(1,1);
 
-       switch (VarType(1))
+       getVarAddressFromPosition(1, &piAddressVarOne);
+
+       if (getVarType(piAddressVarOne) == sci_strings)
        {
-               case sci_matrix :
+               char **pStVarOne = NULL;
+               int *lenStVarOne = NULL;
+
+               int *piAddressVarTwo = NULL;
+               int mTwo = 0, nTwo = 0;
+               char *pStVarTwo = NULL;
+               int lenStVarTwo = 0;
+
+               int *piAddressVarThree = NULL;
+               int mThree = 0, nThree = 0;
+               char *pStVarThree = NULL;
+               int lenStVarThree = 0;
+
+               BOOL isRegExp = FALSE;
+
+               if (Rhs == 4)
                {
-                       int m = 0, n = 0 , l = 0;
-                       GetRhsVar(1,MATRIX_OF_DOUBLE_DATATYPE,&m,&n,&l);
-                       if ( (m == 0) && (n == 0) ) /* strsubst([],...) */
+                       int *piAddressVarFour = NULL;
+                       int mFour = 0, nFour = 0;
+                       char *pStVarFour = NULL;
+                       int lenStVarFour = 0;
+
+                       getVarAddressFromPosition(4, &piAddressVarFour);
+
+                       if ( getVarType(piAddressVarFour) != sci_strings )
                        {
-                               l = 0;
-                               CreateVar(Rhs+1,MATRIX_OF_DOUBLE_DATATYPE,&m,&n,&l);
-                               LhsVar(1) = Rhs+1 ;
-                               C2F(putlhsvar)();
+                               Scierror(999,_("%s: Wrong type for input argument #%d: A string expected.\n"),fname,4);
                                return 0;
                        }
-                       else
+
+                       getMatrixOfString(piAddressVarFour,&mFour,&nFour,&lenStVarFour,&pStVarFour);
+                       if ( (mFour != nFour) && (nFour != 1) ) 
                        {
-                               Scierror(999,_("%s: Wrong type for input argument #%d: Matrix of strings or empty matrix expected.\n"), fname);
+                               Scierror(999,_("%s: Wrong size for input argument #%d: A string expected.\n"),fname,4);
                                return 0;
                        }
-               }
-               break;
 
-               case sci_strings:
-               {
-                       int m1 = 0 , n1 = 0;
-                       int m1n1 = 0; /* m1 * n1 */
-                       char **strings_input = NULL;
-                       
-                       int m2 = 0 , n2 = 0;
-                       int m2n2 = 0; /* m2 * n2 */
-                       char **string_to_search = NULL;
-                       
-                       int m3 = 0 , n3 = 0;
-                       int m3n3 = 0; /* m2 * n2 */
-                       char **replacement_string = NULL;
-                       
-                       char **Output_StringMatrix = NULL;
-                       
-                       if ( (VarType(2) != sci_strings) || (VarType(3) != sci_strings))
+                       pStVarFour = (char*)MALLOC(sizeof(char)*(lenStVarFour + 1));
+                       if (pStVarFour)
                        {
-                               if(VarType(2) != sci_strings)
+                               getMatrixOfString(piAddressVarFour, &mFour, &nFour, &lenStVarFour, &pStVarFour);
+                               if ( (strcmp(pStVarFour,CHAR_R) == 0) || (strcmp(pStVarFour,CHAR_S) == 0) )
                                {
-                                       Scierror(999,_("%s: Wrong type for input argument #%d: A string expected.\n"),fname,2);
+                                       if (strcmp(pStVarFour,CHAR_R) == 0)
+                                       {
+                                               isRegExp = TRUE;
+                                       }
+                                       else
+                                       {
+                                               isRegExp = FALSE;
+                                       }
                                }
                                else
                                {
-                                       Scierror(999,_("%s: Wrong type for input argument #%d: A string expected.\n"),fname,3);
+                                       FREE(pStVarFour); pStVarFour = NULL;
+                                       Scierror(999,_("%s: Wrong value for input argument #%d: 's' or 'r' expected.\n"),fname,4);
+                                       return 0;
                                }
-                               
-                               return 0;
                        }
-                       
-                       GetRhsVar(1,MATRIX_OF_STRING_DATATYPE,&m1,&n1,&strings_input);
-                       m1n1 = m1 * n1 ;
-                               
-                       GetRhsVar(2,MATRIX_OF_STRING_DATATYPE,&m2,&n2,&string_to_search);
-                       m2n2 = m2 * n2 ;
-
-                       if (m2n2 != 1)
-                       {
-                               freeArrayOfString(strings_input,m1n1);
-                               freeArrayOfString(string_to_search,m2n2);
-                               Scierror(36,_("%s: Wrong size for input argument #%d: A string expected.\n"), fname,2);
-                               return 0;
-                       }
-                       GetRhsVar(3,MATRIX_OF_STRING_DATATYPE,&m3,&n3,&replacement_string);
-                       m3n3 = m3 * n3 ;
-                       if (m3n3 != 1)
+                       else
                        {
-                               freeArrayOfString(strings_input,m1n1);
-                               freeArrayOfString(string_to_search,m2n2);
-                               freeArrayOfString(replacement_string,m3n3);
-                               Scierror(36,_("%s: Wrong size for input argument #%d: A string expected.\n"),fname,3);
+                               Scierror(999,_("%s: No more memory.\n"),fname);
                                return 0;
                        }
+               }
+
+               getVarAddressFromPosition(3, &piAddressVarThree);
+
+               // checks type 3th input argument
+               if ( getVarType(piAddressVarThree) != sci_strings )
+               {
+                       Scierror(999,_("%s: Wrong type for input argument #%d: A string expected.\n"),fname,3);
+                       return 0;
+               }
+
+               // checks dimension 3th input argument
+               getMatrixOfString(piAddressVarThree,&mThree,&nThree,&lenStVarThree,&pStVarThree);
+               if ( (mThree != nThree) && (nThree != 1) ) 
+               {
+                       Scierror(999,_("%s: Wrong size for input argument #%d: A string expected.\n"),fname,3);
+                       return 0;
+               }
+
+               getVarAddressFromPosition(2, &piAddressVarTwo);
+
+               // checks type 2nd input argument
+               if ( getVarType(piAddressVarTwo) != sci_strings )
+               {
+                       Scierror(999,_("%s: Wrong type for input argument #%d: A string expected.\n"),fname,2);
+                       return 0;
+               }
 
-                       if (Rhs == 4)
+               // checks dimension 2nd input argument
+               getMatrixOfString(piAddressVarTwo,&mTwo,&nTwo,&lenStVarTwo,&pStVarTwo);
+               if ( (mTwo != nTwo) && (nTwo != 1) ) 
+               {
+                       Scierror(999,_("%s: Wrong size for input argument #%d: A string expected.\n"),fname,2);
+                       return 0;
+               }
+
+               getVarAddressFromPosition(1, &piAddressVarOne);
+
+               // checks type 1st input argument
+               if ( getVarType(piAddressVarOne) != sci_strings )
+               {
+                       Scierror(999,_("%s: Wrong type for input argument #%d: A string expected.\n"),fname,1);
+                       return 0;
+               }
+
+               // get length 3th input argument
+               getMatrixOfString(piAddressVarThree, &mThree, &nThree, &lenStVarThree, &pStVarThree);
+               pStVarThree = (char*)MALLOC(sizeof(char)*(lenStVarThree + 1));
+               if (pStVarThree)
+               {
+                       // get value 3th input argument
+                       getMatrixOfString(piAddressVarThree, &mThree, &nThree, &lenStVarThree, &pStVarThree);
+
+                       // get length 2nd input argument
+                       getMatrixOfString(piAddressVarTwo, &mTwo, &nTwo, &lenStVarTwo, &pStVarTwo);
+                       pStVarTwo = (char*)MALLOC(sizeof(char)*(lenStVarTwo + 1));
+                       if (pStVarTwo)
                        {
-                               int m4 = 0;
-                               int n4 = 0;
-                               char **Strings_Input4 = NULL;
-                               int m4n4 = 0; /* m4 * n4 */
+                               // get value 2nd input argument
+                               getMatrixOfString(piAddressVarTwo, &mTwo, &nTwo, &lenStVarTwo, &pStVarTwo);
 
-                               if (VarType(4) != sci_strings)
-                               {
-                                       freeArrayOfString(strings_input,m1n1);
-                                       freeArrayOfString(string_to_search,m2n2);
-                                       freeArrayOfString(replacement_string,m3n3);
-                                       Scierror(999,_("%s: Wrong type for input argument #%d: A character expected.\n"),fname,4);
-                                       return 0;
-                               }
-                               GetRhsVar(4,MATRIX_OF_STRING_DATATYPE,&m4,&n4,&Strings_Input4);
-                               m4n4 = m4*n4;  
-                               
-                               if (m4n4 != 1)
-                               {
-                                       freeArrayOfString(strings_input,m1n1);
-                                       freeArrayOfString(string_to_search,m2n2);
-                                       freeArrayOfString(replacement_string,m3n3);
-                                       freeArrayOfString(Strings_Input4,m4n4);
-                                       Scierror(999,_("%s: Wrong size for input argument #%d: A character expected.\n"),fname,4);
-                                       return 0;
-                               }
-                               
-                               if ( (strcmp(Strings_Input4[0],CHAR_R) == 0) || (strcmp(Strings_Input4[0],CHAR_S) == 0) )
+                               getMatrixOfString(piAddressVarOne,&mOne,&nOne,lenStVarOne,pStVarOne);
+
+                               lenStVarOne = (int *)MALLOC(sizeof(int) * (mOne * nOne));
+                               if (lenStVarOne)
                                {
-                                       if (strcmp(Strings_Input4[0],CHAR_R) == 0)
+                                       getMatrixOfString(piAddressVarOne,&mOne,&nOne,lenStVarOne,pStVarOne);
+
+                                       pStVarOne = (char **)MALLOC(sizeof(char *) * (mOne * nOne));
+                                       if (pStVarOne)
                                        {
-                                               bStrsubst_with_pattern = TRUE;
+                                               char **Output_StringMatrix = NULL;
+
+                                               int i = 0;
+                                               for (i = 0; i < mOne * nOne; i++)
+                                               {
+                                                       pStVarOne[i] = (char*)MALLOC(sizeof(char) * (lenStVarOne[i] + 1));
+                                                       if (pStVarOne[i] == NULL)
+                                                       {
+                                                               FREE(pStVarThree); pStVarThree = NULL;
+                                                               FREE(pStVarTwo); pStVarTwo = NULL;
+                                                               FREE(lenStVarOne); lenStVarOne = NULL;
+                                                               freeArrayOfString(pStVarOne, i);
+                                                               Scierror(999,_("%s: No more memory.\n"), fname);
+                                                               return 0;
+                                                       }
+                                               }
+
+                                               getMatrixOfString(piAddressVarOne,&mOne,&nOne,lenStVarOne,pStVarOne);
+
+                                               FREE(lenStVarOne); lenStVarOne = NULL;
+
+                                               if (isRegExp)
+                                               {
+                                                       int ierr = (int)PCRE_FINISHED_OK;
+                                                       Output_StringMatrix = strsubst_reg(pStVarOne, mOne * nOne, pStVarTwo, pStVarThree, &ierr);
+                                                       if ( (ierr != PCRE_FINISHED_OK) && (ierr != NO_MATCH) && (ierr != PCRE_EXIT) )
+                                                       {
+                                                               FREE(pStVarThree); pStVarThree = NULL;
+                                                               FREE(pStVarTwo); pStVarTwo = NULL;
+                                                               pcre_error(fname, ierr);
+                                                               return 0;
+                                                       }
+                                               }
+                                               else
+                                               {
+                                                       Output_StringMatrix = strsubst(pStVarOne, mOne * nOne, pStVarTwo, pStVarThree);
+                                               }
+
+                                               FREE(pStVarThree); pStVarThree = NULL;
+                                               FREE(pStVarTwo); pStVarTwo = NULL;
+
+                                               createMatrixOfString(Rhs + 1, mOne, nOne, Output_StringMatrix);
+                                               LhsVar(1) = Rhs + 1 ;
+                                               C2F(putlhsvar)();
+                                               return 0;
                                        }
                                        else
                                        {
-                                               bStrsubst_with_pattern = FALSE;
+                                               FREE(pStVarThree); pStVarThree = NULL;
+                                               FREE(pStVarTwo); pStVarTwo = NULL;
+                                               FREE(lenStVarOne); lenStVarOne = NULL;
+                                               Scierror(999,_("%s: No more memory.\n"),fname);
+                                               return 0;
                                        }
-                                       freeArrayOfString(Strings_Input4,m4n4);
                                }
                                else
                                {
-                                       freeArrayOfString(strings_input,m1n1);
-                                       freeArrayOfString(string_to_search,m2n2);
-                                       freeArrayOfString(replacement_string,m3n3);
-                                       freeArrayOfString(Strings_Input4,m4n4);
-                                       Scierror(999,_("%s: Wrong value for input argument #%d: ''%s'' or ''%s'' expected.\n"),fname,4,"s","r");
+                                       FREE(pStVarThree); pStVarThree = NULL;
+                                       FREE(pStVarTwo); pStVarTwo = NULL;
+                                       Scierror(999,_("%s: No more memory.\n"),fname);
                                        return 0;
                                }
                        }
-                       
-                       if (bStrsubst_with_pattern)
-                       {
-                               Output_StringMatrix = strsubst_reg(strings_input,m1n1,string_to_search[0],replacement_string[0]);
-                       }
                        else
                        {
-                               Output_StringMatrix = strsubst(strings_input,m1n1,string_to_search[0],replacement_string[0]);
+                               FREE(pStVarThree); pStVarThree = NULL;
+                               Scierror(999,_("%s: No more memory.\n"),fname);
+                               return 0;
                        }
-                       freeArrayOfString(strings_input,m1n1);
-                       freeArrayOfString(string_to_search,m2n2);
-                       freeArrayOfString(replacement_string,m3n3);
-                       
-                       /* put on scilab stack */
-                       CreateVarFromPtr( Rhs+1,MATRIX_OF_STRING_DATATYPE, &m1, &n1,Output_StringMatrix );
-                       LhsVar(1) = Rhs+1 ;
+               }
+               else
+               {
+                       Scierror(999,_("%s: No more memory.\n"),fname);
+                       return 0;
+               }
+       }
+       else if (getVarType(piAddressVarOne) == sci_matrix)
+       {
+               getVarDimension(piAddressVarOne, &mOne, &nOne);
+               if ( (mOne == 0) && (nOne == 0) ) /* strsubst([],...) returns [] */
+               {
+                       createMatrixOfDouble(Rhs + 1, mOne, nOne, NULL);
+                       LhsVar(1) = Rhs + 1 ;
                        C2F(putlhsvar)();
-                       freeArrayOfString(Output_StringMatrix,m1n1);
+                       return 0;
                }
-               break;
-
-               default:
+               else
                {
-                       Scierror(999,_("%s: Wrong type for input argument #%d: Matrix of strings expected.\n"),fname,1);
+                       Scierror(999,_("%s: Wrong type for input argument #%d: Matrix of strings or empty matrix expected.\n"), fname);
                        return 0;
                }
-               break;
+       }
+       else
+       {
+               Scierror(999,_("%s: Wrong type for input argument #%d: A string expected.\n"), fname, 1);
+               return 0;
        }
        return 0;
 }
index 9e76423..ef4e81a 100644 (file)
@@ -41,7 +41,7 @@ char **strsubst(char **strings_input,int strings_dim,char *string_to_search,char
        return replacedStrings;
 }
 /*--------------------------------------------------------------------------*/
-char **strsubst_reg(char **strings_input,int strings_dim,char *string_to_search,char *replacement_string)
+char **strsubst_reg(char **strings_input,int strings_dim,char *string_to_search,char *replacement_string, int *ierr)
 {
        char **replacedStrings = NULL;
 
@@ -52,7 +52,7 @@ char **strsubst_reg(char **strings_input,int strings_dim,char *string_to_search,
                for (i = 0; i < strings_dim; i++)
                {
                        char *str = strings_input[i];
-                       replacedStrings[i] = strsub_reg(str,string_to_search,replacement_string);
+                       replacedStrings[i] = strsub_reg(str,string_to_search,replacement_string, ierr);
                }
        }
        return replacedStrings;
@@ -121,7 +121,7 @@ char *strsub(char* input_string, const char* string_to_search, const char* repla
 
        return replacedString;
 }/*-------------------------------------------------------------------------------------*/
-char *strsub_reg(char* input_string, const char* string_to_search, const char* replacement_string)
+char *strsub_reg(char* input_string, const char* string_to_search, const char* replacement_string, int *ierr)
 {
     pcre_error_code w = PCRE_FINISHED_OK;
 
@@ -136,15 +136,19 @@ char *strsub_reg(char* input_string, const char* string_to_search, const char* r
 
        int len = 0;
 
+       *ierr = (int)PCRE_FINISHED_OK;
+
        if (input_string == NULL) return NULL;
 
        if (string_to_search == NULL || replacement_string == NULL) 
        {
                return strdup(input_string);
        }
+
     w = pcre_private(input_string,(char*)string_to_search,&Output_Start,&Output_End);
        if (w != PCRE_FINISHED_OK)
        {
+               *ierr = (int)w;
                return strdup(input_string);
        }
 
@@ -153,6 +157,7 @@ char *strsub_reg(char* input_string, const char* string_to_search, const char* r
 
        if (wcreplacement_string == NULL || wcreplacement_string == NULL) 
        {
+               *ierr = (int)NOT_ENOUGH_MEMORY_FOR_VECTOR;
                return strdup(input_string);
        }
 
diff --git a/scilab/modules/string/tests/nonreg_tests/bug_4807.dia.ref b/scilab/modules/string/tests/nonreg_tests/bug_4807.dia.ref
new file mode 100644 (file)
index 0000000..ab21430
--- /dev/null
@@ -0,0 +1,20 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2009 - DIGITEO - Allan CORNET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- JVM NOT MANDATORY -->
+// <-- Non-regression test for bug 4807 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=4807
+//
+// <-- Short Description -->
+//strsubst does not check if second argument is a valid pattern when there is 'r' as
+// fourth argument
+//======================================================================================== 
+ierr = execstr("strsubst(''pattern -- pattern __ pattern '',''pattern'',''replace'',''r'');","errcatch");
+if ierr <> 999 then bugmes();quit;end
+ierr = execstr("strsubst(''pattern -- pattern __ pattern '',''/pattern/'',''replace'',''r'');","errcatch");
+if ierr <> 0 then bugmes();quit;end
diff --git a/scilab/modules/string/tests/nonreg_tests/bug_4807.tst b/scilab/modules/string/tests/nonreg_tests/bug_4807.tst
new file mode 100644 (file)
index 0000000..0c677e9
--- /dev/null
@@ -0,0 +1,21 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2009 - DIGITEO - Allan CORNET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- JVM NOT MANDATORY -->
+// <-- Non-regression test for bug 4807 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=4807
+//
+// <-- Short Description -->
+//strsubst does not check if second argument is a valid pattern when there is 'r' as
+// fourth argument
+//======================================================================================== 
+ierr = execstr("strsubst(''pattern -- pattern __ pattern '',''pattern'',''replace'',''r'');","errcatch");
+if ierr <> 999 then pause,end
+
+ierr = execstr("strsubst(''pattern -- pattern __ pattern '',''/pattern/'',''replace'',''r'');","errcatch");
+if ierr <> 0 then pause,end