diff -u mapserver-5.6.1/debian/changelog mapserver-5.6.1/debian/changelog --- mapserver-5.6.1/debian/changelog +++ mapserver-5.6.1/debian/changelog @@ -1,3 +1,11 @@ +mapserver (5.6.1-1ubuntu1.2) lucid-security; urgency=low + + * SECURITY UPDATE: Fix possible WFS SQL injection (LP: #809133) + - debian/patches/03_wfs_sql_injection.dpatch: Fix possible WFS SQL injection. + [http://trac.osgeo.org/mapserver/ticket/3874] + + -- Alan Boudreault Tue, 12 Jul 2011 01:31:01 -0400 + mapserver (5.6.1-1ubuntu1.1) lucid-security; urgency=low * SECURITY UPDATE: Buffer overflow in msTmpFile function (LP: #603593) diff -u mapserver-5.6.1/debian/patches/00list mapserver-5.6.1/debian/patches/00list --- mapserver-5.6.1/debian/patches/00list +++ mapserver-5.6.1/debian/patches/00list @@ -2,0 +3 @@ +03_wfs_sql_injection only in patch2: unchanged: --- mapserver-5.6.1.orig/debian/patches/03_wfs_sql_injection.dpatch +++ mapserver-5.6.1/debian/patches/03_wfs_sql_injection.dpatch @@ -0,0 +1,1046 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +# +# Ubuntu: https://bugs.launchpad.net/ubuntu/+source/mapserver/+bug/809133 +# Upstream: http://trac.osgeo.org/mapserver/ticket/3874 +# Patch: aboudreault@mapgears.com +# Description: Fix possible WFS sql injection +# +## 03_wfs_sql_injection.dpatch by Alan Boudreault +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: No description. + +@DPATCH@ +diff -urNad mapserver-5.6.1~/maplayer.c mapserver-5.6.1/maplayer.c +--- mapserver-5.6.1~/maplayer.c 2009-10-08 12:56:13.000000000 -0400 ++++ mapserver-5.6.1/maplayer.c 2011-07-12 01:29:28.000000000 -0400 +@@ -1024,6 +1024,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; iLayerGetNumFeatures = LayerDefaultGetNumFeatures; + ++ vtable->LayerEscapeSQLParam = LayerDefaultEscapeSQLParam; ++ ++ vtable->LayerEscapePropertyName = LayerDefaultEscapePropertyName; ++ + return MS_SUCCESS; + } + +@@ -1253,6 +1336,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) + { +@@ -1285,5 +1394,7 @@ + /* layer->vtable->LayerCreateItems, use default */ + layer->vtable->LayerGetNumFeatures = msINLINELayerGetNumFeatures; + ++ /*layer->vtable->LayerEscapeSQLParam, use default*/ ++ /*layer->vtable->LayerEscapePropertyName, use default*/ + return MS_SUCCESS; + } +diff -urNad mapserver-5.6.1~/mapogcfilter.c mapserver-5.6.1/mapogcfilter.c +--- mapserver-5.6.1~/mapogcfilter.c 2009-11-13 15:39:50.000000000 -0500 ++++ mapserver-5.6.1/mapogcfilter.c 2011-07-12 01:29:28.000000000 -0400 +@@ -168,7 +168,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(psProj); + if (msLoadProjectionString(psProj, szTmp) == 0) + nStatus = MS_TRUE; +@@ -193,7 +193,7 @@ + if (nEpsgTmp > 0) + { + char szTmp[32]; +- sprintf(szTmp, "init=epsg:%d",nEpsgTmp); ++ snprintf(szTmp, sizeof(szTmp), "init=epsg:%d",nEpsgTmp); + msInitProjection(psProj); + if (msLoadProjectionString(psProj, szTmp) == 0) + nStatus = MS_TRUE; +@@ -990,7 +990,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); +@@ -1015,7 +1015,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); +@@ -2771,9 +2771,9 @@ + bString = 1; + } + 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 "); +@@ -2838,8 +2838,7 @@ + "PropertyIsLike") == 0) + { + pszExpression = +- FLTGetIsLikeComparisonSQLExpression(psFilterNode, +- connectiontype); ++ FLTGetIsLikeComparisonSQLExpression(psFilterNode, lp); + } + } + } +@@ -2876,6 +2875,7 @@ + bString = 0; + if (tokens && nTokens > 0) + { ++ char *pszEscapedStr = NULL; + for (i=0; ipsLeftNode->pszValue); ++ strlcat(szBuffer, psFilterNode->psLeftNode->pszValue, bufferSize); + if (bString) +- strcat(szBuffer, "]\" "); ++ strlcat(szBuffer, "]\" ", bufferSize); + else +- strcat(szBuffer, "] "); ++ strlcat(szBuffer, "] ", bufferSize); + + + /* logical operator */ +@@ -3221,40 +3226,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); + } +@@ -3269,9 +3274,11 @@ + char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, + layerObj *lp) + { ++ const size_t bufferSize = 1024; + char szBuffer[1024]; + int bString=0; + char szTmp[256]; ++ char* pszEscapedStr = NULL; + + szBuffer[0] = '\0'; + if (!psFilterNode || ! +@@ -3300,7 +3307,9 @@ + + + /*opening bracket*/ +- strcat(szBuffer, " ("); ++ strlcat(szBuffer, " (", bufferSize); ++ ++ pszEscapedStr = msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue); + + /* attribute */ + /*case insensitive set ? */ +@@ -3310,35 +3319,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, ++ 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 */ + +@@ -3349,23 +3360,33 @@ + 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); + } +@@ -3379,12 +3400,13 @@ + char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, + layerObj *lp) + { ++ const size_t bufferSize = 1024; + char szBuffer[1024]; + char **aszBounds = NULL; + int nBounds = 0; + int bString=0; + char szTmp[256]; +- ++ char* pszEscapedStr; + + szBuffer[0] = '\0'; + if (!psFilterNode || +@@ -3428,32 +3450,46 @@ + /* 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); +@@ -3467,6 +3503,7 @@ + char *FLTGetIsBetweenComparisonExpresssion(FilterEncodingNode *psFilterNode, + layerObj *lp) + { ++ const size_t bufferSize = 1024; + char szBuffer[1024]; + char **aszBounds = NULL; + int nBounds = 0; +@@ -3487,7 +3524,10 @@ + /* -------------------------------------------------------------------- */ + aszBounds = msStringSplit(psFilterNode->psRightNode->pszValue, ';', &nBounds); + if (nBounds != 2) ++ { ++ msFreeCharArray(aszBounds, nBounds); + return NULL; ++ } + /* -------------------------------------------------------------------- */ + /* check if the value is a numeric value or alphanumeric. If it */ + /* is alphanumeric, add quotes around attribute and values. */ +@@ -3516,50 +3556,51 @@ + /* 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); ++ ++ msFreeCharArray(aszBounds, nBounds); ++ + return strdup(szBuffer); + } + +@@ -3570,6 +3611,7 @@ + /************************************************************************/ + char *FLTGetIsLikeComparisonExpression(FilterEncodingNode *psFilterNode) + { ++ const size_t bufferSize = 1024; + char szBuffer[1024]; + char *pszValue = NULL; + +@@ -3617,43 +3659,49 @@ + } + for (i=0; ipOther || !psFilterNode->psLeftNode || + !psFilterNode->psRightNode || !psFilterNode->psRightNode->pszValue) + return NULL; +@@ -3695,60 +3746,80 @@ + + 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; iconnectiontype != MS_OGR) + { +- strcat(szBuffer, " escape '"); ++ strlcat(szBuffer, " escape '",bufferSize); + szTmp[0] = pszEscape[0]; + if (pszEscape[0] == '\\') + { +@@ -3762,9 +3833,9 @@ + szTmp[2] = '\0'; + } + +- strcat(szBuffer, szTmp); ++ strlcat(szBuffer, szTmp,bufferSize); + } +- strcat(szBuffer, ") "); ++ strlcat(szBuffer, ") ",bufferSize); + + return strdup(szBuffer); + } +@@ -4075,7 +4146,7 @@ + { + if (!lp->items[i] || strlen(lp->items[i]) <= 0) + continue; +- sprintf(szTmp, "%s_alias", lp->items[i]); ++ snprintf(szTmp, sizeof(szTmp), "%s_alias", lp->items[i]); + pszFullName = msOWSLookupMetadata(&(lp->metadata), namespaces, szTmp); + if (pszFullName) + { +diff -urNad mapserver-5.6.1~/mapogcfilter.h mapserver-5.6.1/mapogcfilter.h +--- mapserver-5.6.1~/mapogcfilter.h 2009-07-06 12:29:03.000000000 -0400 ++++ mapserver-5.6.1/mapogcfilter.h 2011-07-12 01:29:28.000000000 -0400 +@@ -113,8 +113,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); +diff -urNad mapserver-5.6.1~/mapogcsos.c mapserver-5.6.1/mapogcsos.c +--- mapserver-5.6.1~/mapogcsos.c 2009-10-20 09:38:46.000000000 -0400 ++++ mapserver-5.6.1/mapogcsos.c 2011-07-12 01:29:28.000000000 -0400 +@@ -1820,6 +1820,7 @@ + char *pszProcedureValue = NULL; + int iItemPosition, status; + shapeObj sShape; ++ char* pszEscapedStr = NULL; + + sBbox = map->extent; + +@@ -2051,15 +2052,25 @@ + pszBuffer = msStringConcatenate(pszBuffer, "("); + + if (!bSpatialDB) +- pszBuffer = msStringConcatenate(pszBuffer, "'["); +- +- pszBuffer = msStringConcatenate(pszBuffer, (char *)pszProcedureItem); ++ { ++ pszBuffer = msStringConcatenate(pszBuffer, "'["); ++ pszBuffer = msStringConcatenate(pszBuffer, (char *)pszProcedureItem); ++ } ++ else ++ { ++ 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); + pszBuffer = msStringConcatenate(pszBuffer, "')"); + } + +diff -urNad mapserver-5.6.1~/mapogr.cpp mapserver-5.6.1/mapogr.cpp +--- mapserver-5.6.1~/mapogr.cpp 2009-09-29 17:34:13.000000000 -0400 ++++ mapserver-5.6.1/mapogr.cpp 2011-07-12 01:29:28.000000000 -0400 +@@ -3364,6 +3364,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 +@@ -3390,6 +3450,9 @@ + /* layer->vtable->LayerCreateItems, use default */ + /* layer->vtable->LayerGetNumFeatures, use default */ + ++ layer->vtable->LayerEscapeSQLParam = msOGREscapeSQLParam; ++ layer->vtable->LayerEscapePropertyName = msOGREscapePropertyName; ++ + return MS_SUCCESS; + } + +diff -urNad mapserver-5.6.1~/mappostgis.c mapserver-5.6.1/mappostgis.c +--- mapserver-5.6.1~/mappostgis.c 2009-09-15 18:34:46.000000000 -0400 ++++ mapserver-5.6.1/mappostgis.c 2011-07-12 01:29:28.000000000 -0400 +@@ -493,7 +493,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) { + char *tmp1; + char *tmp2 = NULL; +@@ -1711,7 +1711,7 @@ + msDebug("msPostGISLayerWhichShapes query: %s\n", strSQL); + } + +- pgresult = PQexec(layerinfo->pgconn, strSQL); ++ pgresult = PQexecParams(layerinfo->pgconn, strSQL,0, NULL, NULL, NULL, NULL, 0); + + if ( layer->debug > 1 ) { + msDebug("msPostGISLayerWhichShapes query status: %s (%d)\n", PQresStatus(PQresultStatus(pgresult)), PQresultStatus(pgresult)); +@@ -1911,7 +1911,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) ) { +@@ -2005,7 +2005,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); +diff -urNad mapserver-5.6.1~/mapserver.h mapserver-5.6.1/mapserver.h +--- mapserver-5.6.1~/mapserver.h 2010-01-08 16:21:54.000000000 -0500 ++++ mapserver-5.6.1/mapserver.h 2011-07-12 01:29:28.000000000 -0400 +@@ -1551,6 +1551,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*/ + +@@ -1949,6 +1951,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);