[mapserver-commits] r11898 - trunk/mapserver

svn at osgeo.org svn at osgeo.org
Tue Jul 12 09:24:51 EDT 2011


Author: assefa
Date: 2011-07-12 06:24:51 -0700 (Tue, 12 Jul 2011)
New Revision: 11898

Modified:
   trunk/mapserver/HISTORY.TXT
   trunk/mapserver/maplayer.c
   trunk/mapserver/mapogcfilter.c
   trunk/mapserver/mapogcfilter.h
   trunk/mapserver/mapogcsos.c
   trunk/mapserver/mapogr.cpp
   trunk/mapserver/mappostgis.c
   trunk/mapserver/mapserver.h
Log:
Security fixes (#3903)

Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT	2011-07-12 13:19:08 UTC (rev 11897)
+++ trunk/mapserver/HISTORY.TXT	2011-07-12 13:24:51 UTC (rev 11898)
@@ -14,6 +14,15 @@
 
 Current Version (SVN trunk, 6.1-dev, future 6.2): 
 -------------------------------------------------
+
+IMPORTANT SECURITY FIX:
+
+-  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)
+
 - Fix performance issue with Oracle and scrollable cursors (#3905)
 
 - Fix attribute binding for layer styles (#3941)

Modified: trunk/mapserver/maplayer.c
===================================================================
--- trunk/mapserver/maplayer.c	2011-07-12 13:19:08 UTC (rev 11897)
+++ trunk/mapserver/maplayer.c	2011-07-12 13:24:51 UTC (rev 11898)
@@ -1237,6 +1237,85 @@
   return MS_FALSE;
 }
 
+/************************************************************************/
+/*                          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*) msSmallMalloc( 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*) msSmallMalloc( 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
  *
@@ -1297,6 +1376,10 @@
   
   vtable->LayerGetAutoProjection = LayerDefaultAutoProjection;
 
+  vtable->LayerEscapeSQLParam = LayerDefaultEscapeSQLParam;
+
+  vtable->LayerEscapePropertyName = LayerDefaultEscapePropertyName;
+
   return MS_SUCCESS;
 }
 
@@ -1468,6 +1551,32 @@
     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)
 {
@@ -1499,6 +1608,8 @@
     /* layer->vtable->LayerCreateItems, use default */
     layer->vtable->LayerGetNumFeatures = msINLINELayerGetNumFeatures;
 
+    /*layer->vtable->LayerEscapeSQLParam, use default*/
+    /*layer->vtable->LayerEscapePropertyName, use default*/
     return MS_SUCCESS;
 }
 

Modified: trunk/mapserver/mapogcfilter.c
===================================================================
--- trunk/mapserver/mapogcfilter.c	2011-07-12 13:19:08 UTC (rev 11897)
+++ trunk/mapserver/mapogcfilter.c	2011-07-12 13:24:51 UTC (rev 11898)
@@ -265,6 +265,8 @@
 }
 
 
+
+
 /************************************************************************/
 /*                        FLTIsSimpleFilterNoSpatial                    */
 /*                                                                      */
@@ -2027,7 +2029,6 @@
     char szTmp[256];
     char **tokens = NULL;
     int nTokens = 0, i=0, bString=0;
-    char *pszTmp;
 
     if (psFilterNode == NULL || lp == NULL)
       return NULL;
@@ -2052,8 +2053,8 @@
                                 "PropertyIsLike") == 0)
             {
                  pszExpression = 
-                   FLTGetIsLikeComparisonSQLExpression(psFilterNode,
-                                                       connectiontype);
+                   FLTGetIsLikeComparisonSQLExpression(psFilterNode, lp);
+
             }
         }
     }
@@ -2092,17 +2093,22 @@
                 {
                     for (i=0; i<nTokens; i++)
                     {
-                        if (i == 0)
-                        {
-                            pszTmp = tokens[0];
-                            if (FLTIsNumeric(pszTmp) == MS_FALSE)    
-                               bString = 1;
-                        }
+                        char *pszEscapedStr = NULL;
+                        if (strlen(tokens[i]) <= 0)
+                          continue;
+
+                        if (FLTIsNumeric((tokens[i])) == MS_FALSE)    
+                          bString = 1;
+
+                        pszEscapedStr = msLayerEscapeSQLParam(lp, tokens[i]);
                         if (bString)
-                            snprintf(szTmp, sizeof(szTmp), "(%s = '%s')" , pszAttribute, tokens[i]);
+                            snprintf(szTmp, sizeof(szTmp), "(%s = '%s')" , pszAttribute, pszEscapedStr);
                         else
-                            snprintf(szTmp, sizeof(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 ");
                         else
@@ -2466,6 +2472,7 @@
 
 
 
+
 /************************************************************************/
 /*                      FLTGetBinaryComparisonSQLExpresssion            */
 /*                                                                      */
@@ -2478,6 +2485,7 @@
     char szBuffer[1024];
     int bString=0;
     char szTmp[256];
+    char* pszEscapedStr = NULL;
 
     szBuffer[0] = '\0';
     if (!psFilterNode || !
@@ -2507,13 +2515,11 @@
       
 
     /*opening bracket*/
-    /*for postgis layers double quote the attribute name, allowing reserved names to
- *       be used as attribute name #3311*/
-    if (lp->connectiontype == MS_POSTGIS)
-      strlcat(szBuffer, " (\"", bufferSize);
-    else
-      strlcat(szBuffer, " (", bufferSize);
+    strlcat(szBuffer, " (", bufferSize);
 
+    pszEscapedStr = msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue);
+
+
     /* attribute */
     /*case insensitive set ? */
     if (bString &&
@@ -2522,14 +2528,14 @@
         psFilterNode->psRightNode->pOther && 
         (*(int *)psFilterNode->psRightNode->pOther) == 1)
     {
-        snprintf(szTmp, sizeof(szTmp), "lower(%s) ",  psFilterNode->psLeftNode->pszValue);
+        snprintf(szTmp, sizeof(szTmp), "lower(%s) ",  pszEscapedStr);
         strlcat(szBuffer, szTmp, bufferSize);
     }
     else
-      strlcat(szBuffer, psFilterNode->psLeftNode->pszValue, bufferSize);
+      strlcat(szBuffer, pszEscapedStr, bufferSize);
 
-    if (lp->connectiontype == MS_POSTGIS)
-     strlcat(szBuffer, "\"", bufferSize);
+    msFree(pszEscapedStr);
+    pszEscapedStr = NULL;
 
 
     /* logical operator */
@@ -2572,7 +2578,18 @@
           strlcat(szBuffer, "'", bufferSize);
     
         if (psFilterNode->psRightNode->pszValue)
-          strlcat(szBuffer, psFilterNode->psRightNode->pszValue, bufferSize);
+        {
+            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)
           strlcat(szBuffer, "'", bufferSize);
@@ -2599,8 +2616,8 @@
     int nBounds = 0;
     int bString=0;
     char szTmp[256];
+    char* pszEscapedStr;
 
-
     szBuffer[0] = '\0';
     if (!psFilterNode ||
         !(strcasecmp(psFilterNode->pszValue, "PropertyIsBetween") == 0))
@@ -2647,15 +2664,23 @@
     strlcat(szBuffer, " (", bufferSize);
 
     /* attribute */
-    strlcat(szBuffer, psFilterNode->psLeftNode->pszValue, bufferSize);
+    pszEscapedStr = msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue);
 
+    strlcat(szBuffer, pszEscapedStr, bufferSize);
+    msFree(pszEscapedStr);
+    pszEscapedStr = NULL;
+
     /*between*/
     strlcat(szBuffer, " BETWEEN ", bufferSize);
 
     /*bound 1*/
     if (bString)
       strlcat(szBuffer,"'", bufferSize);
-    strlcat(szBuffer, aszBounds[0], bufferSize);
+    pszEscapedStr = msLayerEscapeSQLParam( lp, aszBounds[0]);
+    strlcat(szBuffer, pszEscapedStr, bufferSize);
+    msFree(pszEscapedStr);
+    pszEscapedStr=NULL;
+
     if (bString)
       strlcat(szBuffer,"'", bufferSize);
 
@@ -2664,7 +2689,11 @@
     /*bound 2*/
     if (bString)
       strlcat(szBuffer, "'", bufferSize);
-    strlcat(szBuffer, aszBounds[1], bufferSize);
+    pszEscapedStr = msLayerEscapeSQLParam( lp, aszBounds[1]);
+    strlcat(szBuffer, pszEscapedStr, bufferSize);
+    msFree(pszEscapedStr);
+    pszEscapedStr=NULL;
+
     if (bString)
       strlcat(szBuffer,"'", bufferSize);
 
@@ -2900,7 +2929,7 @@
 /*      Build an sql expression for IsLike filter.                      */
 /************************************************************************/
 char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode,
-                                          int connectiontype)
+                                          layerObj *lp)
 {
     const size_t bufferSize = 1024;
     char szBuffer[1024];
@@ -2911,9 +2940,11 @@
     char *pszEscape = NULL;
     char szTmp[4];
 
-    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;
@@ -2928,15 +2959,29 @@
         !pszEscape || strlen(pszEscape) == 0)
       return NULL;
 
- 
+    if (pszEscape[0] == '\'')
+    {
+        /* This might be valid, but the risk of SQL injection is too high */
+        /* and the below code is not ready for that */
+        /* Someone who does this has clearly suspect intentions ! */
+        msSetError(MS_MISCERR, "Single quote character is not allowed as an escaping character.",
+                   "FLTGetIsLikeComparisonSQLExpression()");
+        return NULL;
+    }
 
+
     szBuffer[0] = '\0';
     /*opening bracket*/
     strlcat(szBuffer, " (", bufferSize);
 
     /* attribute name */
-    strlcat(szBuffer, psFilterNode->psLeftNode->pszValue, bufferSize);
-    if (bCaseInsensitive == 1 && connectiontype == MS_POSTGIS)
+    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
       strlcat(szBuffer, " like '", bufferSize);
@@ -2944,46 +2989,60 @@
    
     pszValue = psFilterNode->psRightNode->pszValue;
     nLength = strlen(pszValue);
-    iBuffer = strlen(szBuffer);
-    for (i=0; i<nLength; i++)
+
+    pszEscapedStr = (char*) msSmallMalloc( 3 * nLength + 1);
+
+    for (i=0, j=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])
         {
-            strlcat(szBuffer, "%", bufferSize);
-            iBuffer++;
-            szBuffer[iBuffer] = '\0';
+            pszEscapedStr[j++] = '%';
         }
-    } 
+    }
+    pszEscapedStr[j++] = 0;
+    strlcat(szBuffer, pszEscapedStr, bufferSize);
+    msFree(pszEscapedStr);
 
     strlcat(szBuffer, "'", bufferSize);
-    if (connectiontype != MS_OGR)
+    if (lp->connectiontype != MS_OGR)
     {
       strlcat(szBuffer, " escape '", bufferSize);
       szTmp[0] = pszEscape[0];

Modified: trunk/mapserver/mapogcfilter.h
===================================================================
--- trunk/mapserver/mapogcfilter.h	2011-07-12 13:19:08 UTC (rev 11897)
+++ trunk/mapserver/mapogcfilter.h	2011-07-12 13:24:51 UTC (rev 11898)
@@ -109,8 +109,8 @@
 MS_DLL_EXPORT char *FLTGetSQLExpression(FilterEncodingNode *psFilterNode,layerObj *lp);
 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,
-                                       int connectiontype);
+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: trunk/mapserver/mapogcsos.c
===================================================================
--- trunk/mapserver/mapogcsos.c	2011-07-12 13:19:08 UTC (rev 11897)
+++ trunk/mapserver/mapogcsos.c	2011-07-12 13:24:51 UTC (rev 11898)
@@ -1843,6 +1843,7 @@
   char *pszProcedureValue = NULL;
   int iItemPosition, status;
   shapeObj sShape;
+  char* pszEscapedStr = NULL;
 
   sBbox = map->extent;
 
@@ -2075,15 +2076,25 @@
               pszBuffer = msStringConcatenate(pszBuffer, "(");
                             
               if (!bSpatialDB)
-                pszBuffer = msStringConcatenate(pszBuffer, "'[");
+              {
+                  pszBuffer = msStringConcatenate(pszBuffer, "'[");
+                  pszBuffer = msStringConcatenate(pszBuffer, (char *)pszProcedureItem);
+              }
+              else
+              {
+                  pszEscapedStr = msLayerEscapePropertyName(lp, (char *)pszProcedureItem);
+                  pszBuffer = msStringConcatenate(pszBuffer, pszEscapedStr);
+                  msFree(pszEscapedStr);
+                  pszEscapedStr = NULL;
+              }
 
-              pszBuffer = msStringConcatenate(pszBuffer, (char *)pszProcedureItem);
-
               if (!bSpatialDB)
                 pszBuffer = msStringConcatenate(pszBuffer, "]'");
 
               pszBuffer = msStringConcatenate(pszBuffer, " = '");
-              pszBuffer = msStringConcatenate(pszBuffer,  tokens[j]);
+              pszEscapedStr = msLayerEscapeSQLParam(lp, tokens[j]);
+              pszBuffer = msStringConcatenate(pszBuffer,  pszEscapedStr);
+              msFree(pszEscapedStr);
               pszBuffer = msStringConcatenate(pszBuffer,  "')");
             }
                                 

Modified: trunk/mapserver/mapogr.cpp
===================================================================
--- trunk/mapserver/mapogr.cpp	2011-07-12 13:19:08 UTC (rev 11897)
+++ trunk/mapserver/mapogr.cpp	2011-07-12 13:24:51 UTC (rev 11898)
@@ -3712,6 +3712,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 = msStrdup(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 msStrdup("invalid_property_name");
+            }
+        }
+        pszEscapedStr = msStrdup(pszString);
+    }
+    return pszEscapedStr;
+#else
+/* ------------------------------------------------------------------
+ * OGR Support not included...
+ * ------------------------------------------------------------------ */
+
+  msSetError(MS_MISCERR, "OGR support is not available.", 
+             "msOGREscapePropertyName()");
+  return NULL;
+
+#endif /* USE_OGR */  
+}
+/************************************************************************/
 /*                  msOGRLayerInitializeVirtualTable()                  */
 /************************************************************************/
 int
@@ -3738,6 +3798,9 @@
     /* layer->vtable->LayerGetNumFeatures, use default */
     /* layer->vtable->LayerGetAutoProjection, use defaut*/
 
+    layer->vtable->LayerEscapeSQLParam = msOGREscapeSQLParam;
+    layer->vtable->LayerEscapePropertyName = msOGREscapePropertyName;
+
     return MS_SUCCESS;
 }
 

Modified: trunk/mapserver/mappostgis.c
===================================================================
--- trunk/mapserver/mappostgis.c	2011-07-12 13:19:08 UTC (rev 11897)
+++ trunk/mapserver/mappostgis.c	2011-07-12 13:24:51 UTC (rev 11898)
@@ -1020,7 +1020,7 @@
         return MS_FAILURE; 
     } 
 
-    pgresult = PQexec(pgconn, sql);
+    pgresult = PQexecParams(pgconn, sql,0, NULL, NULL, NULL, NULL, 0);
 
     if ( !pgresult || PQresultStatus(pgresult) != PGRES_TUPLES_OK) {
         msSetError(MS_QUERYERR, "Error executing SQL: %s", "msPostGISRetrieveVersion()", sql);
@@ -1160,7 +1160,7 @@
         return MS_FAILURE;
     }
 
-    pgresult = PQexec(layerinfo->pgconn, sql);
+    pgresult = PQexecParams(layerinfo->pgconn, sql, 0, NULL, NULL, NULL, NULL, 0);
     if ( !pgresult || PQresultStatus(pgresult) != PGRES_TUPLES_OK) {
         static char *tmp1 = "Error executing SQL: ";
         char *tmp2 = NULL;
@@ -2451,7 +2451,7 @@
     if(num_bind_values > 0) {
         pgresult = PQexecParams(layerinfo->pgconn, strSQL, num_bind_values, NULL, (const char**)layer_bind_values, NULL, NULL, 1);
     } else {
-        pgresult = PQexec(layerinfo->pgconn, strSQL);
+      pgresult = PQexecParams(layerinfo->pgconn, strSQL,0, NULL, NULL, NULL, NULL, 0);
     }
 
     /* free bind values */
@@ -2641,7 +2641,7 @@
             msDebug("msPostGISLayerGetShape query: %s\n", strSQL);
         }
 
-        pgresult = PQexec(layerinfo->pgconn, strSQL);
+        pgresult = PQexecParams(layerinfo->pgconn, strSQL,0, NULL, NULL, NULL, NULL, 0);
 
         /* Something went wrong. */
         if ( (!pgresult) || (PQresultStatus(pgresult) != PGRES_TUPLES_OK) ) {
@@ -2865,7 +2865,7 @@
         msDebug("msPostGISLayerGetItems executing SQL: %s\n", sql);
     }
 
-    pgresult = PQexec(layerinfo->pgconn, sql);
+    pgresult = PQexecParams(layerinfo->pgconn, sql,0, NULL, NULL, NULL, NULL, 0);
     
     if ( (!pgresult) || (PQresultStatus(pgresult) != PGRES_TUPLES_OK) ) {
         msSetError(MS_QUERYERR, "Error (%s) executing SQL: %s", "msPostGISLayerGetItems()", PQerrorMessage(layerinfo->pgconn), sql);
@@ -3298,6 +3298,34 @@
     return MS_FALSE;
 }
 
+char *msPostGISEscapeSQLParam(layerObj *layer, char *pszString)
+{
+    msPostGISLayerInfo *layerinfo = NULL;
+    int nError;
+    size_t nSrcLen;
+    char* pszEscapedStr =NULL;
+
+    if (layer && pszString && strlen(pszString) > 0)
+    {
+        if(!msPostGISLayerIsOpen(layer))
+          msPostGISLayerOpen(layer);
+    
+        assert(layer->layerinfo != NULL);
+
+        layerinfo = (msPostGISLayerInfo *) layer->layerinfo;
+        nSrcLen = strlen(pszString);
+        pszEscapedStr = (char*) msSmallMalloc( 2 * nSrcLen + 1);
+        PQescapeStringConn (layerinfo->pgconn, pszEscapedStr, pszString, nSrcLen, &nError);
+        if (nError != 0)
+        {
+            free(pszEscapedStr);
+            pszEscapedStr = NULL;
+        }
+    }
+    return pszEscapedStr;
+}
+
+
 int msPostGISLayerInitializeVirtualTable(layerObj *layer) {
     assert(layer != NULL);
     assert(layer->vtable != NULL);
@@ -3319,7 +3347,9 @@
     /* layer->vtable->LayerCreateItems, use default */
     /* layer->vtable->LayerGetNumFeatures, use default */
     
-    /* layer->vtable->LayerGetAutoProjection, use defaut*/    
+    /* layer->vtable->LayerGetAutoProjection, use defaut*/  
 
+    layer->vtable->LayerEscapeSQLParam = msPostGISEscapeSQLParam;
+
     return MS_SUCCESS;
 }

Modified: trunk/mapserver/mapserver.h
===================================================================
--- trunk/mapserver/mapserver.h	2011-07-12 13:19:08 UTC (rev 11897)
+++ trunk/mapserver/mapserver.h	2011-07-12 13:24:51 UTC (rev 11898)
@@ -1661,6 +1661,8 @@
   int (*LayerCreateItems)(layerObj *layer, int nt);
   int (*LayerGetNumFeatures)(layerObj *layer);
   int (*LayerGetAutoProjection)(layerObj *layer, projectionObj *projection);
+  char* (*LayerEscapeSQLParam)(layerObj *layer, const char* pszString);
+  char* (*LayerEscapePropertyName)(layerObj *layer, const char* pszString);
 };
 #endif /*SWIG*/
 
@@ -2107,6 +2109,9 @@
 
 MS_DLL_EXPORT int msLayerGetMaxFeaturesToDraw(layerObj *layer, outputFormatObj *format);
 
+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