[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