Permalink
Browse files

WFS: fix parsing of filters with parenthesis (#4986)

  • Loading branch information...
rouault committed Sep 6, 2014
1 parent a44c9c7 commit f2a817cd85099648dbf5e9349667b9f78861764f
Showing with 77 additions and 17 deletions.
  1. +76 −16 mapwfs.c
  2. +1 −1 msautotest
View
@@ -2184,6 +2184,79 @@ static int msWFSRunBasicGetFeature(mapObj* map,
return MS_SUCCESS;
}
+/*
+** msWFSSplitFilters()
+*/
+static char** msWFSSplitFilters(const char* pszStr, int* pnTokens)
+{
+ const char* pszTokenBegin;
+ char** papszRet = NULL;
+ int nTokens = 0;
+ char chStringQuote = '\0';
+ int nXMLIndent = 0;
+ int bInBracket = FALSE;
+
+ if( *pszStr != '(' )
+ {
+ *pnTokens = 0;
+ return NULL;
+ }
+ pszStr ++;
+ pszTokenBegin = pszStr;
+ while( *pszStr != '\0' )
+ {
+ /* Ignore any character until end of quoted string */
+ if( chStringQuote != '\0' )
+ {
+ if( *pszStr == chStringQuote )
+ chStringQuote = 0;
+ }
+ /* Detect begin of quoted string only for an XML attribute, i.e. between < and > */
+ else if( bInBracket && (*pszStr == '\'' || *pszStr == '"') )
+ {
+ chStringQuote = *pszStr;
+ }
+ /* Begin of XML element */
+ else if( *pszStr == '<' )
+ {
+ bInBracket = TRUE;
+ if( pszStr[1] == '/' )
+ nXMLIndent --;
+ else
+ nXMLIndent ++;
+ }
+ /* <something /> case */
+ else if (*pszStr == '/' && pszStr[1] == '>' )
+ {
+ bInBracket = FALSE;
+ nXMLIndent --;
+ pszStr ++;
+ }
+ /* End of XML element */
+ else if( *pszStr == '>' )
+ {
+ bInBracket = FALSE;
+ }
+ /* Only detect and of filter when XML indentation goes back to zero */
+ else if( nXMLIndent == 0 && *pszStr == ')' )
+ {
+ papszRet = (char**) msSmallRealloc(papszRet, sizeof(char*) * (nTokens + 1));
+ papszRet[nTokens] = msStrdup(pszTokenBegin);
+ papszRet[nTokens][pszStr - pszTokenBegin] = '\0';
+ nTokens ++;
+ if( pszStr[1] != '(' )
+ {
+ break;
+ }
+ pszStr ++;
+ pszTokenBegin = pszStr + 1;
+ }
+ pszStr ++;
+ }
+ *pnTokens = nTokens;
+ return papszRet;
+}
+
/*
** msWFSRetrieveFeatures()
*/
@@ -2208,7 +2281,6 @@ static int msWFSRetrieveFeatures(mapObj* map,
#ifdef USE_OGR
if (pszFilter && strlen(pszFilter) > 0) {
- char **tokens = NULL;
int nFilters;
char **paszFilter = NULL;
@@ -2269,22 +2341,10 @@ static int msWFSRetrieveFeatures(mapObj* map,
/* -------------------------------------------------------------------- */
nFilters = 0;
if (strlen(pszFilter) > 0 && pszFilter[0] == '(') {
- tokens = msStringSplit(pszFilter+1, '(', &nFilters);
-
- if (tokens && nFilters > 0 && numlayers == nFilters) {
- paszFilter = (char **)msSmallMalloc(sizeof(char *)*nFilters);
- for (i=0; i<nFilters; i++)
- {
- size_t nLen;
- paszFilter[i] = msStrdup(tokens[i]);
- nLen = strlen(paszFilter[i]);
- if( nLen > 0 && paszFilter[i][nLen-1] == ')' )
- paszFilter[i][nLen-1] = '\0';
- }
- }
+ paszFilter = msWFSSplitFilters(pszFilter, &nFilters);
- if (tokens && nFilters > 0 ) {
- msFreeCharArray(tokens, nFilters);
+ if ( paszFilter && nFilters > 0 && numlayers != nFilters ) {
+ msFreeCharArray(paszFilter, nFilters);
}
} else if (numlayers == 1) {
nFilters=1;
Submodule msautotest updated from c1e369 to fdb3d1

0 comments on commit f2a817c

Please sign in to comment.