[mapserver-commits] r11894 - branches/branch-5-0/mapserver

svn at osgeo.org svn at osgeo.org
Tue Jul 12 09:15:06 EDT 2011


Author: assefa
Date: 2011-07-12 06:15:06 -0700 (Tue, 12 Jul 2011)
New Revision: 11894

Modified:
   branches/branch-5-0/mapserver/HISTORY.TXT
   branches/branch-5-0/mapserver/maplayer.c
   branches/branch-5-0/mapserver/mapogcfilter.c
   branches/branch-5-0/mapserver/mapogcfilter.h
   branches/branch-5-0/mapserver/mapogcsos.c
   branches/branch-5-0/mapserver/mapogr.cpp
   branches/branch-5-0/mapserver/mappostgis.c
   branches/branch-5-0/mapserver/mapserver.h
Log:
Security fixes (#3903)

Modified: branches/branch-5-0/mapserver/HISTORY.TXT
===================================================================
--- branches/branch-5-0/mapserver/HISTORY.TXT	2011-07-12 13:13:38 UTC (rev 11893)
+++ branches/branch-5-0/mapserver/HISTORY.TXT	2011-07-12 13:15:06 UTC (rev 11894)
@@ -13,6 +13,14 @@
 Current Version (SVN branch, may never be released):
 ----------------------------------------------------
 
+IMPORTANT SECURITY FIXE:
+
+-  Fixes to prevent SQL injections through OGC filter encoding (in WMS, WFS 
+   and SOS), as well as a potential SQL injection in WMS time support. 
+   Your system may be vulnerable if it has MapServer with OGC protocols 
+   enabled, with layers connecting to an SQL RDBMS backend, either 
+   natively or via OGR (#3903)
+
 - Disabled some insecure (and potentially exploitable) mapserv command-line
   debug arguments (#3485). The --enable-cgi-cl-debug-args configure switch
   can be used to re-enable them for devs who really cannot get away without

Modified: branches/branch-5-0/mapserver/maplayer.c
===================================================================
--- branches/branch-5-0/mapserver/maplayer.c	2011-07-12 13:13:38 UTC (rev 11893)
+++ branches/branch-5-0/mapserver/maplayer.c	2011-07-12 13:15:06 UTC (rev 11894)
@@ -1079,6 +1079,85 @@
     return MS_FAILURE;
 }
 
+
+/************************************************************************/
+/*                          LayerDefaultEscapeSQLParam                  */
+/*                                                                      */
+/*      Default function used to escape strings and avoid sql           */
+/*      injection. Specific drivers should redefine if an escaping      */
+/*      function is available in the driver.                            */
+/************************************************************************/
+char *LayerDefaultEscapeSQLParam(layerObj *layer, const char* pszString)
+{
+     char *pszEscapedStr=NULL;
+     if (pszString)
+     {
+         int nSrcLen;
+         char c;
+         int i=0, j=0;
+         nSrcLen = (int)strlen(pszString);
+         pszEscapedStr = (char*) malloc( 2 * nSrcLen + 1);
+         for(i = 0, j = 0; i < nSrcLen; i++)
+         {
+             c = pszString[i];
+             if (c == '\'')
+             {
+                 pszEscapedStr[j++] = '\'';
+                 pszEscapedStr[j++] = '\'';
+             }
+             else if (c == '\\')
+             {
+                 pszEscapedStr[j++] = '\\';
+                 pszEscapedStr[j++] = '\\';
+             }
+             else
+               pszEscapedStr[j++] = c;
+         }
+         pszEscapedStr[j] = 0;
+     }  
+     return pszEscapedStr;
+}
+
+/************************************************************************/
+/*                          LayerDefaultEscapePropertyName              */
+/*                                                                      */
+/*      Return the property name in a properly escaped and quoted form. */
+/************************************************************************/
+char *LayerDefaultEscapePropertyName(layerObj *layer, const char* pszString)
+{
+     char* pszEscapedStr=NULL;
+     int i, j = 0;   
+
+     if (layer && pszString && strlen(pszString) > 0)
+     {
+         int nLength = strlen(pszString);
+
+         pszEscapedStr = (char*) malloc( 1 + 2 * nLength + 1 + 1);
+         pszEscapedStr[j++] = '"';
+
+         for (i=0; i<nLength; i++)
+         {
+             char c = pszString[i];
+             if (c == '"')
+             {
+                 pszEscapedStr[j++] = '"';
+                 pszEscapedStr[j++] ='"';
+             }
+             else if (c == '\\')
+             {
+                 pszEscapedStr[j++] = '\\';
+                 pszEscapedStr[j++] = '\\';
+             }
+             else
+               pszEscapedStr[j++] = c;
+         }
+         pszEscapedStr[j++] = '"';
+         pszEscapedStr[j++] = 0;
+        
+     }
+     return pszEscapedStr;
+}
+
 /*
  * msConnectLayer
  *
@@ -1136,6 +1215,10 @@
     
     vtable->LayerGetNumFeatures = LayerDefaultGetNumFeatures;
 
+    vtable->LayerEscapeSQLParam = LayerDefaultEscapeSQLParam;
+
+    vtable->LayerEscapePropertyName = LayerDefaultEscapePropertyName;
+
     return MS_SUCCESS;
 }
 
@@ -1300,6 +1383,31 @@
     return i;
 }
 
+
+/*
+Returns an escaped string
+*/
+char  *msLayerEscapeSQLParam(layerObj *layer, const char*pszString) 
+{
+    if ( ! layer->vtable) {
+        int rv =  msInitializeVirtualTable(layer);
+        if (rv != MS_SUCCESS)
+            return "";
+    }
+    return layer->vtable->LayerEscapeSQLParam(layer, pszString);
+}
+
+char  *msLayerEscapePropertyName(layerObj *layer, const char*pszString) 
+{
+    if ( ! layer->vtable) {
+        int rv =  msInitializeVirtualTable(layer);
+        if (rv != MS_SUCCESS)
+            return "";
+    }
+    return layer->vtable->LayerEscapePropertyName(layer, pszString);
+}
+
+
 int
 msINLINELayerInitializeVirtualTable(layerObj *layer)
 {
@@ -1331,5 +1439,8 @@
     /* layer->vtable->LayerCreateItems, use default */
     layer->vtable->LayerGetNumFeatures = msINLINELayerGetNumFeatures;
 
+    /*layer->vtable->LayerEscapeSQLParam, use default*/
+    /*layer->vtable->LayerEscapePropertyName, use default*/
+
     return MS_SUCCESS;
 }

Modified: branches/branch-5-0/mapserver/mapogcfilter.c
===================================================================
--- branches/branch-5-0/mapserver/mapogcfilter.c	2011-07-12 13:13:38 UTC (rev 11893)
+++ branches/branch-5-0/mapserver/mapogcfilter.c	2011-07-12 13:15:06 UTC (rev 11894)
@@ -276,7 +276,7 @@
         if (tokens && nTokens == 2)
         {
             char szTmp[32];
-            sprintf(szTmp, "init=epsg:%s",tokens[1]);
+            snprintf(szTmp,  sizeof(szTmp), "init=epsg:%s",tokens[1]);
             msInitProjection(&sProjTmp);
             if (msLoadProjectionString(&sProjTmp, szTmp) == 0)
               msProjectRect(&sProjTmp, &map->projection, &sQueryRect);
@@ -301,7 +301,7 @@
             if (nEpsgTmp > 0)
             {
                 char szTmp[32];
-                sprintf(szTmp, "init=epsg:%d",nEpsgTmp);
+                snprintf(szTmp,  sizeof(szTmp), "init=epsg:%d",nEpsgTmp);
                 msInitProjection(&sProjTmp);
                 if (msLoadProjectionString(&sProjTmp, szTmp) == 0)
                   msProjectRect(&sProjTmp, &map->projection,  &sQueryRect);
@@ -873,7 +873,7 @@
         if (tokens && nTokens == 2)
         {
             char szTmp[32];
-            sprintf(szTmp, "init=epsg:%s",tokens[1]);
+            snprintf(szTmp,  sizeof(szTmp), "init=epsg:%s",tokens[1]);
             msInitProjection(&sProjTmp);
             if (msLoadProjectionString(&sProjTmp, szTmp) == 0)
               msProjectRect(&sProjTmp, &map->projection,  &sQueryRect);
@@ -898,7 +898,7 @@
             if (nEpsgTmp > 0)
             {
                 char szTmp[32];
-                sprintf(szTmp, "init=epsg:%d",nEpsgTmp);
+                snprintf(szTmp,  sizeof(szTmp), "init=epsg:%d",nEpsgTmp);
                 msInitProjection(&sProjTmp);
                 if (msLoadProjectionString(&sProjTmp, szTmp) == 0)
                   msProjectRect(&sProjTmp, &map->projection,  &sQueryRect);
@@ -2649,9 +2649,9 @@
                             }
                         }
                          if (bString)
-                          sprintf(szTmp, "('[%s]' = '%s')" , pszAttribute, tokens[i]);
+                          snprintf(szTmp,  sizeof(szTmp),"('[%s]' = '%s')" , pszAttribute, tokens[i]);
                         else
-                           sprintf(szTmp, "([%s] = %s)" , pszAttribute, tokens[i]);
+                           snprintf(szTmp,  sizeof(szTmp), "([%s] = %s)" , pszAttribute, tokens[i]);
 
                         if (pszExpression != NULL)
                           pszExpression = msStringConcatenate(pszExpression, " OR ");
@@ -2704,20 +2704,20 @@
             if (FLTIsBinaryComparisonFilterType(psFilterNode->pszValue))
             {
                 pszExpression = 
-                  FLTGetBinaryComparisonSQLExpresssion(psFilterNode);
+                  FLTGetBinaryComparisonSQLExpresssion(psFilterNode, lp);
             }            
             else if (strcasecmp(psFilterNode->pszValue, 
                                 "PropertyIsBetween") == 0)
             {
                  pszExpression = 
-                   FLTGetIsBetweenComparisonSQLExpresssion(psFilterNode);
+                   FLTGetIsBetweenComparisonSQLExpresssion(psFilterNode, lp);
             }
             else if (strcasecmp(psFilterNode->pszValue, 
                                 "PropertyIsLike") == 0)
             {
                  pszExpression = 
-                   FLTGetIsLikeComparisonSQLExpression(psFilterNode,
-                                                       connectiontype);
+                   FLTGetIsLikeComparisonSQLExpression(psFilterNode, lp);
+
             }
         }
     }
@@ -2756,6 +2756,7 @@
                 {
                     for (i=0; i<nTokens; i++)
                     {
+                        char *pszEscapedStr = NULL;
                         if (i == 0)
                         {
                             pszTmp = tokens[0];
@@ -2769,11 +2770,15 @@
                                 }
                             }
                         }
+                        pszEscapedStr = msLayerEscapeSQLParam(lp, tokens[i]);
                         if (bString)
-                          sprintf(szTmp, "(%s = '%s')" , pszAttribute, tokens[i]);
+                          snprintf(szTmp,  sizeof(szTmp), "(%s = '%s')" , pszAttribute, pszEscapedStr);
                         else
-                           sprintf(szTmp, "(%s = %s)" , pszAttribute, tokens[i]);
+                           snprintf(szTmp,  sizeof(szTmp), "(%s = %s)" , pszAttribute, pszEscapedStr);
 
+                        msFree(pszEscapedStr);
+                        pszEscapedStr=NULL;
+
                         if (pszExpression != NULL)
                           pszExpression = msStringConcatenate(pszExpression, " OR ");
                         pszExpression = msStringConcatenate(pszExpression, szTmp);
@@ -3050,6 +3055,7 @@
 /************************************************************************/
 char *FLTGetBinaryComparisonExpresssion(FilterEncodingNode *psFilterNode)
 {
+    const size_t bufferSize = 1024;
     char szBuffer[1024];
     int i=0, bString=0, nLenght = 0;
 
@@ -3084,16 +3090,16 @@
       
 
     if (bString)
-      strcat(szBuffer, " (\"[");
+      strlcat(szBuffer, " (\"[", bufferSize);
     else
-      strcat(szBuffer, " ([");
+      strlcat(szBuffer, " ([", bufferSize);
     /* attribute */
 
-    strcat(szBuffer, psFilterNode->psLeftNode->pszValue);
+    strlcat(szBuffer, psFilterNode->psLeftNode->pszValue, bufferSize);
     if (bString)
-      strcat(szBuffer, "]\" ");
+      strlcat(szBuffer, "]\" ", bufferSize);
     else
-      strcat(szBuffer, "] "); 
+      strlcat(szBuffer, "] ", bufferSize); 
     
 
     /* logical operator */
@@ -3104,40 +3110,40 @@
         if (psFilterNode->psRightNode->pOther && 
             (*(int *)psFilterNode->psRightNode->pOther) == 1)
         {
-            strcat(szBuffer, "IEQ");
+            strlcat(szBuffer, "IEQ", bufferSize);
         }
         else
-          strcat(szBuffer, "=");
+          strlcat(szBuffer, "=", bufferSize);
     }
     else if (strcasecmp(psFilterNode->pszValue, 
                         "PropertyIsNotEqualTo") == 0)
-      strcat(szBuffer, "!="); 
+      strlcat(szBuffer, "!=", bufferSize); 
     else if (strcasecmp(psFilterNode->pszValue, 
                         "PropertyIsLessThan") == 0)
-      strcat(szBuffer, "<");
+      strlcat(szBuffer, "<", bufferSize);
     else if (strcasecmp(psFilterNode->pszValue, 
                         "PropertyIsGreaterThan") == 0)
-      strcat(szBuffer, ">");
+      strlcat(szBuffer, ">", bufferSize);
     else if (strcasecmp(psFilterNode->pszValue, 
                         "PropertyIsLessThanOrEqualTo") == 0)
-      strcat(szBuffer, "<=");
+      strlcat(szBuffer, "<=", bufferSize);
     else if (strcasecmp(psFilterNode->pszValue, 
                         "PropertyIsGreaterThanOrEqualTo") == 0)
-      strcat(szBuffer, ">=");
+      strlcat(szBuffer, ">=", bufferSize);
     
-    strcat(szBuffer, " ");
+    strlcat(szBuffer, " ", bufferSize);
     
     /* value */
     if (bString)
-      strcat(szBuffer, "\"");
+      strlcat(szBuffer, "\"", bufferSize);
     
     if (psFilterNode->psRightNode->pszValue)
-      strcat(szBuffer, psFilterNode->psRightNode->pszValue);
+      strlcat(szBuffer, psFilterNode->psRightNode->pszValue, bufferSize);
 
     if (bString)
-      strcat(szBuffer, "\"");
+      strlcat(szBuffer, "\"", bufferSize);
     
-    strcat(szBuffer, ") ");
+    strlcat(szBuffer, ") ", bufferSize);
 
     return strdup(szBuffer);
 }
@@ -3149,11 +3155,14 @@
 /*                                                                      */
 /*      Return the expression for a binary comparison filter node.      */
 /************************************************************************/
-char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode)
+char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode,
+                                           layerObj *lp)
 {
+    const size_t bufferSize = 1024;
     char szBuffer[1024];
     int i=0, bString=0, nLenght = 0;
     char szTmp[100];
+    char* pszEscapedStr = NULL;
 
     szBuffer[0] = '\0';
     if (!psFilterNode || !
@@ -3187,8 +3196,10 @@
       
 
     /*opening bracket*/
-    strcat(szBuffer, " (");
+    strlcat(szBuffer, " (", bufferSize);
 
+    pszEscapedStr = msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue);
+
     /* attribute */
     /*case insensitive set ? */
     if (bString &&
@@ -3197,35 +3208,37 @@
         psFilterNode->psRightNode->pOther && 
         (*(int *)psFilterNode->psRightNode->pOther) == 1)
     {
-        sprintf(szTmp, "lower(%s) ",  psFilterNode->psLeftNode->pszValue);
-        strcat(szBuffer, szTmp);
+        snprintf(szTmp, sizeof(szTmp), "lower(%s) ",  pszEscapedStr);
+        strlcat(szBuffer, szTmp, bufferSize);
     }
     else
-      strcat(szBuffer, psFilterNode->psLeftNode->pszValue);
+      strlcat(szBuffer, pszEscapedStr, bufferSize);
 
+    msFree(pszEscapedStr);
+    pszEscapedStr = NULL;
     
 
     /* logical operator */
     if (strcasecmp(psFilterNode->pszValue, 
                    "PropertyIsEqualTo") == 0)
-      strcat(szBuffer, "=");
+      strlcat(szBuffer, "=", bufferSize);
     else if (strcasecmp(psFilterNode->pszValue, 
                         "PropertyIsNotEqualTo") == 0)
-      strcat(szBuffer, "<>"); 
+      strlcat(szBuffer, "<>", bufferSize); 
     else if (strcasecmp(psFilterNode->pszValue, 
                         "PropertyIsLessThan") == 0)
-      strcat(szBuffer, "<");
+      strlcat(szBuffer, "<", bufferSize);
     else if (strcasecmp(psFilterNode->pszValue, 
                         "PropertyIsGreaterThan") == 0)
-      strcat(szBuffer, ">");
+      strlcat(szBuffer, ">", bufferSize);
     else if (strcasecmp(psFilterNode->pszValue, 
                         "PropertyIsLessThanOrEqualTo") == 0)
-      strcat(szBuffer, "<=");
+      strlcat(szBuffer, "<=", bufferSize);
     else if (strcasecmp(psFilterNode->pszValue, 
                         "PropertyIsGreaterThanOrEqualTo") == 0)
-      strcat(szBuffer, ">=");
+      strlcat(szBuffer, ">=", bufferSize);
     
-    strcat(szBuffer, " ");
+    strlcat(szBuffer, " ", bufferSize);
     
     /* value */
 
@@ -3236,23 +3249,34 @@
         psFilterNode->psRightNode->pOther && 
         (*(int *)psFilterNode->psRightNode->pOther) == 1)
     {
-        sprintf(szTmp, "lower('%s') ",  psFilterNode->psRightNode->pszValue);
-        strcat(szBuffer, szTmp);
+        snprintf(szTmp,  sizeof(szTmp), "lower('%s') ",  psFilterNode->psRightNode->pszValue);
+        strlcat(szBuffer, szTmp, bufferSize);
     }
     else
     {
         if (bString)
-          strcat(szBuffer, "'");
+          strlcat(szBuffer, "'", bufferSize);
     
         if (psFilterNode->psRightNode->pszValue)
-          strcat(szBuffer, psFilterNode->psRightNode->pszValue);
+        {
+            if (bString)
+            {
+                char* pszEscapedStr;
+                pszEscapedStr = msLayerEscapeSQLParam(lp, psFilterNode->psRightNode->pszValue);
+                strlcat(szBuffer, pszEscapedStr, bufferSize);
+                msFree(pszEscapedStr);
+                pszEscapedStr=NULL;
+            }
+            else
+              strlcat(szBuffer, psFilterNode->psRightNode->pszValue, bufferSize);
+        }
 
         if (bString)
-          strcat(szBuffer, "'");
+          strlcat(szBuffer, "'", bufferSize);
 
     }
     /*closing bracket*/
-    strcat(szBuffer, ") ");
+    strlcat(szBuffer, ") ", bufferSize);
 
     return strdup(szBuffer);
 }
@@ -3263,14 +3287,15 @@
 /*                                                                      */
 /*      Build an SQL expresssion for IsBteween Filter.                  */
 /************************************************************************/
-char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode)
+char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, layerObj *lp)
 {
+     const size_t bufferSize = 1024;
     char szBuffer[1024];
     char **aszBounds = NULL;
     int nBounds = 0;
     int i=0, bString=0, nLenght = 0;
+    char* pszEscapedStr;
 
-
     szBuffer[0] = '\0';
     if (!psFilterNode ||
         !(strcasecmp(psFilterNode->pszValue, "PropertyIsBetween") == 0))
@@ -3323,32 +3348,47 @@
 /*      build expresssion.                                              */
 /* -------------------------------------------------------------------- */
     /*opening paranthesis */
-    strcat(szBuffer, " (");
+    strlcat(szBuffer, " (", bufferSize);
 
     /* attribute */
-    strcat(szBuffer, psFilterNode->psLeftNode->pszValue);
+    pszEscapedStr = msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue);
 
+    strlcat(szBuffer, pszEscapedStr, bufferSize);
+    msFree(pszEscapedStr);
+    pszEscapedStr = NULL;
+
+
     /*between*/
-    strcat(szBuffer, " BETWEEN ");
+    strlcat(szBuffer, " BETWEEN ", bufferSize);
 
     /*bound 1*/
     if (bString)
-      strcat(szBuffer,"'");
-    strcat(szBuffer, aszBounds[0]);
+      strlcat(szBuffer,"'", bufferSize);
+
+    pszEscapedStr = msLayerEscapeSQLParam( lp, aszBounds[0]);
+    strlcat(szBuffer, pszEscapedStr, bufferSize);
+    msFree(pszEscapedStr);
+    pszEscapedStr=NULL;
+
     if (bString)
-      strcat(szBuffer,"'");
+      strlcat(szBuffer,"'", bufferSize);
 
-    strcat(szBuffer, " AND ");
+    strlcat(szBuffer, " AND ", bufferSize);
 
     /*bound 2*/
     if (bString)
-      strcat(szBuffer, "'");
-    strcat(szBuffer, aszBounds[1]);
+      strlcat(szBuffer, "'", bufferSize);
+
+    pszEscapedStr = msLayerEscapeSQLParam( lp, aszBounds[1]);
+    strlcat(szBuffer, pszEscapedStr, bufferSize);
+    msFree(pszEscapedStr);
+    pszEscapedStr=NULL;
+
     if (bString)
-      strcat(szBuffer,"'");
+      strlcat(szBuffer,"'", bufferSize);
 
     /*closing paranthesis*/
-    strcat(szBuffer, ")");
+    strlcat(szBuffer, ")", bufferSize);
      
     
     return strdup(szBuffer);
@@ -3361,6 +3401,7 @@
 /************************************************************************/
 char *FLTGetIsBetweenComparisonExpresssion(FilterEncodingNode *psFilterNode)
 {
+    const size_t bufferSize = 1024;
     char szBuffer[1024];
     char **aszBounds = NULL;
     int nBounds = 0;
@@ -3419,48 +3460,48 @@
 /*      build expresssion.                                              */
 /* -------------------------------------------------------------------- */
     if (bString)
-      strcat(szBuffer, " (\"[");
+      strlcat(szBuffer, " (\"[", bufferSize);
     else
-      strcat(szBuffer, " ([");
+      strlcat(szBuffer, " ([", bufferSize);
 
     /* attribute */
-    strcat(szBuffer, psFilterNode->psLeftNode->pszValue);
+    strlcat(szBuffer, psFilterNode->psLeftNode->pszValue, bufferSize);
 
     if (bString)
-      strcat(szBuffer, "]\" ");
+      strlcat(szBuffer, "]\" ", bufferSize);
     else
-      strcat(szBuffer, "] ");
+      strlcat(szBuffer, "] ", bufferSize);
         
     
-    strcat(szBuffer, " >= ");
+    strlcat(szBuffer, " >= ", bufferSize);
     if (bString)
-      strcat(szBuffer,"\"");
-    strcat(szBuffer, aszBounds[0]);
+      strlcat(szBuffer,"\"", bufferSize);
+    strlcat(szBuffer, aszBounds[0], bufferSize);
     if (bString)
-      strcat(szBuffer,"\"");
+      strlcat(szBuffer,"\"", bufferSize);
 
-    strcat(szBuffer, " AND ");
+    strlcat(szBuffer, " AND ", bufferSize);
 
     if (bString)
-      strcat(szBuffer, " \"[");
+      strlcat(szBuffer, " \"[", bufferSize);
     else
-      strcat(szBuffer, " ["); 
+      strlcat(szBuffer, " [", bufferSize); 
 
     /* attribute */
-    strcat(szBuffer, psFilterNode->psLeftNode->pszValue);
+    strlcat(szBuffer, psFilterNode->psLeftNode->pszValue, bufferSize);
     
     if (bString)
-      strcat(szBuffer, "]\" ");
+      strlcat(szBuffer, "]\" ", bufferSize);
     else
-      strcat(szBuffer, "] ");
+      strlcat(szBuffer, "] ", bufferSize);
     
-    strcat(szBuffer, " <= ");
+    strlcat(szBuffer, " <= ", bufferSize);
     if (bString)
-      strcat(szBuffer,"\"");
-    strcat(szBuffer, aszBounds[1]);
+      strlcat(szBuffer,"\"", bufferSize);
+    strlcat(szBuffer, aszBounds[1], bufferSize);
     if (bString)
-      strcat(szBuffer,"\"");
-    strcat(szBuffer, ")");
+      strlcat(szBuffer,"\"", bufferSize);
+    strlcat(szBuffer, ")", bufferSize);
      
     
     return strdup(szBuffer);
@@ -3473,6 +3514,7 @@
 /************************************************************************/
 char *FLTGetIsLikeComparisonExpression(FilterEncodingNode *psFilterNode)
 {
+    const size_t bufferSize = 1024;
     char szBuffer[1024];
     char *pszValue = NULL;
     
@@ -3520,43 +3562,48 @@
     }
     for (i=0; i<nLength; i++)
     {
-        if (pszValue[i] != pszWild[0] && 
-            pszValue[i] != pszSingle[0] &&
-            pszValue[i] != pszEscape[0])
-        {
-            szBuffer[iBuffer] = pszValue[i];
-            iBuffer++;
-            szBuffer[iBuffer] = '\0';
-        }
-        else if  (pszValue[i] == pszSingle[0])
-        {
-             szBuffer[iBuffer] = '.';
-             iBuffer++;
-             szBuffer[iBuffer] = '\0';
-        }
-        else if  (pszValue[i] == pszEscape[0])
-        {
-            szBuffer[iBuffer] = '\\';
-            iBuffer++;
-            szBuffer[iBuffer] = '\0';
+        if (iBuffer < 1024)
+        {     
+            if (pszValue[i] != pszWild[0] && 
+                pszValue[i] != pszSingle[0] &&
+                pszValue[i] != pszEscape[0])
+            {
+                szBuffer[iBuffer] = pszValue[i];
+                iBuffer++;
+                szBuffer[iBuffer] = '\0';
+            }
+            else if  (pszValue[i] == pszSingle[0])
+            {
+                szBuffer[iBuffer] = '.';
+                iBuffer++;
+                szBuffer[iBuffer] = '\0';
+            }
+            else if  (pszValue[i] == pszEscape[0])
+            {
+                szBuffer[iBuffer] = '\\';
+                iBuffer++;
+                szBuffer[iBuffer] = '\0';
 
+            }
+            else if (pszValue[i] == pszWild[0])
+            {
+                /* strcat(szBuffer, "[0-9,a-z,A-Z,\\s]*"); */
+                /* iBuffer+=17; */
+                strlcat(szBuffer, ".*", bufferSize);
+                iBuffer+=2;
+                szBuffer[iBuffer] = '\0';
+            }
         }
-        else if (pszValue[i] == pszWild[0])
+    }  
+    if (iBuffer < 1024)
+    {
+        szBuffer[iBuffer] = '/';
+        if (bCaseInsensitive == 1)
         {
-            /* strcat(szBuffer, "[0-9,a-z,A-Z,\\s]*"); */
-            /* iBuffer+=17; */
-            strcat(szBuffer, ".*");
-            iBuffer+=2;
-            szBuffer[iBuffer] = '\0';
-        }
-    }   
-    szBuffer[iBuffer] = '/';
-    if (bCaseInsensitive == 1)
-    {
-      szBuffer[++iBuffer] = 'i';
-    } 
-    szBuffer[++iBuffer] = '\0';
-    
+            szBuffer[++iBuffer] = 'i';
+        } 
+        szBuffer[++iBuffer] = '\0';
+    }
         
     return strdup(szBuffer);
 }
@@ -3566,9 +3613,9 @@
 /*                                                                      */
 /*      Build an sql expression for IsLike filter.                      */
 /************************************************************************/
-char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode,
-                                          int connectiontype)
+char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode, layerObj *lp)
 {
+    const size_t bufferSize = 1024;
     char szBuffer[1024];
     char *pszValue = NULL;
     
@@ -3577,9 +3624,11 @@
     char *pszEscape = NULL;
     char szTmp[3];
 
-    int nLength=0, i=0, iBuffer = 0;
+    int nLength=0, i=0, j=0;
     int  bCaseInsensitive = 0;
 
+    char *pszEscapedStr = NULL;
+
     if (!psFilterNode || !psFilterNode->pOther || !psFilterNode->psLeftNode ||
         !psFilterNode->psRightNode || !psFilterNode->psRightNode->pszValue)
       return NULL;
@@ -3598,60 +3647,78 @@
 
     szBuffer[0] = '\0';
     /*opening bracket*/
-    strcat(szBuffer, " (");
+    strlcat(szBuffer, " (", bufferSize);
 
     /* attribute name */
-    strcat(szBuffer, psFilterNode->psLeftNode->pszValue);
-    if (bCaseInsensitive == 1 && connectiontype == MS_POSTGIS)
-      strcat(szBuffer, " ilike '");
+    pszEscapedStr = msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue);
+
+    strlcat(szBuffer, pszEscapedStr, bufferSize);
+    msFree(pszEscapedStr);
+    pszEscapedStr = NULL;
+
+    if (bCaseInsensitive == 1 && lp->connectiontype == MS_POSTGIS)
+      strlcat(szBuffer, " ilike '", bufferSize);
     else
-      strcat(szBuffer, " like '");
+      strlcat(szBuffer, " like '", bufferSize);
         
    
     pszValue = psFilterNode->psRightNode->pszValue;
     nLength = strlen(pszValue);
-    iBuffer = strlen(szBuffer);
+
+    pszEscapedStr = (char*) malloc( 3 * nLength + 1);
     for (i=0; i<nLength; i++)
     {
-        if (pszValue[i] != pszWild[0] && 
-            pszValue[i] != pszSingle[0] &&
-            pszValue[i] != pszEscape[0])
+        char c = pszValue[i];
+        if (c != pszWild[0] &&
+            c != pszSingle[0] &&
+            c != pszEscape[0])
         {
-            szBuffer[iBuffer] = pszValue[i];
-            iBuffer++;
-            szBuffer[iBuffer] = '\0';
+            if (c == '\'')
+            {
+                pszEscapedStr[j++] = '\'';
+                pszEscapedStr[j++] = '\'';
+            }
+            else if (c == '\\')
+            {
+                pszEscapedStr[j++] = '\\';
+                pszEscapedStr[j++] = '\\';
+            }
+            else
+                pszEscapedStr[j++] = c;
         }
-        else if  (pszValue[i] == pszSingle[0])
+        else if  (c == pszSingle[0])
         {
-             szBuffer[iBuffer] = '_';
-             iBuffer++;
-             szBuffer[iBuffer] = '\0';
+            pszEscapedStr[j++] = '_';
         }
-        else if  (pszValue[i] == pszEscape[0])
+        else if  (c == pszEscape[0])
         {
-            szBuffer[iBuffer] = pszEscape[0];
-            iBuffer++;
-            szBuffer[iBuffer] = '\0';
-            /*if (i<nLength-1)
+            pszEscapedStr[j++] = pszEscape[0];
+            if (i+1<nLength)
             {
-                szBuffer[iBuffer] = pszValue[i+1];
-                iBuffer++;
-                szBuffer[iBuffer] = '\0';
+                char nextC = pszValue[i+1];
+                i++;
+                if (nextC == '\'')
+                {
+                    pszEscapedStr[j++] = '\'';
+                    pszEscapedStr[j++] = '\'';
+                }
+                else
+                    pszEscapedStr[j++] = nextC;
             }
-            */
         }
-        else if (pszValue[i] == pszWild[0])
+        else if (c == pszWild[0])
         {
-            strcat(szBuffer, "%");
-            iBuffer++;
-            szBuffer[iBuffer] = '\0';
+            pszEscapedStr[j++] = '%';
         }
     } 
+    pszEscapedStr[j++] = 0;
+    strlcat(szBuffer, pszEscapedStr, bufferSize);
+    msFree(pszEscapedStr);
 
-    strcat(szBuffer, "'");
-    if (connectiontype != MS_OGR)
+    strlcat(szBuffer, "'", bufferSize);
+    if (lp->connectiontype != MS_OGR)
     {
-      strcat(szBuffer, " escape '");
+      strlcat(szBuffer, " escape '", bufferSize);
       szTmp[0] = pszEscape[0];
       if (pszEscape[0] == '\\')
       {
@@ -3665,9 +3732,9 @@
           szTmp[2] = '\0';
       }
 
-      strcat(szBuffer,  szTmp);
+      strlcat(szBuffer,  szTmp, bufferSize);
     }
-    strcat(szBuffer,  ") ");
+    strlcat(szBuffer,  ") ", bufferSize);
     
     return strdup(szBuffer);
 }

Modified: branches/branch-5-0/mapserver/mapogcfilter.h
===================================================================
--- branches/branch-5-0/mapserver/mapogcfilter.h	2011-07-12 13:13:38 UTC (rev 11893)
+++ branches/branch-5-0/mapserver/mapogcfilter.h	2011-07-12 13:15:06 UTC (rev 11894)
@@ -111,10 +111,10 @@
                           int iLayerIndex);
 
 MS_DLL_EXPORT char *FLTGetSQLExpression(FilterEncodingNode *psFilterNode,layerObj *lp);
-MS_DLL_EXPORT char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode);
-MS_DLL_EXPORT char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode);
-MS_DLL_EXPORT char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode,
-                                       int connectiontype);
+MS_DLL_EXPORT char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode,  layerObj *lp);
+MS_DLL_EXPORT char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, layerObj *lp);
+MS_DLL_EXPORT char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode, layerObj *lp);
+
 MS_DLL_EXPORT char *FLTGetLogicalComparisonSQLExpresssion(FilterEncodingNode *psFilterNode,
                                             layerObj *lp);
 MS_DLL_EXPORT int FLTIsSimpleFilter(FilterEncodingNode *psFilterNode);

Modified: branches/branch-5-0/mapserver/mapogcsos.c
===================================================================
--- branches/branch-5-0/mapserver/mapogcsos.c	2011-07-12 13:13:38 UTC (rev 11893)
+++ branches/branch-5-0/mapserver/mapogcsos.c	2011-07-12 13:15:06 UTC (rev 11894)
@@ -1504,6 +1504,7 @@
     xmlChar *buffer = NULL;
     int size = 0;
     msIOContext *context = NULL;
+    char* pszEscapedStr = NULL;
 
     sBbox = map->extent;
 
@@ -1726,12 +1727,20 @@
                             
                             if (!bSpatialDB)
                               pszBuffer = msStringConcatenate(pszBuffer, "'[");
-                            pszBuffer = msStringConcatenate(pszBuffer, (char *)pszProcedureItem);
+                            pszEscapedStr = msLayerEscapePropertyName(lp, (char *)pszProcedureItem);
+                            pszBuffer = msStringConcatenate(pszBuffer, pszEscapedStr);
+                            msFree(pszEscapedStr);
+                            pszEscapedStr = NULL;
+
                             if (!bSpatialDB)
                               pszBuffer = msStringConcatenate(pszBuffer, "]'");
                                     
                             pszBuffer = msStringConcatenate(pszBuffer, " = '");
-                            pszBuffer = msStringConcatenate(pszBuffer,  tokens[j]);
+                            pszEscapedStr = msLayerEscapeSQLParam(lp, tokens[j]);
+                            pszBuffer = msStringConcatenate(pszBuffer,  pszEscapedStr);
+                            msFree(pszEscapedStr);
+                            pszEscapedStr=NULL;
+
                             pszBuffer = msStringConcatenate(pszBuffer,  "')");
                         }
                                 

Modified: branches/branch-5-0/mapserver/mapogr.cpp
===================================================================
--- branches/branch-5-0/mapserver/mapogr.cpp	2011-07-12 13:13:38 UTC (rev 11893)
+++ branches/branch-5-0/mapserver/mapogr.cpp	2011-07-12 13:15:06 UTC (rev 11894)
@@ -2376,6 +2376,66 @@
 }
 
 /************************************************************************/
+/*                           msOGREscapeSQLParam                        */
+/************************************************************************/
+char *msOGREscapeSQLParam(layerObj *layer, const char *pszString)
+{
+    char* pszEscapedStr =NULL;
+#ifdef USE_OGR
+    if(layer && pszString && strlen(pszString) > 0)
+    {
+        char* pszEscapedOGRStr =  CPLEscapeString(pszString, strlen(pszString),  
+		                                    CPLES_SQL ); 
+	pszEscapedStr = strdup(pszEscapedOGRStr);
+        CPLFree(pszEscapedOGRStr);
+	return pszEscapedStr; 
+    }
+#else
+/* ------------------------------------------------------------------
+ * OGR Support not included...
+ * ------------------------------------------------------------------ */
+
+  msSetError(MS_MISCERR, "OGR support is not available.", 
+             "msOGREscapeSQLParam()");
+  return NULL;
+
+#endif /* USE_OGR */  
+}
+
+
+/************************************************************************/
+/*                           msOGREscapeSQLParam                        */
+/************************************************************************/
+char *msOGREscapePropertyName(layerObj *layer, const char *pszString)
+{
+    char* pszEscapedStr =NULL;
+    int i =0;
+#ifdef USE_OGR
+    if(layer && pszString && strlen(pszString) > 0)
+    {
+        unsigned char ch;
+        for(i=0; (ch = ((unsigned char*)pszString)[i]) != '\0'; i++)
+        {
+            if ( !(isalnum(ch) || ch == '_' || ch > 127) )
+            {
+                return strdup("invalid_property_name");
+            }
+        }
+        pszEscapedStr = strdup(pszString);
+    }
+    return pszEscapedStr;
+#else
+/* ------------------------------------------------------------------
+ * OGR Support not included...
+ * ------------------------------------------------------------------ */
+
+  msSetError(MS_MISCERR, "OGR support is not available.", 
+             "msOGREscapePropertyName()");
+  return NULL;
+
+#endif /* USE_OGR */  
+}
+/************************************************************************/
 /*                  msOGRLayerInitializeVirtualTable()                  */
 /************************************************************************/
 int
@@ -2406,6 +2466,9 @@
     /* layer->vtable->LayerGetNumFeatures, use default */
 
 
+    layer->vtable->LayerEscapeSQLParam = msOGREscapeSQLParam;
+    layer->vtable->LayerEscapePropertyName = msOGREscapePropertyName;
+
     return MS_SUCCESS;
 }
 

Modified: branches/branch-5-0/mapserver/mappostgis.c
===================================================================
--- branches/branch-5-0/mapserver/mappostgis.c	2011-07-12 13:13:38 UTC (rev 11893)
+++ branches/branch-5-0/mapserver/mappostgis.c	2011-07-12 13:15:06 UTC (rev 11894)
@@ -556,7 +556,7 @@
     if(layer->debug) {
         msDebug("query_string_0_6:%s\n", query_string_0_6);
     }
-    result = PQexec(layerinfo->conn, query_string_0_6);
+    result = PQexecParams(layerinfo->conn, query_string_0_6,0, NULL, NULL, NULL, NULL, 0);
 
     if(!result || PQresultStatus(result) != PGRES_COMMAND_OK)
     {
@@ -1239,7 +1239,7 @@
     free(geom_column_name);
     free(table_name);
 
-    query_result = PQexec(layerinfo->conn, query_str);
+    query_result = PQexecParams(layerinfo->conn, query_str,0, NULL, NULL, NULL, NULL, 0);
 
     if(!query_result || PQresultStatus(query_result) != PGRES_COMMAND_OK) {
         msSetError(MS_QUERYERR, "Error executing POSTGIS SQL statement (in FETCH ALL): %s\n-%s\nMore Help:", "msPOSTGISLayerGetShape()", query_str, PQerrorMessage(layerinfo->conn));
@@ -1431,7 +1431,7 @@
     /* geom_column_name is needed later */
     free(table_name);
 
-    query_result = PQexec(layerinfo->conn, sql);
+    query_result = PQexecParams(layerinfo->conn, sql,0, NULL, NULL, NULL, NULL, 0);
 
     if(!query_result || PQresultStatus(query_result) != PGRES_TUPLES_OK) {
         msSetError(MS_QUERYERR, "Error executing POSTGIS SQL statement (in msPOSTGISLayerGetItems): %s\n-%s\n", "msPOSTGISLayerGetItems()", sql, PQerrorMessage(layerinfo->conn));

Modified: branches/branch-5-0/mapserver/mapserver.h
===================================================================
--- branches/branch-5-0/mapserver/mapserver.h	2011-07-12 13:13:38 UTC (rev 11893)
+++ branches/branch-5-0/mapserver/mapserver.h	2011-07-12 13:15:06 UTC (rev 11894)
@@ -1280,6 +1280,8 @@
 
     int (*LayerCreateItems)(layerObj *layer, int nt);
     int (*LayerGetNumFeatures)(layerObj *layer);
+    char* (*LayerEscapeSQLParam)(layerObj *layer, const char* pszString);
+    char* (*LayerEscapePropertyName)(layerObj *layer, const char* pszString);
 };
 #endif /*SWIG*/
 
@@ -1631,6 +1633,9 @@
 /* maplayer.c */
 MS_DLL_EXPORT int msLayerGetNumFeatures(layerObj *layer);
 
+MS_DLL_EXPORT char *msLayerEscapeSQLParam(layerObj *layer, const char* pszString);
+MS_DLL_EXPORT char *msLayerEscapePropertyName(layerObj *layer, const char* pszString);
+
 /* These are special because SWF is using these */
 int msOGRLayerNextShape(layerObj *layer, shapeObj *shape);
 int msOGRLayerGetItems(layerObj *layer);



More information about the mapserver-commits mailing list