1
Author: aboudreault@mapgears.com
2
Bug: http://trac.osgeo.org/mapserver/ticket/3874
3
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/mapserver/+bug/809133
4
Description: Fix possible WFS sql injection
5
Note: updated to include http://trac.osgeo.org/mapserver/changeset/11914 and
6
fix the warning introduced in msOGREscapeSQLParam -- sbeattie)
8
Index: mapserver-5.6.6/maplayer.c
9
===================================================================
10
--- mapserver-5.6.6.orig/maplayer.c 2011-09-09 09:43:52.000000000 -0500
11
+++ mapserver-5.6.6/maplayer.c 2011-09-09 09:44:02.000000000 -0500
12
@@ -1051,6 +1051,85 @@
16
+/************************************************************************/
17
+/* LayerDefaultEscapeSQLParam */
19
+/* Default function used to escape strings and avoid sql */
20
+/* injection. Specific drivers should redefine if an escaping */
21
+/* function is available in the driver. */
22
+/************************************************************************/
23
+char *LayerDefaultEscapeSQLParam(layerObj *layer, const char* pszString)
25
+ char *pszEscapedStr=NULL;
31
+ nSrcLen = (int)strlen(pszString);
32
+ pszEscapedStr = (char*) malloc( 2 * nSrcLen + 1);
33
+ for(i = 0, j = 0; i < nSrcLen; i++)
38
+ pszEscapedStr[j++] = '\'';
39
+ pszEscapedStr[j++] = '\'';
43
+ pszEscapedStr[j++] = '\\';
44
+ pszEscapedStr[j++] = '\\';
47
+ pszEscapedStr[j++] = c;
49
+ pszEscapedStr[j] = 0;
51
+ return pszEscapedStr;
54
+/************************************************************************/
55
+/* LayerDefaultEscapePropertyName */
57
+/* Return the property name in a properly escaped and quoted form. */
58
+/************************************************************************/
59
+char *LayerDefaultEscapePropertyName(layerObj *layer, const char* pszString)
61
+ char* pszEscapedStr=NULL;
64
+ if (layer && pszString && strlen(pszString) > 0)
66
+ int nLength = strlen(pszString);
68
+ pszEscapedStr = (char*) malloc( 1 + 2 * nLength + 1 + 1);
69
+ pszEscapedStr[j++] = '"';
71
+ for (i=0; i<nLength; i++)
73
+ char c = pszString[i];
76
+ pszEscapedStr[j++] = '"';
77
+ pszEscapedStr[j++] ='"';
81
+ pszEscapedStr[j++] = '\\';
82
+ pszEscapedStr[j++] = '\\';
85
+ pszEscapedStr[j++] = c;
87
+ pszEscapedStr[j++] = '"';
88
+ pszEscapedStr[j++] = 0;
91
+ return pszEscapedStr;
98
@@ -1108,6 +1187,10 @@
100
vtable->LayerGetNumFeatures = LayerDefaultGetNumFeatures;
102
+ vtable->LayerEscapeSQLParam = LayerDefaultEscapeSQLParam;
104
+ vtable->LayerEscapePropertyName = LayerDefaultEscapePropertyName;
109
@@ -1280,6 +1363,32 @@
116
+Returns an escaped string
118
+char *msLayerEscapeSQLParam(layerObj *layer, const char*pszString)
120
+ if ( ! layer->vtable) {
121
+ int rv = msInitializeVirtualTable(layer);
122
+ if (rv != MS_SUCCESS)
125
+ return layer->vtable->LayerEscapeSQLParam(layer, pszString);
128
+char *msLayerEscapePropertyName(layerObj *layer, const char*pszString)
130
+ if ( ! layer->vtable) {
131
+ int rv = msInitializeVirtualTable(layer);
132
+ if (rv != MS_SUCCESS)
135
+ return layer->vtable->LayerEscapePropertyName(layer, pszString);
140
msINLINELayerInitializeVirtualTable(layerObj *layer)
142
@@ -1312,5 +1421,7 @@
143
/* layer->vtable->LayerCreateItems, use default */
144
layer->vtable->LayerGetNumFeatures = msINLINELayerGetNumFeatures;
146
+ /*layer->vtable->LayerEscapeSQLParam, use default*/
147
+ /*layer->vtable->LayerEscapePropertyName, use default*/
150
Index: mapserver-5.6.6/mapogcfilter.c
151
===================================================================
152
--- mapserver-5.6.6.orig/mapogcfilter.c 2011-09-09 09:43:52.000000000 -0500
153
+++ mapserver-5.6.6/mapogcfilter.c 2011-09-09 09:44:02.000000000 -0500
155
if (tokens && nTokens == 2)
158
- sprintf(szTmp, "init=epsg:%s",tokens[1]);
159
+ snprintf(szTmp, sizeof(szTmp), "init=epsg:%s",tokens[1]);
160
msInitProjection(psProj);
161
if (msLoadProjectionString(psProj, szTmp) == 0)
167
- sprintf(szTmp, "init=epsg:%d",nEpsgTmp);
168
+ snprintf(szTmp, sizeof(szTmp), "init=epsg:%d",nEpsgTmp);
169
msInitProjection(psProj);
170
if (msLoadProjectionString(psProj, szTmp) == 0)
173
if (tokens && nTokens == 2)
176
- sprintf(szTmp, "init=epsg:%s",tokens[1]);
177
+ snprintf(szTmp, sizeof(szTmp), "init=epsg:%s",tokens[1]);
178
msInitProjection(&sProjTmp);
179
if (msLoadProjectionString(&sProjTmp, szTmp) == 0)
180
msProjectRect(&sProjTmp, &map->projection, &sQueryRect);
181
@@ -1014,7 +1014,7 @@
185
- sprintf(szTmp, "init=epsg:%d",nEpsgTmp);
186
+ snprintf(szTmp, sizeof(szTmp), "init=epsg:%d",nEpsgTmp);
187
msInitProjection(&sProjTmp);
188
if (msLoadProjectionString(&sProjTmp, szTmp) == 0)
189
msProjectRect(&sProjTmp, &map->projection, &sQueryRect);
190
@@ -2780,9 +2780,9 @@
194
- sprintf(szTmp, "('[%s]' = '%s')" , pszAttribute, tokens[i]);
195
+ snprintf(szTmp, sizeof(szTmp), "('[%s]' = '%s')" , pszAttribute, tokens[i]);
197
- sprintf(szTmp, "([%s] = %s)" , pszAttribute, tokens[i]);
198
+ snprintf(szTmp, sizeof(szTmp), "([%s] = %s)" , pszAttribute, tokens[i]);
200
if (pszExpression != NULL)
201
pszExpression = msStringConcatenate(pszExpression, " OR ");
202
@@ -2847,8 +2847,7 @@
203
"PropertyIsLike") == 0)
206
- FLTGetIsLikeComparisonSQLExpression(psFilterNode,
208
+ FLTGetIsLikeComparisonSQLExpression(psFilterNode, lp);
212
@@ -2885,6 +2884,7 @@
214
if (tokens && nTokens > 0)
216
+ char *pszEscapedStr = NULL;
217
for (i=0; i<nTokens; i++)
220
@@ -2893,10 +2893,14 @@
221
if (FLTIsNumeric(pszTmp) == MS_FALSE)
224
+ pszEscapedStr = msLayerEscapeSQLParam(lp, tokens[i]);
226
- sprintf(szTmp, "(%s = '%s')" , pszAttribute, tokens[i]);
227
+ snprintf(szTmp, sizeof(szTmp), "(%s = '%s')" , pszAttribute, pszEscapedStr);
229
- sprintf(szTmp, "(%s = %s)" , pszAttribute, tokens[i]);
230
+ snprintf(szTmp, sizeof(szTmp), "(%s = %s)" , pszAttribute, pszEscapedStr);
232
+ msFree(pszEscapedStr);
233
+ pszEscapedStr=NULL;
235
if (pszExpression != NULL)
236
pszExpression = msStringConcatenate(pszExpression, " OR ");
237
@@ -3181,6 +3185,7 @@
238
/************************************************************************/
239
char *FLTGetBinaryComparisonExpresssion(FilterEncodingNode *psFilterNode, layerObj *lp)
241
+ const size_t bufferSize = 1024;
245
@@ -3210,16 +3215,16 @@
249
- strcat(szBuffer, " (\"[");
250
+ strlcat(szBuffer, " (\"[", bufferSize);
252
- strcat(szBuffer, " ([");
253
+ strlcat(szBuffer, " ([", bufferSize);
256
- strcat(szBuffer, psFilterNode->psLeftNode->pszValue);
257
+ strlcat(szBuffer, psFilterNode->psLeftNode->pszValue, bufferSize);
259
- strcat(szBuffer, "]\" ");
260
+ strlcat(szBuffer, "]\" ", bufferSize);
262
- strcat(szBuffer, "] ");
263
+ strlcat(szBuffer, "] ", bufferSize);
266
/* logical operator */
267
@@ -3230,40 +3235,40 @@
268
if (psFilterNode->psRightNode->pOther &&
269
(*(int *)psFilterNode->psRightNode->pOther) == 1)
271
- strcat(szBuffer, "IEQ");
272
+ strlcat(szBuffer, "IEQ", bufferSize);
275
- strcat(szBuffer, "=");
276
+ strlcat(szBuffer, "=",bufferSize);
278
else if (strcasecmp(psFilterNode->pszValue,
279
"PropertyIsNotEqualTo") == 0)
280
- strcat(szBuffer, "!=");
281
+ strlcat(szBuffer, "!=", bufferSize);
282
else if (strcasecmp(psFilterNode->pszValue,
283
"PropertyIsLessThan") == 0)
284
- strcat(szBuffer, "<");
285
+ strlcat(szBuffer, "<", bufferSize);
286
else if (strcasecmp(psFilterNode->pszValue,
287
"PropertyIsGreaterThan") == 0)
288
- strcat(szBuffer, ">");
289
+ strlcat(szBuffer, ">", bufferSize);
290
else if (strcasecmp(psFilterNode->pszValue,
291
"PropertyIsLessThanOrEqualTo") == 0)
292
- strcat(szBuffer, "<=");
293
+ strlcat(szBuffer, "<=", bufferSize);
294
else if (strcasecmp(psFilterNode->pszValue,
295
"PropertyIsGreaterThanOrEqualTo") == 0)
296
- strcat(szBuffer, ">=");
297
+ strlcat(szBuffer, ">=", bufferSize);
299
- strcat(szBuffer, " ");
300
+ strlcat(szBuffer, " ", bufferSize);
304
- strcat(szBuffer, "\"");
305
+ strlcat(szBuffer, "\"", bufferSize);
307
if (psFilterNode->psRightNode->pszValue)
308
- strcat(szBuffer, psFilterNode->psRightNode->pszValue);
309
+ strlcat(szBuffer, psFilterNode->psRightNode->pszValue,bufferSize);
312
- strcat(szBuffer, "\"");
313
+ strlcat(szBuffer, "\"",bufferSize);
315
- strcat(szBuffer, ") ");
316
+ strlcat(szBuffer, ") ",bufferSize);
318
return strdup(szBuffer);
320
@@ -3278,9 +3283,11 @@
321
char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode,
324
+ const size_t bufferSize = 1024;
328
+ char* pszEscapedStr = NULL;
331
if (!psFilterNode || !
332
@@ -3309,7 +3316,9 @@
336
- strcat(szBuffer, " (");
337
+ strlcat(szBuffer, " (", bufferSize);
339
+ pszEscapedStr = msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue);
342
/*case insensitive set ? */
343
@@ -3319,35 +3328,37 @@
344
psFilterNode->psRightNode->pOther &&
345
(*(int *)psFilterNode->psRightNode->pOther) == 1)
347
- sprintf(szTmp, "lower(%s) ", psFilterNode->psLeftNode->pszValue);
348
- strcat(szBuffer, szTmp);
349
+ snprintf(szTmp, sizeof(szTmp), "lower(%s) ", pszEscapedStr);
350
+ strlcat(szBuffer, szTmp, bufferSize);
353
- strcat(szBuffer, psFilterNode->psLeftNode->pszValue);
354
+ strlcat(szBuffer, pszEscapedStr, bufferSize);
356
+ msFree(pszEscapedStr);
357
+ pszEscapedStr = NULL;
360
/* logical operator */
361
- if (strcasecmp(psFilterNode->pszValue,
362
+ if (strcasecmp(psFilterNode->pszValue,
363
"PropertyIsEqualTo") == 0)
364
- strcat(szBuffer, "=");
365
+ strlcat(szBuffer, "=", bufferSize);
366
else if (strcasecmp(psFilterNode->pszValue,
367
"PropertyIsNotEqualTo") == 0)
368
- strcat(szBuffer, "<>");
369
+ strlcat(szBuffer, "<>", bufferSize);
370
else if (strcasecmp(psFilterNode->pszValue,
371
"PropertyIsLessThan") == 0)
372
- strcat(szBuffer, "<");
373
+ strlcat(szBuffer, "<", bufferSize);
374
else if (strcasecmp(psFilterNode->pszValue,
375
"PropertyIsGreaterThan") == 0)
376
- strcat(szBuffer, ">");
377
+ strlcat(szBuffer, ">", bufferSize);
378
else if (strcasecmp(psFilterNode->pszValue,
379
"PropertyIsLessThanOrEqualTo") == 0)
380
- strcat(szBuffer, "<=");
381
+ strlcat(szBuffer, "<=", bufferSize);
382
else if (strcasecmp(psFilterNode->pszValue,
383
"PropertyIsGreaterThanOrEqualTo") == 0)
384
- strcat(szBuffer, ">=");
385
+ strlcat(szBuffer, ">=", bufferSize);
387
- strcat(szBuffer, " ");
388
+ strlcat(szBuffer, " ", bufferSize);
392
@@ -3358,23 +3369,33 @@
393
psFilterNode->psRightNode->pOther &&
394
(*(int *)psFilterNode->psRightNode->pOther) == 1)
396
- sprintf(szTmp, "lower('%s') ", psFilterNode->psRightNode->pszValue);
397
- strcat(szBuffer, szTmp);
398
+ snprintf(szTmp, sizeof(szTmp), "lower('%s') ", psFilterNode->psRightNode->pszValue);
399
+ strlcat(szBuffer, szTmp, bufferSize);
404
- strcat(szBuffer, "'");
405
+ strlcat(szBuffer, "'", bufferSize);
407
if (psFilterNode->psRightNode->pszValue)
408
- strcat(szBuffer, psFilterNode->psRightNode->pszValue);
412
+ char* pszEscapedStr;
413
+ pszEscapedStr = msLayerEscapeSQLParam(lp, psFilterNode->psRightNode->pszValue);
414
+ strlcat(szBuffer, pszEscapedStr, bufferSize);
415
+ msFree(pszEscapedStr);
416
+ pszEscapedStr=NULL;
419
+ strlcat(szBuffer, psFilterNode->psRightNode->pszValue, bufferSize);
423
- strcat(szBuffer, "'");
425
+ strlcat(szBuffer, "'", bufferSize);
428
- strcat(szBuffer, ") ");
429
+ strlcat(szBuffer, ") ", bufferSize);
431
return strdup(szBuffer);
433
@@ -3388,12 +3409,13 @@
434
char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode,
437
+ const size_t bufferSize = 1024;
439
char **aszBounds = NULL;
444
+ char* pszEscapedStr;
448
@@ -3437,32 +3459,46 @@
449
/* build expresssion. */
450
/* -------------------------------------------------------------------- */
451
/*opening paranthesis */
452
- strcat(szBuffer, " (");
453
+ strlcat(szBuffer, " (",bufferSize);
456
- strcat(szBuffer, psFilterNode->psLeftNode->pszValue);
457
+ pszEscapedStr = msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue);
459
+ strlcat(szBuffer, pszEscapedStr, bufferSize);
460
+ msFree(pszEscapedStr);
461
+ pszEscapedStr = NULL;
464
- strcat(szBuffer, " BETWEEN ");
465
+ strlcat(szBuffer, " BETWEEN ",bufferSize);
469
- strcat(szBuffer,"'");
470
- strcat(szBuffer, aszBounds[0]);
471
+ strlcat(szBuffer,"'",bufferSize);
473
+ pszEscapedStr = msLayerEscapeSQLParam( lp, aszBounds[0]);
474
+ strlcat(szBuffer, pszEscapedStr, bufferSize);
475
+ msFree(pszEscapedStr);
476
+ pszEscapedStr=NULL;
479
- strcat(szBuffer,"'");
480
+ strlcat(szBuffer,"'",bufferSize);
482
- strcat(szBuffer, " AND ");
483
+ strlcat(szBuffer, " AND ",bufferSize);
487
- strcat(szBuffer, "'");
488
- strcat(szBuffer, aszBounds[1]);
489
+ strlcat(szBuffer, "'",bufferSize);
491
+ pszEscapedStr = msLayerEscapeSQLParam( lp, aszBounds[1]);
492
+ strlcat(szBuffer, pszEscapedStr, bufferSize);
493
+ msFree(pszEscapedStr);
494
+ pszEscapedStr=NULL;
497
- strcat(szBuffer,"'");
498
+ strlcat(szBuffer,"'",bufferSize);
500
/*closing paranthesis*/
501
- strcat(szBuffer, ")");
502
+ strlcat(szBuffer, ")",bufferSize);
505
return strdup(szBuffer);
506
@@ -3476,6 +3512,7 @@
507
char *FLTGetIsBetweenComparisonExpresssion(FilterEncodingNode *psFilterNode,
510
+ const size_t bufferSize = 1024;
512
char **aszBounds = NULL;
514
@@ -3496,7 +3533,10 @@
515
/* -------------------------------------------------------------------- */
516
aszBounds = msStringSplit(psFilterNode->psRightNode->pszValue, ';', &nBounds);
519
+ msFreeCharArray(aszBounds, nBounds);
522
/* -------------------------------------------------------------------- */
523
/* check if the value is a numeric value or alphanumeric. If it */
524
/* is alphanumeric, add quotes around attribute and values. */
525
@@ -3525,50 +3565,51 @@
526
/* build expresssion. */
527
/* -------------------------------------------------------------------- */
529
- strcat(szBuffer, " (\"[");
530
+ strlcat(szBuffer, " (\"[", bufferSize);
532
- strcat(szBuffer, " ([");
533
+ strlcat(szBuffer, " ([", bufferSize);
536
- strcat(szBuffer, psFilterNode->psLeftNode->pszValue);
537
+ strlcat(szBuffer, psFilterNode->psLeftNode->pszValue, bufferSize);
540
- strcat(szBuffer, "]\" ");
541
+ strlcat(szBuffer, "]\" ", bufferSize);
543
- strcat(szBuffer, "] ");
544
+ strlcat(szBuffer, "] ", bufferSize);
547
- strcat(szBuffer, " >= ");
548
+ strlcat(szBuffer, " >= ", bufferSize);
550
- strcat(szBuffer,"\"");
551
- strcat(szBuffer, aszBounds[0]);
552
+ strlcat(szBuffer,"\"", bufferSize);
553
+ strlcat(szBuffer, aszBounds[0], bufferSize);
555
- strcat(szBuffer,"\"");
556
+ strlcat(szBuffer,"\"", bufferSize);
558
- strcat(szBuffer, " AND ");
559
+ strlcat(szBuffer, " AND ", bufferSize);
562
- strcat(szBuffer, " \"[");
563
+ strlcat(szBuffer, " \"[", bufferSize);
565
- strcat(szBuffer, " [");
566
+ strlcat(szBuffer, " [", bufferSize);
569
- strcat(szBuffer, psFilterNode->psLeftNode->pszValue);
570
+ strlcat(szBuffer, psFilterNode->psLeftNode->pszValue, bufferSize);
573
- strcat(szBuffer, "]\" ");
574
+ strlcat(szBuffer, "]\" ", bufferSize);
576
- strcat(szBuffer, "] ");
577
+ strlcat(szBuffer, "] ", bufferSize);
579
- strcat(szBuffer, " <= ");
580
+ strlcat(szBuffer, " <= ", bufferSize);
582
- strcat(szBuffer,"\"");
583
- strcat(szBuffer, aszBounds[1]);
584
+ strlcat(szBuffer,"\"", bufferSize);
585
+ strlcat(szBuffer, aszBounds[1], bufferSize);
587
- strcat(szBuffer,"\"");
588
- strcat(szBuffer, ")");
591
+ strlcat(szBuffer,"\"", bufferSize);
592
+ strlcat(szBuffer, ")", bufferSize);
594
+ msFreeCharArray(aszBounds, nBounds);
596
return strdup(szBuffer);
599
@@ -3579,6 +3620,7 @@
600
/************************************************************************/
601
char *FLTGetIsLikeComparisonExpression(FilterEncodingNode *psFilterNode)
603
+ const size_t bufferSize = 1024;
605
char *pszValue = NULL;
607
@@ -3626,43 +3668,49 @@
609
for (i=0; i<nLength; i++)
611
- if (pszValue[i] != pszWild[0] &&
612
- pszValue[i] != pszSingle[0] &&
613
- pszValue[i] != pszEscape[0])
615
- szBuffer[iBuffer] = pszValue[i];
617
- szBuffer[iBuffer] = '\0';
619
- else if (pszValue[i] == pszSingle[0])
621
- szBuffer[iBuffer] = '.';
623
- szBuffer[iBuffer] = '\0';
625
- else if (pszValue[i] == pszEscape[0])
626
+ if (iBuffer < 1024)
628
- szBuffer[iBuffer] = '\\';
630
- szBuffer[iBuffer] = '\0';
631
+ if (pszValue[i] != pszWild[0] &&
632
+ pszValue[i] != pszSingle[0] &&
633
+ pszValue[i] != pszEscape[0])
635
+ szBuffer[iBuffer] = pszValue[i];
637
+ szBuffer[iBuffer] = '\0';
639
+ else if (pszValue[i] == pszSingle[0])
641
+ szBuffer[iBuffer] = '.';
643
+ szBuffer[iBuffer] = '\0';
645
+ else if (pszValue[i] == pszEscape[0])
647
+ szBuffer[iBuffer] = '\\';
649
+ szBuffer[iBuffer] = '\0';
652
- else if (pszValue[i] == pszWild[0])
654
- /* strcat(szBuffer, "[0-9,a-z,A-Z,\\s]*"); */
656
- strcat(szBuffer, ".*");
658
- szBuffer[iBuffer] = '\0';
660
+ else if (pszValue[i] == pszWild[0])
662
+ /* strcat(szBuffer, "[0-9,a-z,A-Z,\\s]*"); */
664
+ strlcat(szBuffer, ".*",bufferSize);
666
+ szBuffer[iBuffer] = '\0';
670
- szBuffer[iBuffer] = '/';
671
- if (bCaseInsensitive == 1)
673
+ if (iBuffer < 1024)
675
- szBuffer[++iBuffer] = 'i';
677
- szBuffer[++iBuffer] = '\0';
679
+ szBuffer[iBuffer] = '/';
680
+ if (bCaseInsensitive == 1)
682
+ szBuffer[++iBuffer] = 'i';
684
+ szBuffer[++iBuffer] = '\0';
687
return strdup(szBuffer);
689
@@ -3673,8 +3721,9 @@
690
/* Build an sql expression for IsLike filter. */
691
/************************************************************************/
692
char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode,
693
- int connectiontype)
696
+ const size_t bufferSize = 1024;
698
char *pszValue = NULL;
700
@@ -3683,9 +3732,11 @@
701
char *pszEscape = NULL;
704
- int nLength=0, i=0, iBuffer = 0;
705
+ int nLength=0, i=0, j=0;
706
int bCaseInsensitive = 0;
708
+ char *pszEscapedStr = NULL;
710
if (!psFilterNode || !psFilterNode->pOther || !psFilterNode->psLeftNode ||
711
!psFilterNode->psRightNode || !psFilterNode->psRightNode->pszValue)
713
@@ -3704,60 +3755,80 @@
717
- strcat(szBuffer, " (");
718
+ strlcat(szBuffer, " (", bufferSize);
721
- strcat(szBuffer, psFilterNode->psLeftNode->pszValue);
722
- if (bCaseInsensitive == 1 && connectiontype == MS_POSTGIS)
723
- strcat(szBuffer, " ilike '");
724
+ pszEscapedStr = msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue);
726
+ strlcat(szBuffer, pszEscapedStr, bufferSize);
727
+ msFree(pszEscapedStr);
728
+ pszEscapedStr = NULL;
731
+ if (bCaseInsensitive == 1 && lp->connectiontype == MS_POSTGIS)
732
+ strlcat(szBuffer, " ilike '",bufferSize);
734
- strcat(szBuffer, " like '");
735
+ strlcat(szBuffer, " like '",bufferSize);
738
pszValue = psFilterNode->psRightNode->pszValue;
739
nLength = strlen(pszValue);
740
- iBuffer = strlen(szBuffer);
742
+ pszEscapedStr = (char*) malloc( 3 * nLength + 1);
744
for (i=0; i<nLength; i++)
746
- if (pszValue[i] != pszWild[0] &&
747
- pszValue[i] != pszSingle[0] &&
748
- pszValue[i] != pszEscape[0])
749
+ char c = pszValue[i];
750
+ if (c != pszWild[0] &&
751
+ c != pszSingle[0] &&
754
- szBuffer[iBuffer] = pszValue[i];
756
- szBuffer[iBuffer] = '\0';
759
+ pszEscapedStr[j++] = '\'';
760
+ pszEscapedStr[j++] = '\'';
762
+ else if (c == '\\')
764
+ pszEscapedStr[j++] = '\\';
765
+ pszEscapedStr[j++] = '\\';
768
+ pszEscapedStr[j++] = c;
770
- else if (pszValue[i] == pszSingle[0])
771
+ else if (c == pszSingle[0])
773
- szBuffer[iBuffer] = '_';
775
- szBuffer[iBuffer] = '\0';
776
+ pszEscapedStr[j++] = '_';
778
- else if (pszValue[i] == pszEscape[0])
779
+ else if (c == pszEscape[0])
781
- szBuffer[iBuffer] = pszEscape[0];
783
- szBuffer[iBuffer] = '\0';
785
+ pszEscapedStr[j++] = pszEscape[0];
788
- szBuffer[iBuffer] = pszValue[i+1];
790
- szBuffer[iBuffer] = '\0';
791
+ char nextC = pszValue[i+1];
795
+ pszEscapedStr[j++] = '\'';
796
+ pszEscapedStr[j++] = '\'';
799
+ pszEscapedStr[j++] = nextC;
803
- else if (pszValue[i] == pszWild[0])
804
+ else if (c == pszWild[0])
806
- strcat(szBuffer, "%");
808
- szBuffer[iBuffer] = '\0';
809
+ pszEscapedStr[j++] = '%';
812
+ pszEscapedStr[j++] = 0;
813
+ strlcat(szBuffer, pszEscapedStr, bufferSize);
814
+ msFree(pszEscapedStr);
816
- strcat(szBuffer, "'");
817
- if (connectiontype != MS_OGR)
818
+ strlcat(szBuffer, "'",bufferSize);
819
+ if (lp->connectiontype != MS_OGR)
821
- strcat(szBuffer, " escape '");
822
+ strlcat(szBuffer, " escape '",bufferSize);
823
szTmp[0] = pszEscape[0];
824
if (pszEscape[0] == '\\')
826
@@ -3771,9 +3842,9 @@
830
- strcat(szBuffer, szTmp);
831
+ strlcat(szBuffer, szTmp,bufferSize);
833
- strcat(szBuffer, ") ");
834
+ strlcat(szBuffer, ") ",bufferSize);
836
return strdup(szBuffer);
838
@@ -4084,7 +4155,7 @@
840
if (!lp->items[i] || strlen(lp->items[i]) <= 0)
842
- sprintf(szTmp, "%s_alias", lp->items[i]);
843
+ snprintf(szTmp, sizeof(szTmp), "%s_alias", lp->items[i]);
844
pszFullName = msOWSLookupMetadata(&(lp->metadata), namespaces, szTmp);
847
Index: mapserver-5.6.6/mapogcfilter.h
848
===================================================================
849
--- mapserver-5.6.6.orig/mapogcfilter.h 2011-09-09 09:43:52.000000000 -0500
850
+++ mapserver-5.6.6/mapogcfilter.h 2011-09-09 09:44:02.000000000 -0500
852
MS_DLL_EXPORT char *FLTGetSQLExpression(FilterEncodingNode *psFilterNode,layerObj *lp);
853
MS_DLL_EXPORT char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, layerObj *lp);
854
MS_DLL_EXPORT char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, layerObj *lp);
855
-MS_DLL_EXPORT char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode,
856
- int connectiontype);
857
+MS_DLL_EXPORT char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode, layerObj *lp);
859
MS_DLL_EXPORT char *FLTGetLogicalComparisonSQLExpresssion(FilterEncodingNode *psFilterNode,
861
MS_DLL_EXPORT int FLTIsSimpleFilter(FilterEncodingNode *psFilterNode);
862
Index: mapserver-5.6.6/mapogcsos.c
863
===================================================================
864
--- mapserver-5.6.6.orig/mapogcsos.c 2011-09-09 09:43:52.000000000 -0500
865
+++ mapserver-5.6.6/mapogcsos.c 2011-09-09 09:44:02.000000000 -0500
866
@@ -1820,6 +1820,7 @@
867
char *pszProcedureValue = NULL;
868
int iItemPosition, status;
870
+ char* pszEscapedStr = NULL;
874
@@ -2051,15 +2052,25 @@
875
pszBuffer = msStringConcatenate(pszBuffer, "(");
878
- pszBuffer = msStringConcatenate(pszBuffer, "'[");
880
- pszBuffer = msStringConcatenate(pszBuffer, (char *)pszProcedureItem);
882
+ pszBuffer = msStringConcatenate(pszBuffer, "'[");
883
+ pszBuffer = msStringConcatenate(pszBuffer, (char *)pszProcedureItem);
887
+ pszEscapedStr = msLayerEscapePropertyName(lp, (char *)pszProcedureItem);
888
+ pszBuffer = msStringConcatenate(pszBuffer, pszEscapedStr);
889
+ msFree(pszEscapedStr);
890
+ pszEscapedStr = NULL;
894
pszBuffer = msStringConcatenate(pszBuffer, "]'");
896
pszBuffer = msStringConcatenate(pszBuffer, " = '");
897
- pszBuffer = msStringConcatenate(pszBuffer, tokens[j]);
898
+ pszEscapedStr = msLayerEscapeSQLParam(lp, tokens[j]);
899
+ pszBuffer = msStringConcatenate(pszBuffer, pszEscapedStr);
900
+ msFree(pszEscapedStr);
901
pszBuffer = msStringConcatenate(pszBuffer, "')");
904
Index: mapserver-5.6.6/mapogr.cpp
905
===================================================================
906
--- mapserver-5.6.6.orig/mapogr.cpp 2011-09-09 09:43:52.000000000 -0500
907
+++ mapserver-5.6.6/mapogr.cpp 2011-09-09 09:44:02.000000000 -0500
908
@@ -3465,6 +3465,66 @@
911
/************************************************************************/
912
+/* msOGREscapeSQLParam */
913
+/************************************************************************/
914
+char *msOGREscapeSQLParam(layerObj *layer, const char *pszString)
916
+ char* pszEscapedStr =NULL;
918
+ if(layer && pszString && strlen(pszString) > 0)
920
+ char* pszEscapedOGRStr = CPLEscapeString(pszString, strlen(pszString),
922
+ pszEscapedStr = strdup(pszEscapedOGRStr);
923
+ CPLFree(pszEscapedOGRStr);
925
+ return pszEscapedStr;
927
+/* ------------------------------------------------------------------
928
+ * OGR Support not included...
929
+ * ------------------------------------------------------------------ */
931
+ msSetError(MS_MISCERR, "OGR support is not available.",
932
+ "msOGREscapeSQLParam()");
935
+#endif /* USE_OGR */
939
+/************************************************************************/
940
+/* msOGREscapeSQLParam */
941
+/************************************************************************/
942
+char *msOGREscapePropertyName(layerObj *layer, const char *pszString)
944
+ char* pszEscapedStr =NULL;
947
+ if(layer && pszString && strlen(pszString) > 0)
950
+ for(i=0; (ch = ((unsigned char*)pszString)[i]) != '\0'; i++)
952
+ if ( !(isalnum(ch) || ch == '_' || ch > 127) )
954
+ return strdup("invalid_property_name");
957
+ pszEscapedStr = strdup(pszString);
959
+ return pszEscapedStr;
961
+/* ------------------------------------------------------------------
962
+ * OGR Support not included...
963
+ * ------------------------------------------------------------------ */
965
+ msSetError(MS_MISCERR, "OGR support is not available.",
966
+ "msOGREscapePropertyName()");
969
+#endif /* USE_OGR */
971
+/************************************************************************/
972
/* msOGRLayerInitializeVirtualTable() */
973
/************************************************************************/
975
@@ -3491,6 +3551,9 @@
976
/* layer->vtable->LayerCreateItems, use default */
977
/* layer->vtable->LayerGetNumFeatures, use default */
979
+ layer->vtable->LayerEscapeSQLParam = msOGREscapeSQLParam;
980
+ layer->vtable->LayerEscapePropertyName = msOGREscapePropertyName;
985
Index: mapserver-5.6.6/mappostgis.c
986
===================================================================
987
--- mapserver-5.6.6.orig/mappostgis.c 2011-09-09 09:43:53.000000000 -0500
988
+++ mapserver-5.6.6/mappostgis.c 2011-09-09 09:44:02.000000000 -0500
993
- pgresult = PQexec(layerinfo->pgconn, sql);
994
+ pgresult = PQexecParams(layerinfo->pgconn, sql,0, NULL, NULL, NULL, NULL, 0);
995
if ( !pgresult || PQresultStatus(pgresult) != PGRES_TUPLES_OK) {
998
@@ -1774,7 +1774,7 @@
999
msDebug("msPostGISLayerWhichShapes query: %s\n", strSQL);
1002
- pgresult = PQexec(layerinfo->pgconn, strSQL);
1003
+ pgresult = PQexecParams(layerinfo->pgconn, strSQL,0, NULL, NULL, NULL, NULL, 0);
1005
if ( layer->debug > 1 ) {
1006
msDebug("msPostGISLayerWhichShapes query status: %s (%d)\n", PQresStatus(PQresultStatus(pgresult)), PQresultStatus(pgresult));
1007
@@ -1979,7 +1979,7 @@
1008
msDebug("msPostGISLayerGetShape query: %s\n", strSQL);
1011
- pgresult = PQexec(layerinfo->pgconn, strSQL);
1012
+ pgresult = PQexecParams(layerinfo->pgconn, strSQL,0, NULL, NULL, NULL, NULL, 0);
1014
/* Something went wrong. */
1015
if ( (!pgresult) || (PQresultStatus(pgresult) != PGRES_TUPLES_OK) ) {
1016
@@ -2073,7 +2073,7 @@
1017
msDebug("msPostGISLayerGetItems executing SQL: %s\n", sql);
1020
- pgresult = PQexec(layerinfo->pgconn, sql);
1021
+ pgresult = PQexecParams(layerinfo->pgconn, sql,0, NULL, NULL, NULL, NULL, 0);
1023
if ( (!pgresult) || (PQresultStatus(pgresult) != PGRES_TUPLES_OK) ) {
1024
msSetError(MS_QUERYERR, "Error (%s) executing SQL: %s", "msPostGISLayerGetItems()", PQerrorMessage(layerinfo->pgconn), sql);
1025
@@ -2538,6 +2538,42 @@
1030
+char *msPostGISEscapeSQLParam(layerObj *layer, const char *pszString)
1033
+ msPostGISLayerInfo *layerinfo = NULL;
1036
+ char* pszEscapedStr =NULL;
1038
+ if (layer && pszString && strlen(pszString) > 0)
1040
+ if(!msPostGISLayerIsOpen(layer))
1041
+ msPostGISLayerOpen(layer);
1043
+ assert(layer->layerinfo != NULL);
1045
+ layerinfo = (msPostGISLayerInfo *) layer->layerinfo;
1046
+ nSrcLen = strlen(pszString);
1047
+ pszEscapedStr = (char*) malloc( 2 * nSrcLen + 1);
1048
+ PQescapeStringConn (layerinfo->pgconn, pszEscapedStr, pszString, nSrcLen, &nError);
1051
+ free(pszEscapedStr);
1052
+ pszEscapedStr = NULL;
1055
+ return pszEscapedStr;
1057
+ msSetError( MS_MISCERR,
1058
+ "PostGIS support is not available.",
1059
+ "msPostGISEscapeSQLParam()");
1065
int msPostGISLayerInitializeVirtualTable(layerObj *layer) {
1066
assert(layer != NULL);
1067
assert(layer->vtable != NULL);
1068
@@ -2560,5 +2596,8 @@
1069
/* layer->vtable->LayerCreateItems, use default */
1070
/* layer->vtable->LayerGetNumFeatures, use default */
1073
+ layer->vtable->LayerEscapeSQLParam = msPostGISEscapeSQLParam;
1077
Index: mapserver-5.6.6/mapserver.h
1078
===================================================================
1079
--- mapserver-5.6.6.orig/mapserver.h 2011-09-09 09:43:53.000000000 -0500
1080
+++ mapserver-5.6.6/mapserver.h 2011-09-09 09:44:02.000000000 -0500
1081
@@ -1556,6 +1556,8 @@
1083
int (*LayerCreateItems)(layerObj *layer, int nt);
1084
int (*LayerGetNumFeatures)(layerObj *layer);
1085
+ char* (*LayerEscapeSQLParam)(layerObj *layer, const char* pszString);
1086
+ char* (*LayerEscapePropertyName)(layerObj *layer, const char* pszString);
1090
@@ -1955,6 +1957,9 @@
1092
MS_DLL_EXPORT int msLayerGetNumFeatures(layerObj *layer);
1094
+MS_DLL_EXPORT char *msLayerEscapeSQLParam(layerObj *layer, const char* pszString);
1095
+MS_DLL_EXPORT char *msLayerEscapePropertyName(layerObj *layer, const char* pszString);
1097
/* These are special because SWF is using these */
1098
int msOGRLayerNextShape(layerObj *layer, shapeObj *shape);
1099
int msOGRLayerGetItems(layerObj *layer);