• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geographika / mapserver / 17823520225

18 Sep 2025 08:57AM UTC coverage: 41.442% (-0.02%) from 41.466%
17823520225

push

github

geographika
Use full path for CONFIG test

62112 of 149877 relevant lines covered (41.44%)

25354.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

49.77
/src/mapservutil.c
1
/******************************************************************************
2
 * $id$
3
 *
4
 * Project:  MapServer
5
 * Purpose:  MapServer CGI utility functions.
6
 * Author:   Steve Lime and the MapServer team.
7
 *
8
 ******************************************************************************
9
 * Copyright (c) 1996-2005 Regents of the University of Minnesota.
10
 *
11
 * Permission is hereby granted, free of charge, to any person obtaining a
12
 * copy of this software and associated documentation files (the "Software"),
13
 * to deal in the Software without restriction, including without limitation
14
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15
 * and/or sell copies of the Software, and to permit persons to whom the
16
 * Software is furnished to do so, subject to the following conditions:
17
 *
18
 * The above copyright notice and this permission notice shall be included in
19
 * all copies of this Software or works derived from this Software.
20
 *
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27
 * DEALINGS IN THE SOFTWARE.
28
 ****************************************************************************/
29

30
#include "mapserver.h"
31
#include "apps/mapserv.h"
32
#include "maptime.h"
33
#include "mapows.h"
34
#include "mapogcapi.h"
35
#include "mapserv-index.h"
36

37
#include "cpl_conv.h"
38

39
#include "mapserver-config.h"
40

41
/*
42
** Enumerated types, keep the query modes in sequence and at the end of the
43
*enumeration (mode enumeration is in maptemplate.h).
44
*/
45
static const int numModes = 23;
46
static char *const modeStrings[23] = {"BROWSE",
47
                                      "ZOOMIN",
48
                                      "ZOOMOUT",
49
                                      "MAP",
50
                                      "LEGEND",
51
                                      "LEGENDICON",
52
                                      "REFERENCE",
53
                                      "SCALEBAR",
54
                                      "COORDINATE",
55
                                      "QUERY",
56
                                      "NQUERY",
57
                                      "ITEMQUERY",
58
                                      "ITEMNQUERY",
59
                                      "FEATUREQUERY",
60
                                      "FEATURENQUERY",
61
                                      "ITEMFEATUREQUERY",
62
                                      "ITEMFEATURENQUERY",
63
                                      "INDEXQUERY",
64
                                      "TILE",
65
                                      "OWS",
66
                                      "WFS",
67
                                      "MAPLEGEND",
68
                                      "MAPLEGENDICON"};
69

70
static int commonLoadForm(mapservObj *mapserv, mapObj *map);
71

72
void msCGIWriteError(mapservObj *mapserv) {
290✔
73
  errorObj *ms_error = msGetErrorObj();
290✔
74

75
  if (!ms_error || ms_error->code == MS_NOERR || ms_error->isreported) {
290✔
76
    /* either we have no error, or it was already reported by other means */
77
    return;
78
  }
79

80
  if (!mapserv || !mapserv->map) {
34✔
81
    if (CPLGetConfigOption("MS_ERROR_URL", NULL) != NULL) {
18✔
82
      msRedirect(CPLGetConfigOption("MS_ERROR_URL", NULL));
1✔
83
    } else {
84
      if (ms_error->http_status[0])
17✔
85
        msIO_setHeader("Status", "%s", ms_error->http_status);
1✔
86
      msIO_setHeader("Content-Type", "text/html");
17✔
87
      msIO_sendHeaders();
17✔
88
      msIO_printf("<HTML>\n");
17✔
89
      msIO_printf("<HEAD><TITLE>MapServer Message</TITLE></HEAD>\n");
17✔
90
      msIO_printf("<BODY BGCOLOR=\"#FFFFFF\">\n");
17✔
91
      msWriteErrorXML(stdout);
17✔
92
      msIO_printf("</BODY></HTML>");
17✔
93
    }
94
    return;
18✔
95
  }
96

97
  if ((ms_error->code == MS_NOTFOUND) &&
16✔
98
      (mapserv->map->web.empty != NULL ||
3✔
99
       CPLGetConfigOption("MS_EMPTY_URL", NULL) != NULL)) {
3✔
100
    const char *url = mapserv->map->web.empty; // takes precedence
2✔
101
    if (url == NULL)
2✔
102
      url = CPLGetConfigOption("MS_EMPTY_URL", NULL);
1✔
103
    msRedirect(url);
2✔
104
  } else if (mapserv->map->web.error != NULL ||
28✔
105
             CPLGetConfigOption("MS_ERROR_URL", NULL) != NULL) {
14✔
106
    const char *url = mapserv->map->web.error; // takes precedence
×
107
    if (url == NULL)
×
108
      url = CPLGetConfigOption("MS_ERROR_URL", NULL);
×
109
    msRedirect(url);
×
110
  } else {
111
    if (ms_error->http_status[0])
14✔
112
      msIO_setHeader("Status", "%s", ms_error->http_status);
×
113
    msIO_setHeader("Content-Type", "text/html");
14✔
114
    msIO_sendHeaders();
14✔
115
    msIO_printf("<HTML>\n");
14✔
116
    msIO_printf("<HEAD><TITLE>MapServer Message</TITLE></HEAD>\n");
14✔
117
    msIO_printf("<BODY BGCOLOR=\"#FFFFFF\">\n");
14✔
118
    msWriteErrorXML(stdout);
14✔
119
    msIO_printf("</BODY></HTML>");
14✔
120
  }
121

122
  return;
123
}
124

125
/*
126
** Converts a string (e.g. form parameter) to a double, first checking the
127
*format against
128
** a regular expression. returns an error if the format test fails.
129
*/
130

131
#define GET_NUMERIC(string, dbl)                                               \
132
  do {                                                                         \
133
    dbl = strtod((string), &strtoderr);                                        \
134
    if (*strtoderr) {                                                          \
135
      msSetError(MS_TYPEERR, NULL, "GET_NUMERIC()");                           \
136
      return MS_FAILURE;                                                       \
137
    }                                                                          \
138
  } while (0)
139

140
#define GET_NUMERIC_NO_ERROR(string, dbl) dbl = strtod((string), &strtoderr);
141

142
#define FREE_TOKENS_ON_ERROR(ntok)                                             \
143
  if (!strtoderr) {                                                            \
144
    msSetError(MS_TYPEERR, "invalid number", "msCGILoadForm()");               \
145
    msFreeCharArray(tokens, (ntok));                                           \
146
    return MS_FAILURE;                                                         \
147
  }
148

149
static void setClassGroup(layerObj *layer, char *classgroup) {
×
150
  int i;
151

152
  if (!layer || !classgroup)
×
153
    return;
154

155
  for (i = 0; i < layer->numclasses; i++) {
×
156
    if (layer->class[i] -> group && strcmp(layer->class[i] -> group,
×
157
                                           classgroup) == 0) {
158
      msFree(layer->classgroup);
×
159
      layer->classgroup = msStrdup(classgroup);
×
160
      return; /* bail */
×
161
    }
162
  }
163
}
164

165
/*
166
** Extract Map File name from params and load it.
167
** Returns map object or NULL on error.
168
*/
169
mapObj *msCGILoadMap(mapservObj *mapserv, configObj *config) {
1,985✔
170
  int i;
171
  mapObj *map = NULL;
172

173
  const char *ms_map_bad_pattern_default = "[/\\\\]{2}|[/\\\\]?\\.+[/\\\\]|,";
174

175
  int ms_mapfile_tainted = MS_TRUE;
176
  const char *ms_mapfile = CPLGetConfigOption("MS_MAPFILE", NULL);
1,985✔
177

178
  const char *ms_map_no_path = CPLGetConfigOption("MS_MAP_NO_PATH", NULL);
1,985✔
179
  const char *ms_map_pattern = CPLGetConfigOption("MS_MAP_PATTERN", NULL);
1,985✔
180

181
  const char *ms_map_bad_pattern =
182
      CPLGetConfigOption("MS_MAP_BAD_PATTERN", NULL);
1,985✔
183
  if (ms_map_bad_pattern == NULL)
1,985✔
184
    ms_map_bad_pattern = ms_map_bad_pattern_default;
185

186
  const char *map_value = NULL;
187

188
  // Determine if it is a WMS query so that errors emitted look for the
189
  // MS_WMS_ERROR_STATUS_CODE configuration option to determine if a HTTP
190
  // status must be emitted. Otherwise MS_HTTP_ERROR_STATUS_CODE is used.
191
  {
192
    int isWMS = MS_FALSE;
193
    for (i = 0; i < mapserv->request->NumParams; i++) {
4,415✔
194
      if (strcasecmp(mapserv->request->ParamNames[i], "SERVICE") == 0) {
4,077✔
195
        isWMS = strcasecmp(mapserv->request->ParamValues[i], "WMS") == 0;
1,647✔
196
        break;
1,647✔
197
      }
198
    }
199
    msSetErrorSetIsWMS(isWMS);
1,985✔
200
  }
201

202
  if (mapserv->request->api_path != NULL) {
1,985✔
203
    map_value = mapserv->request
38✔
204
                    ->api_path[0]; /* mapfile is *always* in the first position
205
                                      (/{mapfile}/{signature}) of an API call */
206
  } else {
207
    for (i = 0; i < mapserv->request->NumParams;
1,995✔
208
         i++) { /* find the map parameter */
48✔
209
      if (strcasecmp(mapserv->request->ParamNames[i], "map") == 0) {
1,839✔
210
        map_value = mapserv->request->ParamValues[i];
1,791✔
211
        break;
1,791✔
212
      }
213
    }
214
  }
215

216
  if (map_value == NULL) {
1,985✔
217
    if (ms_mapfile == NULL) {
156✔
218
      msSetErrorWithStatus(MS_WEBERR, MS_HTTP_500_INTERNAL_SERVER_ERROR,
×
219
                           "CGI variable \"map\" is not set.",
220
                           "msCGILoadMap()"); /* no default, outta here */
221
      return NULL;
×
222
    }
223
    ms_mapfile_tainted = MS_FALSE;
224
  } else {
225
    char pathBuf[MS_MAXPATHLEN];
226
    ms_mapfile = msConfigGetMap(
1,829✔
227
        config, map_value,
228
        pathBuf); /* does NOT check the environment, only the config */
229
    if (ms_mapfile) {
1,829✔
230
      ms_mapfile_tainted = MS_FALSE;
231
    } else {
232
      /* by now we know the map parameter isn't referencing something in the
233
       * configuration */
234
      if (ms_map_no_path != NULL) {
1,827✔
235
        msSetErrorWithStatus(
3✔
236
            MS_WEBERR, MS_HTTP_500_INTERNAL_SERVER_ERROR,
237
            "CGI variable \"map\" not found in configuration and this "
238
            "server is not configured for full paths.",
239
            "msCGILoadMap()");
240
        return NULL;
3✔
241
      }
242
      ms_mapfile = map_value;
243
    }
244
  }
245

246
  /* validate ms_mapfile if tainted */
247
  if (ms_mapfile_tainted == MS_TRUE) {
248
    if (ms_map_pattern == NULL) { // can't go any further, bail
1,824✔
249
      msSetErrorWithStatus(
1✔
250
          MS_WEBERR, MS_HTTP_500_INTERNAL_SERVER_ERROR,
251
          "Required configuration value MS_MAP_PATTERN not set.",
252
          "msCGILoadMap()");
253
      return NULL;
1✔
254
    }
255
    if (msIsValidRegex(ms_map_bad_pattern) == MS_FALSE ||
3,646✔
256
        msEvalRegex(ms_map_bad_pattern, ms_mapfile) == MS_TRUE) {
1,823✔
257
      msSetErrorWithStatus(MS_WEBERR, MS_HTTP_500_INTERNAL_SERVER_ERROR,
×
258
                           "CGI variable \"map\" fails to validate.",
259
                           "msCGILoadMap()");
260
      return NULL;
×
261
    }
262
    if (msEvalRegex(ms_map_pattern, ms_mapfile) != MS_TRUE) {
1,823✔
263
      msSetErrorWithStatus(MS_WEBERR, MS_HTTP_500_INTERNAL_SERVER_ERROR,
2✔
264
                           "CGI variable \"map\" fails to validate.",
265
                           "msCGILoadMap()");
266
      return NULL;
2✔
267
    }
268
  }
269

270
  /* ok to try to load now */
271
  map = msLoadMap(ms_mapfile, NULL, config);
1,979✔
272
  if (!map)
1,979✔
273
    return NULL;
274

275
  /* handle common parameters */
276
  if (commonLoadForm(mapserv, map) != MS_SUCCESS) {
1,972✔
277
    msFreeMap(map);
×
278
    return NULL;
×
279
  }
280

281
  if (!msLookupHashTable(&(map->web.validation), "immutable")) {
1,972✔
282
    /* check for any %variable% substitutions, we do this here so WMS/WFS  */
283
    /* services can take advantage of these "vendor specific" extensions */
284

285
    msApplySubstitutions(map, mapserv->request->ParamNames,
1,972✔
286
                         mapserv->request->ParamValues,
287
                         mapserv->request->NumParams);
1,972✔
288
    msApplyDefaultSubstitutions(map);
1,972✔
289

290
    /* check to see if a ogc map context is passed as argument. if there */
291
    /* is one load it */
292

293
    for (i = 0; i < mapserv->request->NumParams; i++) {
15,757✔
294
      if (strcasecmp(mapserv->request->ParamNames[i], "context") == 0) {
13,785✔
295
        if (mapserv->request->ParamValues[i] &&
2✔
296
            strlen(mapserv->request->ParamValues[i]) > 0) {
2✔
297
          if (strncasecmp(mapserv->request->ParamValues[i], "http", 4) == 0) {
2✔
298
            if (msGetConfigOption(map, "CGI_CONTEXT_URL"))
×
299
              msLoadMapContextURL(map, mapserv->request->ParamValues[i],
×
300
                                  MS_FALSE);
301
          } else {
302
            const char *map_context_filename = mapserv->request->ParamValues[i];
303
            const char *ms_context_pattern =
304
                CPLGetConfigOption("MS_CONTEXT_PATTERN", NULL);
2✔
305
            const char *ms_context_bad_pattern =
306
                CPLGetConfigOption("MS_CONTEXT_BAD_PATTERN", NULL);
2✔
307
            if (ms_context_bad_pattern == NULL)
2✔
308
              ms_context_bad_pattern = ms_map_bad_pattern_default;
309

310
            if (ms_context_pattern == NULL) { // can't go any further, bail
2✔
311
              msSetErrorWithStatus(
×
312
                  MS_WEBERR, MS_HTTP_500_INTERNAL_SERVER_ERROR,
313
                  "Required configuration value MS_CONTEXT_PATTERN not set.",
314
                  "msCGILoadMap()");
315
              msFreeMap(map);
×
316
              return NULL;
×
317
            }
318
            if (msIsValidRegex(ms_context_bad_pattern) == MS_FALSE ||
4✔
319
                msEvalRegex(ms_context_bad_pattern, map_context_filename) ==
2✔
320
                    MS_TRUE) {
321
              msSetErrorWithStatus(
×
322
                  MS_WEBERR, MS_HTTP_500_INTERNAL_SERVER_ERROR,
323
                  "CGI variable \"context\" fails to validate.",
324
                  "msCGILoadMap()");
325
              msFreeMap(map);
×
326
              return NULL;
×
327
            }
328
            if (msEvalRegex(ms_context_pattern, map_context_filename) !=
2✔
329
                MS_TRUE) {
330
              msSetErrorWithStatus(
×
331
                  MS_WEBERR, MS_HTTP_500_INTERNAL_SERVER_ERROR,
332
                  "CGI variable \"context\" fails to validate.",
333
                  "msCGILoadMap()");
334
              msFreeMap(map);
×
335
              return NULL;
×
336
            }
337
            msLoadMapContext(map, map_context_filename, MS_FALSE);
2✔
338
          }
339
        }
340
      }
341
    }
342
  }
343

344
  /*
345
   * RFC-42 HTTP Cookie Forwarding
346
   * Here we set the http_cookie_data metadata to handle the
347
   * HTTP Cookie Forwarding. The content of this metadata is the cookie
348
   * content. In the future, this metadata will probably be replaced
349
   * by an object that is part of the mapObject that would contain
350
   * information on the application status (such as cookie).
351
   */
352
  if (mapserv->request->httpcookiedata != NULL) {
1,972✔
353
    msInsertHashTable(&(map->web.metadata), "http_cookie_data",
×
354
                      mapserv->request->httpcookiedata);
355
  }
356

357
  return map;
358
}
359

360
/*
361
** Set operation mode. First look in MS_MODE env. var. as a
362
** default value that can be overridden by the mode=... CGI param.
363
** Returns silently, leaving mapserv->Mode unchanged if mode param not set.
364
*/
365
int msCGISetMode(mapservObj *mapserv) {
1,939✔
366
  const char *mode = NULL;
367
  int i, j;
368

369
  mode = CPLGetConfigOption("MS_MODE", NULL);
1,939✔
370
  for (i = 0; i < mapserv->request->NumParams; i++) {
15,278✔
371
    if (strcasecmp(mapserv->request->ParamNames[i], "mode") == 0) {
13,465✔
372
      mode = mapserv->request->ParamValues[i];
126✔
373
      break;
126✔
374
    }
375
  }
376

377
  if (mode) {
1,939✔
378
    for (j = 0; j < numModes; j++) {
1,215✔
379
      if (strcasecmp(mode, modeStrings[j]) == 0) {
1,215✔
380
        mapserv->Mode = j;
126✔
381
        break;
126✔
382
      }
383
    }
384

385
    if (j == numModes) {
126✔
386
      msSetError(MS_WEBERR, "Invalid mode.", "msCGISetMode()");
×
387
      return MS_FAILURE;
×
388
    }
389
  }
390

391
  if (mapserv->Mode >= 0) {
1,939✔
392
    int disabled = MS_FALSE;
126✔
393
    const char *enable_modes =
394
        msLookupHashTable(&mapserv->map->web.metadata, "ms_enable_modes");
126✔
395

396
    if (!msOWSParseRequestMetadata(enable_modes, mode, &disabled) && disabled) {
126✔
397
      /* the current mode is disabled */
398
      msSetError(MS_WEBERR,
×
399
                 "The specified mode '%s' is not supported by the current map "
400
                 "configuration",
401
                 "msCGISetMode()", mode);
402
      return MS_FAILURE;
×
403
    }
404
  }
405

406
  return MS_SUCCESS;
407
}
408

409
/*
410
** API-related functions.
411
*/
412
int msCGIIsAPIRequest(mapservObj *mapserv) {
1,986✔
413
  char **tmp_api_path = NULL;
414
  int i, n, tmp_api_path_length = 0;
1,986✔
415

416
  mapserv->request->path_info = getenv("PATH_INFO");
1,986✔
417
  if (mapserv->request->path_info != NULL &&
1,986✔
418
      strlen(mapserv->request->path_info) > 0) {
38✔
419
    tmp_api_path =
420
        msStringSplit(mapserv->request->path_info, '/',
38✔
421
                      &tmp_api_path_length); // ignores consecutive delimiters
422
    if (tmp_api_path_length >=
38✔
423
        2) { // we can access a mapfile by key using /{mapfile-key} so 2
424
             // components at a minimum (1st component is a zero-length string)
425

426
      // capture only non-zero length components
427
      n = 0;
428
      for (i = 0; i < tmp_api_path_length; i++) {
227✔
429
        if (strlen(tmp_api_path[i]) > 0)
189✔
430
          n++;
148✔
431
      }
432

433
      if (n < 1) { // we need at least a mapfile key for a legitimate request
38✔
434
        msFreeCharArray(tmp_api_path, tmp_api_path_length);
×
435
        return MS_FALSE;
×
436
      }
437

438
      mapserv->request->api_path = (char **)msSmallMalloc(sizeof(char *) * n);
38✔
439
      if (mapserv->request->api_path == NULL) {
38✔
440
        msFreeCharArray(tmp_api_path, tmp_api_path_length);
×
441
        return MS_FALSE;
×
442
      }
443

444
      mapserv->request->api_path_length = 0;
38✔
445
      for (i = 0; i < tmp_api_path_length; i++) {
227✔
446
        if (strlen(tmp_api_path[i]) > 0) {
189✔
447
          mapserv->request->api_path[mapserv->request->api_path_length] =
296✔
448
              msStrdup(tmp_api_path[i]);
148✔
449
          mapserv->request->api_path_length++;
148✔
450
        }
451
      }
452

453
      msFreeCharArray(tmp_api_path, tmp_api_path_length);
38✔
454
      return MS_TRUE;
38✔
455
    } else {
456
      msFreeCharArray(tmp_api_path, tmp_api_path_length);
×
457
    }
458
  }
459

460
  return MS_FALSE;
461
}
462

463
int msCGIDispatchAPIRequest(mapservObj *mapserv) {
33✔
464
  // should be a more elegant way to do this (perhaps similar to how drivers are
465
  // handled)
466
  if (strcmp("ogcapi", mapserv->request->api_path[1]) == 0) {
33✔
467
#ifdef USE_OGCAPI_SVR
468
    return msOGCAPIDispatchRequest(mapserv->map, mapserv->request);
31✔
469
#else
470
    msSetError(MS_OGCAPIERR, "OGC API server support is not enabled.",
471
               "msCGIDispatchAPIRequest()");
472
#endif
473
  } else {
474
    msSetError(MS_WEBERR, "Invalid API signature.",
2✔
475
               "msCGIDispatchAPIRequest()");
476
  }
477

478
  return MS_FAILURE;
2✔
479
}
480

481
/*
482
** Process common parameters that can apply to CGI and WxS calls - there are
483
*just a few and affect the mapObj directly.
484
*/
485
static int commonLoadForm(mapservObj *mapserv, mapObj *map) {
1,972✔
486
  double tmpval;
487
  char *strtoderr;
488

489
  if (!mapserv || !map)
1,972✔
490
    return MS_FAILURE;
491

492
  for (int i = 0; i < mapserv->request->NumParams; i++) {
15,757✔
493
    if (strlen(mapserv->request->ParamValues[i]) == 0)
13,785✔
494
      continue;
465✔
495

496
    if (strncasecmp(mapserv->request->ParamNames[i], "classgroup", 10) ==
13,320✔
497
        0) { /* #4207 */
498
      for (int j = 0; j < map->numlayers; j++) {
×
499
        setClassGroup(GET_LAYER(map, j), mapserv->request->ParamValues[i]);
×
500
      }
501
      continue;
×
502
    }
503

504
    /*
505
    ** For backwards compatibility. Might want to consider a vendor parameter
506
    *for WFS specifically and then deprecate this.
507
    */
508
    if (strcasecmp(mapserv->request->ParamNames[i], "map.extent") == 0 ||
13,320✔
509
        strcasecmp(mapserv->request->ParamNames[i], "map_extent") == 0) {
13,320✔
510
      int n = 0;
2✔
511
      char **tokens = msStringSplit(mapserv->request->ParamValues[i], ' ', &n);
2✔
512

513
      if (!tokens) {
2✔
514
        msSetError(MS_MEMERR, NULL, "commonLoadForm()");
×
515
        return MS_FAILURE;
×
516
      }
517

518
      if (n != 4) {
2✔
519
        msSetError(MS_WEBERR, "Not enough arguments for mapext.",
×
520
                   "commonLoadForm()");
521
        msFreeCharArray(tokens, n);
×
522
        return MS_FAILURE;
×
523
      }
524

525
      GET_NUMERIC_NO_ERROR(tokens[0], map->extent.minx);
2✔
526
      FREE_TOKENS_ON_ERROR(4);
2✔
527
      GET_NUMERIC_NO_ERROR(tokens[1], map->extent.miny);
2✔
528
      FREE_TOKENS_ON_ERROR(4);
2✔
529
      GET_NUMERIC_NO_ERROR(tokens[2], map->extent.maxx);
2✔
530
      FREE_TOKENS_ON_ERROR(4);
2✔
531
      GET_NUMERIC_NO_ERROR(tokens[3], map->extent.maxy);
2✔
532
      FREE_TOKENS_ON_ERROR(4);
2✔
533

534
      msFreeCharArray(tokens, 4);
2✔
535

536
      if (!MS_VALID_EXTENT(map->extent)) {
2✔
537
        msSetError(MS_WEBERR,
×
538
                   "Supplied extent is invalid. Check that it is in the form: "
539
                   "minx, miny, maxx, maxy",
540
                   "commonLoadForm()");
541
        return (MS_FAILURE);
×
542
      }
543
    }
544

545
    /*
546
    ** For backwards compatibility - we don't use plain RESOLUTION here because
547
    *of a potential conflict WCS. Might want
548
    ** to consider a vendor parameter for WMS specifically and then deprecate
549
    *these.
550
    */
551
    if (strcasecmp(mapserv->request->ParamNames[i], "map.resolution") == 0 ||
13,320✔
552
        strcasecmp(mapserv->request->ParamNames[i], "map_resolution") == 0) {
13,305✔
553
      GET_NUMERIC(mapserv->request->ParamValues[i], tmpval);
20✔
554
      if (tmpval < MS_RESOLUTION_MIN || tmpval > MS_RESOLUTION_MAX) {
20✔
555
        msSetError(MS_WEBERR, "Resolution value out of range.",
×
556
                   "commonLoadForm()");
557
        return MS_FAILURE;
×
558
      }
559
      map->resolution = (int)tmpval;
20✔
560
      continue;
20✔
561
    }
562

563
    if (strcasecmp(mapserv->request->ParamNames[i], "keysize") ==
13,300✔
564
        0) { // legend keysize, used with legend-related outputs
3✔
565
      int n = 0;
3✔
566
      char **tokens = msStringSplit(mapserv->request->ParamValues[i], ' ', &n);
3✔
567

568
      if (!tokens) {
3✔
569
        msSetError(MS_MEMERR, NULL, "commonLoadForm()");
×
570
        return MS_FAILURE;
×
571
      }
572

573
      if (n != 2) {
3✔
574
        msSetError(MS_WEBERR, "Not enough arguments for keysize.",
×
575
                   "commonLoadForm()");
576
        msFreeCharArray(tokens, n);
×
577
        return MS_FAILURE;
×
578
      }
579

580
      GET_NUMERIC_NO_ERROR(tokens[0], tmpval);
3✔
581
      FREE_TOKENS_ON_ERROR(2);
3✔
582
      map->legend.keysizex = (int)tmpval;
3✔
583
      GET_NUMERIC_NO_ERROR(tokens[1], tmpval);
3✔
584
      FREE_TOKENS_ON_ERROR(2);
3✔
585
      map->legend.keysizey = (int)tmpval;
3✔
586

587
      msFreeCharArray(tokens, 2);
3✔
588

589
      if (map->legend.keysizex < MS_LEGEND_KEYSIZE_MIN ||
3✔
590
          map->legend.keysizex > MS_LEGEND_KEYSIZE_MAX ||
3✔
591
          map->legend.keysizey < MS_LEGEND_KEYSIZE_MIN ||
3✔
592
          map->legend.keysizey > MS_LEGEND_KEYSIZE_MAX) {
593
        msSetError(MS_WEBERR, "Legend keysize out of range.",
×
594
                   "commonLoadForm()");
595
        return MS_FAILURE;
×
596
      }
597

598
      continue;
3✔
599
    }
600
  }
601

602
  return MS_SUCCESS;
603
}
604

605
/*
606
** Process CGI parameters.
607
*/
608
int msCGILoadForm(mapservObj *mapserv) {
128✔
609
  int i, n;
610
  char **tokens = NULL;
611
  double tmpval;
612
  char *strtoderr;
613

614
  for (i = 0; i < mapserv->request->NumParams;
646✔
615
       i++) { /* now process the rest of the form variables */
518✔
616
    if (strlen(mapserv->request->ParamValues[i]) == 0)
519✔
617
      continue;
×
618

619
    if (strcasecmp(mapserv->request->ParamNames[i], "icon") == 0) {
519✔
620
      mapserv->icon = msStrdup(mapserv->request->ParamValues[i]);
×
621
      continue;
×
622
    }
623

624
    if (strcasecmp(mapserv->request->ParamNames[i], "queryfile") == 0) {
519✔
625
      mapserv->QueryFile = msStrdup(mapserv->request->ParamValues[i]);
×
626
      if (msValidateParameter(
×
627
              mapserv->QueryFile,
×
628
              msLookupHashTable(&(mapserv->map->web.validation), "queryfile"),
×
629
              NULL, NULL, NULL) != MS_SUCCESS) {
630
        msSetError(MS_WEBERR, "Parameter 'queryfile' value fails to validate.",
×
631
                   "mapserv()");
632
        return MS_FAILURE;
×
633
      }
634
      continue;
×
635
    }
636

637
    if (strcasecmp(mapserv->request->ParamNames[i], "savequery") == 0) {
519✔
638
      mapserv->savequery = MS_TRUE;
×
639
      continue;
×
640
    }
641

642
    /* Insecure as implemented, need to save someplace non accessible by
643
       everyone in the universe
644
        if(strcasecmp(mapserv->request->ParamNames[i],"savemap") == 0) {
645
         mapserv->savemap = MS_TRUE;
646
         continue;
647
        }
648
    */
649

650
    if (strcasecmp(mapserv->request->ParamNames[i], "zoom") == 0) {
519✔
651
      GET_NUMERIC(mapserv->request->ParamValues[i], mapserv->Zoom);
×
652
      if ((mapserv->Zoom > MAXZOOM) || (mapserv->Zoom < MINZOOM)) {
×
653
        msSetError(MS_WEBERR, "Zoom value out of range.", "msCGILoadForm()");
×
654
        return MS_FAILURE;
×
655
      }
656
      continue;
×
657
    }
658

659
    if (strcasecmp(mapserv->request->ParamNames[i], "zoomdir") == 0) {
519✔
660
      GET_NUMERIC(mapserv->request->ParamValues[i], tmpval);
×
661
      mapserv->ZoomDirection = (int)tmpval;
×
662
      if ((mapserv->ZoomDirection != -1) && (mapserv->ZoomDirection != 1) &&
×
663
          (mapserv->ZoomDirection != 0)) {
664
        msSetError(MS_WEBERR, "Zoom direction must be 1, 0 or -1.",
×
665
                   "msCGILoadForm()");
666
        return MS_FAILURE;
×
667
      }
668
      continue;
×
669
    }
670

671
    if (strcasecmp(mapserv->request->ParamNames[i], "zoomsize") ==
519✔
672
        0) { /* absolute zoom magnitude */
673
      GET_NUMERIC(mapserv->request->ParamValues[i], tmpval);
×
674
      mapserv->ZoomSize = (int)tmpval;
×
675
      if ((mapserv->ZoomSize > MAXZOOM) || (mapserv->ZoomSize < 1)) {
×
676
        msSetError(MS_WEBERR, "Invalid zoom size.", "msCGILoadForm()");
×
677
        return MS_FAILURE;
×
678
      }
679
      continue;
×
680
    }
681

682
    if (strcasecmp(mapserv->request->ParamNames[i], "imgext") ==
519✔
683
        0) { /* extent of an existing image in a web application */
684
      tokens = msStringSplit(mapserv->request->ParamValues[i], ' ', &n);
8✔
685

686
      if (!tokens) {
8✔
687
        msSetError(MS_MEMERR, NULL, "msCGILoadForm()");
×
688
        return MS_FAILURE;
×
689
      }
690

691
      if (n != 4) {
8✔
692
        msSetError(MS_WEBERR, "Not enough arguments for imgext.",
×
693
                   "msCGILoadForm()");
694
        msFreeCharArray(tokens, n);
×
695
        return MS_FAILURE;
×
696
      }
697

698
      GET_NUMERIC_NO_ERROR(tokens[0], mapserv->ImgExt.minx);
8✔
699
      FREE_TOKENS_ON_ERROR(4);
8✔
700
      GET_NUMERIC_NO_ERROR(tokens[1], mapserv->ImgExt.miny);
8✔
701
      FREE_TOKENS_ON_ERROR(4);
8✔
702
      GET_NUMERIC_NO_ERROR(tokens[2], mapserv->ImgExt.maxx);
8✔
703
      FREE_TOKENS_ON_ERROR(4);
8✔
704
      GET_NUMERIC_NO_ERROR(tokens[3], mapserv->ImgExt.maxy);
8✔
705
      FREE_TOKENS_ON_ERROR(4);
8✔
706

707
      msFreeCharArray(tokens, 4);
8✔
708
      continue;
8✔
709
    }
710

711
    if (strcasecmp(mapserv->request->ParamNames[i], "searchmap") == 0) {
511✔
712
      mapserv->SearchMap = MS_TRUE;
×
713
      continue;
×
714
    }
715

716
    if (strcasecmp(mapserv->request->ParamNames[i], "id") == 0) {
511✔
717
      if (msEvalRegex(IDPATTERN, mapserv->request->ParamValues[i]) ==
×
718
          MS_FALSE) {
719
        msSetError(MS_WEBERR, "Parameter 'id' value fails to validate.",
×
720
                   "msCGILoadForm()");
721
        return MS_FAILURE;
×
722
      }
723
      strlcpy(mapserv->Id, mapserv->request->ParamValues[i], IDSIZE);
×
724
      continue;
×
725
    }
726

727
    if (strcasecmp(mapserv->request->ParamNames[i], "mapext") ==
511✔
728
        0) { /* extent of the new map or query */
729

730
      if (strncasecmp(mapserv->request->ParamValues[i], "shape", 5) == 0)
19✔
731
        mapserv->UseShapes = MS_TRUE;
×
732
      else {
733
        tokens = msStringSplit(mapserv->request->ParamValues[i], ' ', &n);
19✔
734

735
        if (!tokens) {
19✔
736
          msSetError(MS_MEMERR, NULL, "msCGILoadForm()");
×
737
          return MS_FAILURE;
×
738
        }
739

740
        if (n != 4) {
19✔
741
          msSetError(MS_WEBERR, "Not enough arguments for mapext.",
×
742
                     "msCGILoadForm()");
743
          msFreeCharArray(tokens, n);
×
744
          return MS_FAILURE;
×
745
        }
746

747
        GET_NUMERIC_NO_ERROR(tokens[0], mapserv->map->extent.minx);
19✔
748
        FREE_TOKENS_ON_ERROR(4);
19✔
749
        GET_NUMERIC_NO_ERROR(tokens[1], mapserv->map->extent.miny);
19✔
750
        FREE_TOKENS_ON_ERROR(4);
19✔
751
        GET_NUMERIC_NO_ERROR(tokens[2], mapserv->map->extent.maxx);
19✔
752
        FREE_TOKENS_ON_ERROR(4);
19✔
753
        GET_NUMERIC_NO_ERROR(tokens[3], mapserv->map->extent.maxy);
19✔
754
        FREE_TOKENS_ON_ERROR(4);
19✔
755

756
        msFreeCharArray(tokens, 4);
19✔
757

758
        /*
759
         * If there is a projection in the map file, and it is not lon/lat, and
760
         * the extents "look like" they *are* lon/lat, based on their size, then
761
         * convert the extents to the map file projection.
762
         *
763
         * DANGER: If the extents are legitimately in the mapfile projection
764
         *         and coincidentally fall in the lon/lat range, bad things
765
         *         will ensue.
766
         */
767
        if (mapserv->map->projection.proj &&
23✔
768
            !msProjIsGeographicCRS(&(mapserv->map->projection)) &&
4✔
769
            (mapserv->map->extent.minx >= -180.0 &&
4✔
770
             mapserv->map->extent.minx <= 180.0) &&
2✔
771
            (mapserv->map->extent.miny >= -90.0 &&
2✔
772
             mapserv->map->extent.miny <= 90.0) &&
2✔
773
            (mapserv->map->extent.maxx >= -180.0 &&
2✔
774
             mapserv->map->extent.maxx <= 180.0) &&
×
775
            (mapserv->map->extent.maxy >= -90.0 &&
×
776
             mapserv->map->extent.maxy <= 90.0)) {
777
          msProjectRect(&(mapserv->map->latlon), &(mapserv->map->projection),
×
778
                        &(mapserv->map->extent)); /* extent is a in lat/lon */
779
        }
780

781
        if ((mapserv->map->extent.minx != mapserv->map->extent.maxx) &&
19✔
782
            (mapserv->map->extent.miny !=
19✔
783
             mapserv->map->extent.maxy)) { /* extent seems ok */
19✔
784
          mapserv->CoordSource = FROMUSERBOX;
19✔
785
          mapserv->QueryCoordSource = FROMUSERBOX;
19✔
786
        }
787
      }
788

789
      continue;
19✔
790
    }
791

792
    if (strcasecmp(mapserv->request->ParamNames[i], "minx") ==
492✔
793
        0) { /* extent of the new map, in pieces */
794
      GET_NUMERIC(mapserv->request->ParamValues[i], mapserv->map->extent.minx);
×
795
      continue;
×
796
    }
797
    if (strcasecmp(mapserv->request->ParamNames[i], "maxx") == 0) {
492✔
798
      GET_NUMERIC(mapserv->request->ParamValues[i], mapserv->map->extent.maxx);
×
799
      continue;
×
800
    }
801
    if (strcasecmp(mapserv->request->ParamNames[i], "miny") == 0) {
492✔
802
      GET_NUMERIC(mapserv->request->ParamValues[i], mapserv->map->extent.miny);
×
803
      continue;
×
804
    }
805
    if (strcasecmp(mapserv->request->ParamNames[i], "maxy") == 0) {
492✔
806
      GET_NUMERIC(mapserv->request->ParamValues[i], mapserv->map->extent.maxy);
×
807
      mapserv->CoordSource = FROMUSERBOX;
×
808
      mapserv->QueryCoordSource = FROMUSERBOX;
×
809
      continue;
×
810
    }
811

812
    if (strcasecmp(mapserv->request->ParamNames[i], "mapxy") ==
492✔
813
        0) { /* user map coordinate */
814

815
      if (strncasecmp(mapserv->request->ParamValues[i], "shape", 5) == 0) {
16✔
816
        mapserv->UseShapes = MS_TRUE;
×
817
      } else {
818
        tokens = msStringSplit(mapserv->request->ParamValues[i], ' ', &n);
16✔
819

820
        if (!tokens) {
16✔
821
          msSetError(MS_MEMERR, NULL, "msCGILoadForm()");
×
822
          return MS_FAILURE;
×
823
        }
824

825
        if (n != 2) {
16✔
826
          msSetError(MS_WEBERR, "Not enough arguments for mapxy.",
×
827
                     "msCGILoadForm()");
828
          msFreeCharArray(tokens, n);
×
829
          return MS_FAILURE;
×
830
        }
831

832
        GET_NUMERIC_NO_ERROR(tokens[0], mapserv->mappnt.x);
16✔
833
        FREE_TOKENS_ON_ERROR(2);
16✔
834
        GET_NUMERIC_NO_ERROR(tokens[1], mapserv->mappnt.y);
16✔
835
        FREE_TOKENS_ON_ERROR(2);
16✔
836

837
        msFreeCharArray(tokens, 2);
16✔
838

839
        if (mapserv->map->projection.proj &&
16✔
840
            !msProjIsGeographicCRS(&(mapserv->map->projection)) &&
×
841
            (mapserv->mappnt.x >= -180.0 && mapserv->mappnt.x <= 180.0) &&
×
842
            (mapserv->mappnt.y >= -90.0 && mapserv->mappnt.y <= 90.0)) {
×
843
          msProjectPoint(&(mapserv->map->latlon), &(mapserv->map->projection),
×
844
                         &mapserv->mappnt); /* point is a in lat/lon */
845
        }
846

847
        if (mapserv->CoordSource == NONE) { /* don't override previous settings
16✔
848
                                               (i.e. buffer or scale ) */
849
          mapserv->CoordSource = FROMUSERPNT;
16✔
850
          mapserv->QueryCoordSource = FROMUSERPNT;
16✔
851
        }
852
      }
853
      continue;
16✔
854
    }
855

856
    /*
857
    ** Query shape consisting of map or image coordinates. It's almost identical
858
    *processing so we'll do either in this block...
859
    */
860
    if (strcasecmp(mapserv->request->ParamNames[i], "mapshape") == 0 ||
476✔
861
        strcasecmp(mapserv->request->ParamNames[i], "imgshape") == 0) {
468✔
862
      if (strcasecmp(mapserv->request->ParamNames[i], "mapshape") == 0)
8✔
863
        mapserv->QueryCoordSource = FROMUSERSHAPE;
8✔
864
      else
865
        mapserv->QueryCoordSource = FROMIMGSHAPE;
×
866

867
      if (strchr(mapserv->request->ParamValues[i], '(') != NULL) { /* try WKT */
8✔
868
        if ((mapserv->map->query.shape =
4✔
869
                 msShapeFromWKT(mapserv->request->ParamValues[i])) == NULL) {
4✔
870
          msSetError(MS_WEBERR, "WKT parse failed for mapshape/imgshape.",
×
871
                     "msCGILoadForm()");
872
          return MS_FAILURE;
×
873
        }
874
      } else {
875
        lineObj line = {0, NULL};
4✔
876
        char **tmp = NULL;
877
        int n, j;
878

879
        tmp = msStringSplit(mapserv->request->ParamValues[i], ' ', &n);
4✔
880

881
        if (n % 2 != 0 || n < 8) { /* n must be even and be at least 8 */
4✔
882
          msSetError(MS_WEBERR,
×
883
                     "Malformed polygon geometry for mapshape/imgshape.",
884
                     "msCGILoadForm()");
885
          msFreeCharArray(tmp, n);
×
886
          return MS_FAILURE;
×
887
        }
888

889
        line.numpoints = n / 2;
4✔
890
        line.point =
4✔
891
            (pointObj *)msSmallMalloc(sizeof(pointObj) * line.numpoints);
4✔
892

893
        mapserv->map->query.shape = (shapeObj *)msSmallMalloc(sizeof(shapeObj));
4✔
894
        msInitShape(mapserv->map->query.shape);
4✔
895
        mapserv->map->query.shape->type = MS_SHAPE_POLYGON;
4✔
896

897
        for (j = 0; j < line.numpoints; j++) {
20✔
898
          line.point[j].x = atof(tmp[2 * j]);
16✔
899
          line.point[j].y = atof(tmp[2 * j + 1]);
16✔
900

901
          if (mapserv->QueryCoordSource == FROMUSERSHAPE &&
16✔
902
              mapserv->map->projection.proj &&
16✔
903
              !msProjIsGeographicCRS(&(mapserv->map->projection)) &&
×
904
              (line.point[j].x >= -180.0 && line.point[j].x <= 180.0) &&
×
905
              (line.point[j].y >= -90.0 && line.point[j].y <= 90.0)) {
×
906
            msProjectPoint(&(mapserv->map->latlon), &(mapserv->map->projection),
×
907
                           &line.point[j]); /* point is a in lat/lon */
908
          }
909
        }
910

911
        if (msAddLine(mapserv->map->query.shape, &line) == -1) {
4✔
912
          msFree(line.point);
×
913
          msFreeCharArray(tmp, n);
×
914
          return MS_FAILURE;
×
915
        }
916

917
        msFree(line.point);
4✔
918
        msFreeCharArray(tmp, n);
4✔
919
      }
920

921
      continue;
8✔
922
    }
923

924
    if (strcasecmp(mapserv->request->ParamNames[i], "img.x") ==
468✔
925
        0) { /* mouse click, in pieces */
926
      GET_NUMERIC(mapserv->request->ParamValues[i], mapserv->ImgPnt.x);
×
927
      if ((mapserv->ImgPnt.x > (2 * mapserv->map->maxsize)) ||
×
928
          (mapserv->ImgPnt.x < (-2 * mapserv->map->maxsize))) {
×
929
        msSetError(MS_WEBERR, "Coordinate out of range.", "msCGILoadForm()");
×
930
        return MS_FAILURE;
×
931
      }
932
      mapserv->CoordSource = FROMIMGPNT;
×
933
      mapserv->QueryCoordSource = FROMIMGPNT;
×
934
      continue;
×
935
    }
936
    if (strcasecmp(mapserv->request->ParamNames[i], "img.y") == 0) {
468✔
937
      GET_NUMERIC(mapserv->request->ParamValues[i], mapserv->ImgPnt.y);
×
938
      if ((mapserv->ImgPnt.y > (2 * mapserv->map->maxsize)) ||
×
939
          (mapserv->ImgPnt.y < (-2 * mapserv->map->maxsize))) {
×
940
        msSetError(MS_WEBERR, "Coordinate out of range.", "msCGILoadForm()");
×
941
        return MS_FAILURE;
×
942
      }
943
      mapserv->CoordSource = FROMIMGPNT;
×
944
      mapserv->QueryCoordSource = FROMIMGPNT;
×
945
      continue;
×
946
    }
947

948
    if (strcasecmp(mapserv->request->ParamNames[i], "imgxy") ==
468✔
949
        0) { /* mouse click, single variable */
950
      if (mapserv->CoordSource == FROMIMGPNT)
8✔
951
        continue;
×
952

953
      tokens = msStringSplit(mapserv->request->ParamValues[i], ' ', &n);
8✔
954

955
      if (!tokens) {
8✔
956
        msSetError(MS_MEMERR, NULL, "msCGILoadForm()");
×
957
        return MS_FAILURE;
×
958
      }
959

960
      if (n != 2) {
8✔
961
        msSetError(MS_WEBERR, "Not enough arguments for imgxy.",
×
962
                   "msCGILoadForm()");
963
        msFreeCharArray(tokens, n);
×
964
        return MS_FAILURE;
×
965
      }
966

967
      GET_NUMERIC_NO_ERROR(tokens[0], mapserv->ImgPnt.x);
8✔
968
      FREE_TOKENS_ON_ERROR(2);
8✔
969
      GET_NUMERIC_NO_ERROR(tokens[1], mapserv->ImgPnt.y);
8✔
970
      FREE_TOKENS_ON_ERROR(2);
8✔
971

972
      msFreeCharArray(tokens, 2);
8✔
973

974
      if ((mapserv->ImgPnt.x > (2 * mapserv->map->maxsize)) ||
8✔
975
          (mapserv->ImgPnt.x < (-2 * mapserv->map->maxsize)) ||
8✔
976
          (mapserv->ImgPnt.y > (2 * mapserv->map->maxsize)) ||
8✔
977
          (mapserv->ImgPnt.y < (-2 * mapserv->map->maxsize))) {
978
        msSetError(MS_WEBERR, "Reference map coordinate out of range.",
×
979
                   "msCGILoadForm()");
980
        return MS_FAILURE;
×
981
      }
982

983
      if (mapserv->CoordSource ==
8✔
984
          NONE) { /* override nothing since this parameter is usually used to
985
                     hold a default value */
986
        mapserv->CoordSource = FROMIMGPNT;
8✔
987
        mapserv->QueryCoordSource = FROMIMGPNT;
8✔
988
      }
989
      continue;
8✔
990
    }
991

992
    if (strcasecmp(mapserv->request->ParamNames[i], "imgbox") ==
460✔
993
        0) { /* selection box (eg. mouse drag) */
994
      tokens = msStringSplit(mapserv->request->ParamValues[i], ' ', &n);
×
995

996
      if (!tokens) {
×
997
        msSetError(MS_MEMERR, NULL, "msCGILoadForm()");
×
998
        return MS_FAILURE;
×
999
      }
1000

1001
      if (n != 4) {
×
1002
        msSetError(MS_WEBERR, "Not enough arguments for imgbox.",
×
1003
                   "msCGILoadForm()");
1004
        msFreeCharArray(tokens, n);
×
1005
        return MS_FAILURE;
×
1006
      }
1007

1008
      GET_NUMERIC_NO_ERROR(tokens[0], mapserv->ImgBox.minx);
×
1009
      FREE_TOKENS_ON_ERROR(4);
×
1010
      GET_NUMERIC_NO_ERROR(tokens[1], mapserv->ImgBox.miny);
×
1011
      FREE_TOKENS_ON_ERROR(4);
×
1012
      GET_NUMERIC_NO_ERROR(tokens[2], mapserv->ImgBox.maxx);
×
1013
      FREE_TOKENS_ON_ERROR(4);
×
1014
      GET_NUMERIC_NO_ERROR(tokens[3], mapserv->ImgBox.maxy);
×
1015
      FREE_TOKENS_ON_ERROR(4);
×
1016

1017
      msFreeCharArray(tokens, 4);
×
1018

1019
      if ((mapserv->ImgBox.minx != mapserv->ImgBox.maxx) &&
×
1020
          (mapserv->ImgBox.miny !=
×
1021
           mapserv->ImgBox.maxy)) { /* must not degenerate into a point */
×
1022
        mapserv->CoordSource = FROMIMGBOX;
×
1023
        mapserv->QueryCoordSource = FROMIMGBOX;
×
1024
      }
1025
      continue;
×
1026
    }
1027

1028
    if (strcasecmp(mapserv->request->ParamNames[i], "ref.x") ==
460✔
1029
        0) { /* mouse click in reference image, in pieces */
1030
      GET_NUMERIC(mapserv->request->ParamValues[i], mapserv->RefPnt.x);
×
1031
      if ((mapserv->RefPnt.x > (2 * mapserv->map->maxsize)) ||
×
1032
          (mapserv->RefPnt.x < (-2 * mapserv->map->maxsize))) {
×
1033
        msSetError(MS_WEBERR, "Coordinate out of range.", "msCGILoadForm()");
×
1034
        return MS_FAILURE;
×
1035
      }
1036
      mapserv->CoordSource = FROMREFPNT;
×
1037
      continue;
×
1038
    }
1039
    if (strcasecmp(mapserv->request->ParamNames[i], "ref.y") == 0) {
460✔
1040
      GET_NUMERIC(mapserv->request->ParamValues[i], mapserv->RefPnt.y);
×
1041
      if ((mapserv->RefPnt.y > (2 * mapserv->map->maxsize)) ||
×
1042
          (mapserv->RefPnt.y < (-2 * mapserv->map->maxsize))) {
×
1043
        msSetError(MS_WEBERR, "Coordinate out of range.", "msCGILoadForm()");
×
1044
        return MS_FAILURE;
×
1045
      }
1046
      mapserv->CoordSource = FROMREFPNT;
×
1047
      continue;
×
1048
    }
1049

1050
    if (strcasecmp(mapserv->request->ParamNames[i], "refxy") ==
460✔
1051
        0) { /* mouse click in reference image, single variable */
1052
      tokens = msStringSplit(mapserv->request->ParamValues[i], ' ', &n);
×
1053

1054
      if (!tokens) {
×
1055
        msSetError(MS_MEMERR, NULL, "msCGILoadForm()");
×
1056
        return MS_FAILURE;
×
1057
      }
1058

1059
      if (n != 2) {
×
1060
        msSetError(MS_WEBERR, "Not enough arguments for imgxy.",
×
1061
                   "msCGILoadForm()");
1062
        msFreeCharArray(tokens, n);
×
1063
        return MS_FAILURE;
×
1064
      }
1065

1066
      GET_NUMERIC_NO_ERROR(tokens[0], mapserv->RefPnt.x);
×
1067
      FREE_TOKENS_ON_ERROR(2);
×
1068
      GET_NUMERIC_NO_ERROR(tokens[1], mapserv->RefPnt.y);
×
1069
      FREE_TOKENS_ON_ERROR(2);
×
1070

1071
      msFreeCharArray(tokens, 2);
×
1072

1073
      if ((mapserv->RefPnt.x > (2 * mapserv->map->maxsize)) ||
×
1074
          (mapserv->RefPnt.x < (-2 * mapserv->map->maxsize)) ||
×
1075
          (mapserv->RefPnt.y > (2 * mapserv->map->maxsize)) ||
×
1076
          (mapserv->RefPnt.y < (-2 * mapserv->map->maxsize))) {
1077
        msSetError(MS_WEBERR, "Reference map coordinate out of range.",
×
1078
                   "msCGILoadForm()");
1079
        return MS_FAILURE;
×
1080
      }
1081

1082
      mapserv->CoordSource = FROMREFPNT;
×
1083
      continue;
×
1084
    }
1085

1086
    if (strcasecmp(mapserv->request->ParamNames[i], "buffer") ==
460✔
1087
        0) { /* radius (map units), actually 1/2 square side */
1088
      GET_NUMERIC(mapserv->request->ParamValues[i], mapserv->Buffer);
×
1089
      mapserv->CoordSource = FROMBUF;
×
1090
      mapserv->QueryCoordSource = FROMUSERPNT;
×
1091
      continue;
×
1092
    }
1093

1094
    if (strcasecmp(mapserv->request->ParamNames[i], "scale") == 0 ||
460✔
1095
        strcasecmp(mapserv->request->ParamNames[i], "scaledenom") ==
460✔
1096
            0) { /* scale for new map */
1097
      GET_NUMERIC(mapserv->request->ParamValues[i], mapserv->ScaleDenom);
×
1098
      if (mapserv->ScaleDenom <= 0) {
×
1099
        msSetError(MS_WEBERR, "Scale out of range.", "msCGILoadForm()");
×
1100
        return MS_FAILURE;
×
1101
      }
1102
      mapserv->CoordSource = FROMSCALE;
×
1103
      mapserv->QueryCoordSource = FROMUSERPNT;
×
1104
      continue;
×
1105
    }
1106

1107
    if (strcasecmp(mapserv->request->ParamNames[i], "imgsize") ==
460✔
1108
        0) { /* size of existing image (pixels) */
1109
      tokens = msStringSplit(mapserv->request->ParamValues[i], ' ', &n);
8✔
1110

1111
      if (!tokens) {
8✔
1112
        msSetError(MS_MEMERR, NULL, "msCGILoadForm()");
×
1113
        return MS_FAILURE;
×
1114
      }
1115

1116
      if (n != 2) {
8✔
1117
        msSetError(MS_WEBERR, "Not enough arguments for imgsize.",
×
1118
                   "msCGILoadForm()");
1119
        msFreeCharArray(tokens, n);
×
1120
        return MS_FAILURE;
×
1121
      }
1122

1123
      GET_NUMERIC_NO_ERROR(tokens[0], tmpval);
8✔
1124
      FREE_TOKENS_ON_ERROR(2);
8✔
1125
      mapserv->ImgCols = (int)tmpval;
8✔
1126
      GET_NUMERIC_NO_ERROR(tokens[1], tmpval);
8✔
1127
      FREE_TOKENS_ON_ERROR(2);
8✔
1128
      mapserv->ImgRows = (int)tmpval;
8✔
1129

1130
      msFreeCharArray(tokens, 2);
8✔
1131

1132
      if (mapserv->ImgCols > mapserv->map->maxsize ||
8✔
1133
          mapserv->ImgRows > mapserv->map->maxsize || mapserv->ImgCols <= 0 ||
8✔
1134
          mapserv->ImgRows <= 0) {
1135
        msSetError(MS_WEBERR, "Image size out of range.", "msCGILoadForm()");
×
1136
        return MS_FAILURE;
×
1137
      }
1138

1139
      continue;
8✔
1140
    }
1141

1142
    if (strcasecmp(mapserv->request->ParamNames[i], "resolution") == 0) {
452✔
1143
      GET_NUMERIC(mapserv->request->ParamValues[i], tmpval);
×
1144
      if (tmpval < MS_RESOLUTION_MIN || tmpval > MS_RESOLUTION_MAX) {
×
1145
        msSetError(MS_WEBERR, "Resolution value out of range.",
×
1146
                   "msCGILoadForm()");
1147
        return MS_FAILURE;
×
1148
      }
1149
      mapserv->map->resolution = (int)tmpval;
×
1150
      continue;
×
1151
    }
1152

1153
    // map.imagetype and map_imagetype are for backwards compatibility and may
1154
    // be removed in the future
1155
    if (strcasecmp(mapserv->request->ParamNames[i], "imagetype") == 0 ||
452✔
1156
        strcasecmp(mapserv->request->ParamNames[i], "map.imagetype") == 0 ||
452✔
1157
        strcasecmp(mapserv->request->ParamNames[i], "map_imagetype") == 0) {
438✔
1158

1159
      const char *imagetype_validation_pattern =
1160
          msLookupHashTable(&(mapserv->map->web.validation), "imagetype");
14✔
1161
      if (imagetype_validation_pattern != NULL &&
14✔
1162
          msEvalRegex(imagetype_validation_pattern,
×
1163
                      mapserv->request->ParamValues[i]) !=
×
1164
              MS_TRUE) { /* optional check */
1165
        msSetError(MS_WEBERR, "Imagetype value fails to validate.",
×
1166
                   "msCGILoadMap()");
1167
        return MS_FAILURE;
×
1168
      }
1169

1170
      outputFormatObj *format =
1171
          msSelectOutputFormat(mapserv->map, mapserv->request->ParamValues[i]);
14✔
1172
      if (format == NULL) {
14✔
1173
        msSetError(MS_WEBERR, "Invalid imagetype value.\n", "msCGILoadForm()");
1✔
1174
        return MS_FAILURE;
1✔
1175
      } else {
1176
        msFree((char *)mapserv->map->imagetype);
13✔
1177
        mapserv->map->imagetype = msStrdup(mapserv->request->ParamValues[i]);
13✔
1178
        msApplyOutputFormat(&(mapserv->map->outputformat), format,
13✔
1179
                            MS_NOOVERRIDE);
1180
      }
1181
    }
1182

1183
    if (strcasecmp(mapserv->request->ParamNames[i], "tilesize") ==
451✔
1184
        0) { /* size of existing image (pixels) */
1185
      tokens = msStringSplit(mapserv->request->ParamValues[i], ' ', &n);
1✔
1186

1187
      if (!tokens) {
1✔
1188
        msSetError(MS_MEMERR, NULL, "msCGILoadForm()");
×
1189
        return MS_FAILURE;
×
1190
      }
1191

1192
      if (n != 2) {
1✔
1193
        msSetError(MS_WEBERR, "Not enough arguments for tilesize.",
×
1194
                   "msCGILoadForm()");
1195
        msFreeCharArray(tokens, n);
×
1196
        return MS_FAILURE;
×
1197
      }
1198

1199
      GET_NUMERIC_NO_ERROR(tokens[0], tmpval);
1✔
1200
      FREE_TOKENS_ON_ERROR(2);
1✔
1201
      mapserv->TileWidth = (int)tmpval;
1✔
1202
      GET_NUMERIC_NO_ERROR(tokens[1], tmpval);
1✔
1203
      FREE_TOKENS_ON_ERROR(2);
1✔
1204
      mapserv->TileHeight = (int)tmpval;
1✔
1205

1206
      msFreeCharArray(tokens, 2);
1✔
1207

1208
      if (mapserv->TileWidth > mapserv->map->maxsize ||
1✔
1209
          mapserv->TileHeight > mapserv->map->maxsize ||
1✔
1210
          mapserv->TileWidth <= 0 || mapserv->TileHeight <= 0) {
1✔
1211
        msSetError(MS_WEBERR, "Tile size out of range.", "msCGILoadForm()");
×
1212
        return MS_FAILURE;
×
1213
      }
1214

1215
      continue;
1✔
1216
    }
1217

1218
    /* size of new map (pixels), map.size/map_size are included for backwards
1219
     * compatibility and may be removed in future release */
1220
    if (strcasecmp(mapserv->request->ParamNames[i], "mapsize") == 0 ||
450✔
1221
        strcasecmp(mapserv->request->ParamNames[i], "map.size") == 0 ||
448✔
1222
        strcasecmp(mapserv->request->ParamNames[i], "map_size") == 0) {
448✔
1223
      tokens = msStringSplit(mapserv->request->ParamValues[i], ' ', &n);
2✔
1224

1225
      if (!tokens) {
2✔
1226
        msSetError(MS_MEMERR, NULL, "msCGILoadForm()");
×
1227
        return MS_FAILURE;
×
1228
      }
1229

1230
      if (n != 2) {
2✔
1231
        msSetError(MS_WEBERR, "Not enough arguments for mapsize.",
×
1232
                   "msCGILoadForm()");
1233
        msFreeCharArray(tokens, n);
×
1234
        return MS_FAILURE;
×
1235
      }
1236

1237
      GET_NUMERIC_NO_ERROR(tokens[0], tmpval);
2✔
1238
      FREE_TOKENS_ON_ERROR(2);
2✔
1239
      mapserv->map->width = (int)tmpval;
2✔
1240
      GET_NUMERIC_NO_ERROR(tokens[1], tmpval);
2✔
1241
      FREE_TOKENS_ON_ERROR(2);
2✔
1242
      mapserv->map->height = (int)tmpval;
2✔
1243

1244
      msFreeCharArray(tokens, 2);
2✔
1245

1246
      if (mapserv->map->width > mapserv->map->maxsize ||
2✔
1247
          mapserv->map->height > mapserv->map->maxsize ||
2✔
1248
          mapserv->map->width <= 0 || mapserv->map->height <= 0) {
2✔
1249
        msSetError(MS_WEBERR, "Image size out of range.", "msCGILoadForm()");
×
1250
        return MS_FAILURE;
×
1251
      }
1252
      continue;
2✔
1253
    }
1254

1255
    if (strncasecmp(mapserv->request->ParamNames[i], "layers", 6) ==
448✔
1256
        0) { /* turn a set of layers, delimited by spaces, on */
1257

1258
      /* If layers=all then turn on all layers */
1259
      if (strcasecmp(mapserv->request->ParamValues[i], "all") == 0) {
26✔
1260
        int l;
1261

1262
        /* Reset NumLayers=0. If individual layers were already selected then
1263
         * free the previous values.  */
1264
        for (l = 0; l < mapserv->NumLayers; l++)
20✔
1265
          msFree(mapserv->Layers[l]);
×
1266
        mapserv->NumLayers = 0;
20✔
1267

1268
        for (mapserv->NumLayers = 0;
20✔
1269
             mapserv->NumLayers < mapserv->map->numlayers;
65✔
1270
             mapserv->NumLayers++) {
45✔
1271
          if (msGrowMapservLayers(mapserv) == MS_FAILURE)
45✔
1272
            return MS_FAILURE;
1273

1274
          if (GET_LAYER(mapserv->map, mapserv->NumLayers)->name) {
45✔
1275
            mapserv->Layers[mapserv->NumLayers] =
45✔
1276
                msStrdup(GET_LAYER(mapserv->map, mapserv->NumLayers)->name);
45✔
1277
          } else {
1278
            mapserv->Layers[mapserv->NumLayers] = msStrdup("");
×
1279
          }
1280
        }
1281
      } else {
1282
        int num_layers = 0, l;
6✔
1283
        char **layers = NULL;
1284

1285
        layers =
1286
            msStringSplit(mapserv->request->ParamValues[i], ' ', &(num_layers));
6✔
1287
        for (l = 0; l < num_layers; l++) {
13✔
1288
          if (msGrowMapservLayers(mapserv) == MS_FAILURE) {
7✔
1289
            msFreeCharArray(layers, num_layers);
×
1290
            return MS_FAILURE;
×
1291
          }
1292
          mapserv->Layers[mapserv->NumLayers++] = msStrdup(layers[l]);
7✔
1293
        }
1294

1295
        msFreeCharArray(layers, num_layers);
6✔
1296
        num_layers = 0;
1297
      }
1298

1299
      continue;
26✔
1300
    }
1301

1302
    if (strncasecmp(mapserv->request->ParamNames[i], "layer", 5) ==
422✔
1303
        0) { /* turn a single layer/group on */
1304
      if (msGrowMapservLayers(mapserv) == MS_FAILURE)
26✔
1305
        return MS_FAILURE;
1306
      mapserv->Layers[mapserv->NumLayers] =
52✔
1307
          msStrdup(mapserv->request->ParamValues[i]);
26✔
1308
      mapserv->NumLayers++;
26✔
1309
      continue;
26✔
1310
    }
1311

1312
    if (strcasecmp(mapserv->request->ParamNames[i], "qlayer") ==
396✔
1313
        0) { /* layer to query (i.e search) */
1314
      mapserv->QueryLayer = msStrdup(mapserv->request->ParamValues[i]);
54✔
1315
      continue;
54✔
1316
    }
1317

1318
    if (strcasecmp(mapserv->request->ParamNames[i], "qitem") ==
342✔
1319
        0) { /* attribute to query on (optional) */
1320
      mapserv->QueryItem = msStrdup(mapserv->request->ParamValues[i]);
11✔
1321
      continue;
11✔
1322
    }
1323

1324
    if (strcasecmp(mapserv->request->ParamNames[i], "qstring") ==
331✔
1325
        0) { /* attribute query string */
1326
      mapserv->QueryString = msStrdup(mapserv->request->ParamValues[i]);
15✔
1327
      continue;
15✔
1328
    }
1329

1330
    if (strcasecmp(mapserv->request->ParamNames[i], "qformat") ==
316✔
1331
        0) { /* format to apply to query results (shortcut instead of having to
1332
                use "map.web=QUERYFORMAT+foo") */
1333
      if (mapserv->map->web.queryformat)
20✔
1334
        free(mapserv->map->web.queryformat); /* avoid leak */
20✔
1335
      mapserv->map->web.queryformat =
40✔
1336
          msStrdup(mapserv->request->ParamValues[i]);
20✔
1337
      continue;
20✔
1338
    }
1339

1340
    if (strcasecmp(mapserv->request->ParamNames[i], "slayer") ==
296✔
1341
        0) { /* layer to select (for feature based search) */
1342
      mapserv->SelectLayer = msStrdup(mapserv->request->ParamValues[i]);
4✔
1343
      continue;
4✔
1344
    }
1345

1346
    if (strcasecmp(mapserv->request->ParamNames[i], "shapeindex") ==
292✔
1347
        0) { /* used for index queries */
1348
      GET_NUMERIC(mapserv->request->ParamValues[i], tmpval);
4✔
1349
      mapserv->ShapeIndex = (int)tmpval;
4✔
1350
      continue;
4✔
1351
    }
1352
    if (strcasecmp(mapserv->request->ParamNames[i], "tileindex") == 0) {
288✔
1353
      GET_NUMERIC(mapserv->request->ParamValues[i], tmpval);
×
1354
      mapserv->TileIndex = (int)tmpval;
×
1355
      continue;
×
1356
    }
1357

1358
    /* --------------------------------------------------------------------
1359
     *   The following code is used to support mode=tile
1360
     * -------------------------------------------------------------------- */
1361

1362
    if (strcasecmp(mapserv->request->ParamNames[i], "tilemode") == 0) {
288✔
1363
      /* currently, only valid tilemode is "spheremerc" */
1364
      if (strcasecmp(mapserv->request->ParamValues[i], "gmap") == 0) {
5✔
1365
        mapserv->TileMode = TILE_GMAP;
5✔
1366
      } else if (strcasecmp(mapserv->request->ParamValues[i], "ve") == 0) {
×
1367
        mapserv->TileMode = TILE_VE;
×
1368
      } else {
1369
        msSetError(MS_WEBERR, "Invalid tilemode. Use one of: gmap, ve",
×
1370
                   "msCGILoadForm()");
1371
        return MS_FAILURE;
×
1372
      }
1373
      continue;
5✔
1374
    }
1375

1376
    if (strcasecmp(mapserv->request->ParamNames[i], "tile") == 0) {
283✔
1377

1378
      if (strlen(mapserv->request->ParamValues[i]) < 1) {
5✔
1379
        msSetError(MS_WEBERR, "Empty tile parameter.", "msCGILoadForm()");
×
1380
        return MS_FAILURE;
×
1381
      }
1382
      mapserv->CoordSource = FROMTILE;
5✔
1383
      mapserv->TileCoords = msStrdup(mapserv->request->ParamValues[i]);
5✔
1384

1385
      continue;
5✔
1386
    }
1387

1388
  } /* next parameter */
1389

1390
  if (mapserv->Mode == ZOOMIN) {
127✔
1391
    mapserv->ZoomDirection = 1;
×
1392
    mapserv->Mode = BROWSE;
×
1393
  }
1394
  if (mapserv->Mode == ZOOMOUT) {
127✔
1395
    mapserv->ZoomDirection = -1;
×
1396
    mapserv->Mode = BROWSE;
×
1397
  }
1398

1399
  if (mapserv->ZoomSize !=
127✔
1400
      0) { /* use direction and magnitude to calculate zoom */
1401
    if (mapserv->ZoomDirection == 0) {
×
1402
      mapserv->fZoom = 1;
×
1403
    } else {
1404
      mapserv->fZoom = mapserv->ZoomSize * mapserv->ZoomDirection;
×
1405
      if (mapserv->fZoom < 0)
×
1406
        mapserv->fZoom = 1.0 / MS_ABS(mapserv->fZoom);
×
1407
    }
1408
  } else { /* use single value for zoom */
1409
    if ((mapserv->Zoom >= -1) && (mapserv->Zoom <= 1)) {
127✔
1410
      mapserv->fZoom = 1; /* pan */
127✔
1411
    } else {
1412
      if (mapserv->Zoom < 0)
×
1413
        mapserv->fZoom = 1.0 / MS_ABS(mapserv->Zoom);
×
1414
      else
1415
        mapserv->fZoom = mapserv->Zoom;
×
1416
    }
1417
  }
1418

1419
  if (mapserv->ImgRows == -1)
127✔
1420
    mapserv->ImgRows = mapserv->map->height;
119✔
1421
  if (mapserv->ImgCols == -1)
127✔
1422
    mapserv->ImgCols = mapserv->map->width;
119✔
1423
  if (mapserv->map->height == -1)
127✔
1424
    mapserv->map->height = mapserv->ImgRows;
62✔
1425
  if (mapserv->map->width == -1)
127✔
1426
    mapserv->map->width = mapserv->ImgCols;
62✔
1427
  return MS_SUCCESS;
1428
}
1429

1430
int setExtentFromShapes(mapservObj *mapserv) {
×
1431
  double dx, dy, cellsize;
1432

1433
  rectObj tmpext = {-1.0, -1.0, -1.0, -1.0};
×
1434
  pointObj tmppnt = {-1.0, -1.0, -1.0, -1.0};
1435

1436
  msGetQueryResultBounds(mapserv->map, &(tmpext));
×
1437

1438
  dx = tmpext.maxx - tmpext.minx;
×
1439
  dy = tmpext.maxy - tmpext.miny;
×
1440

1441
  tmppnt.x = (tmpext.maxx + tmpext.minx) / 2;
×
1442
  tmppnt.y = (tmpext.maxy + tmpext.miny) / 2;
×
1443
  tmpext.minx -= dx * EXTENT_PADDING / 2.0;
×
1444
  tmpext.maxx += dx * EXTENT_PADDING / 2.0;
×
1445
  tmpext.miny -= dy * EXTENT_PADDING / 2.0;
×
1446
  tmpext.maxy += dy * EXTENT_PADDING / 2.0;
×
1447

1448
  if (mapserv->ScaleDenom !=
×
1449
      0) { /* apply the scale around the center point (tmppnt) */
1450
    cellsize = (mapserv->ScaleDenom / mapserv->map->resolution) /
×
1451
               msInchesPerUnit(mapserv->map->units,
×
1452
                               0); /* user supplied a point and a scale */
1453
    tmpext.minx = tmppnt.x - cellsize * mapserv->map->width / 2.0;
×
1454
    tmpext.miny = tmppnt.y - cellsize * mapserv->map->height / 2.0;
×
1455
    tmpext.maxx = tmppnt.x + cellsize * mapserv->map->width / 2.0;
×
1456
    tmpext.maxy = tmppnt.y + cellsize * mapserv->map->height / 2.0;
×
1457
  } else if (mapserv->Buffer !=
×
1458
             0) { /* apply the buffer around the center point (tmppnt) */
1459
    tmpext.minx = tmppnt.x - mapserv->Buffer;
×
1460
    tmpext.miny = tmppnt.y - mapserv->Buffer;
×
1461
    tmpext.maxx = tmppnt.x + mapserv->Buffer;
×
1462
    tmpext.maxy = tmppnt.y + mapserv->Buffer;
×
1463
  }
1464

1465
  /* in case we don't get  usable extent at this point (i.e. single point
1466
   * result) */
1467
  if (!MS_VALID_EXTENT(tmpext)) {
×
1468
    if (mapserv->map->web.minscaledenom >
×
1469
        0) { /* try web object minscale first */
1470
      cellsize = (mapserv->map->web.minscaledenom / mapserv->map->resolution) /
×
1471
                 msInchesPerUnit(mapserv->map->units,
×
1472
                                 0); /* user supplied a point and a scale */
1473
      tmpext.minx = tmppnt.x - cellsize * mapserv->map->width / 2.0;
×
1474
      tmpext.miny = tmppnt.y - cellsize * mapserv->map->height / 2.0;
×
1475
      tmpext.maxx = tmppnt.x + cellsize * mapserv->map->width / 2.0;
×
1476
      tmpext.maxy = tmppnt.y + cellsize * mapserv->map->height / 2.0;
×
1477
    } else {
1478
      msSetError(MS_WEBERR,
×
1479
                 "No way to generate a valid map extent from selected shapes.",
1480
                 "mapserv()");
1481
      return MS_FAILURE;
×
1482
    }
1483
  }
1484

1485
  mapserv->mappnt = tmppnt;
×
1486
  mapserv->map->extent = mapserv->RawExt = tmpext; /* save unadjusted extent */
×
1487

1488
  return MS_SUCCESS;
×
1489
}
1490

1491
/* FIX: NEED ERROR CHECKING HERE FOR IMGPNT or MAPPNT */
1492
void setCoordinate(mapservObj *mapserv) {
8✔
1493
  double cellx, celly;
1494

1495
  cellx =
8✔
1496
      MS_CELLSIZE(mapserv->ImgExt.minx, mapserv->ImgExt.maxx, mapserv->ImgCols);
8✔
1497
  celly =
8✔
1498
      MS_CELLSIZE(mapserv->ImgExt.miny, mapserv->ImgExt.maxy, mapserv->ImgRows);
8✔
1499

1500
  mapserv->mappnt.x =
8✔
1501
      MS_IMAGE2MAP_X(mapserv->ImgPnt.x, mapserv->ImgExt.minx, cellx);
8✔
1502
  mapserv->mappnt.y =
8✔
1503
      MS_IMAGE2MAP_Y(mapserv->ImgPnt.y, mapserv->ImgExt.maxy, celly);
8✔
1504

1505
  return;
8✔
1506
}
1507

1508
int msCGIDispatchBrowseRequest(mapservObj *mapserv) {
3✔
1509
  char *template = NULL;
1510
  int i, status;
1511
  for (i = 0; i < mapserv->request->NumParams;
9✔
1512
       i++) /* find the template param value */
6✔
1513
    if (strcasecmp(mapserv->request->ParamNames[i], "template") == 0)
6✔
1514
      template = mapserv->request->ParamValues[i];
1✔
1515

1516
  if ((!mapserv->map->web.template) &&
3✔
1517
      (template == NULL || (strcasecmp(template, "openlayers") != 0))) {
1✔
1518
    msSetError(MS_WEBERR,
2✔
1519
               "Traditional BROWSE mode requires a TEMPLATE in the WEB "
1520
               "section, but none was provided.",
1521
               "mapserv()");
1522
    return MS_FAILURE;
2✔
1523
  }
1524

1525
  if (mapserv->QueryFile) {
1✔
1526
    status = msLoadQuery(mapserv->map, mapserv->QueryFile);
×
1527
    if (status != MS_SUCCESS)
×
1528
      return MS_FAILURE;
1529
  }
1530

1531
  status = setExtent(mapserv);
1✔
1532
  if (status != MS_SUCCESS)
1✔
1533
    return MS_FAILURE;
1534
  status = checkWebScale(mapserv);
1✔
1535
  if (status != MS_SUCCESS)
1✔
1536
    return MS_FAILURE;
1537

1538
  /* -------------------------------------------------------------------- */
1539
  /*      generate map, legend, scalebar and reference images.             */
1540
  /* -------------------------------------------------------------------- */
1541
  if (msGenerateImages(mapserv, MS_FALSE, MS_TRUE) != MS_SUCCESS)
1✔
1542
    return MS_FAILURE;
1543

1544
  if ((template != NULL) && (strcasecmp(template, "openlayers") == 0)) {
1✔
1545
    msIO_setHeader("Content-Type", "text/html");
1✔
1546
    msIO_sendHeaders();
1✔
1547
    if (msReturnOpenLayersPage(mapserv) != MS_SUCCESS)
1✔
1548
      return MS_FAILURE;
1549
  } else if (mapserv->QueryFile) {
×
1550
    if (msReturnTemplateQuery(mapserv, mapserv->map->web.queryformat, NULL) !=
×
1551
        MS_SUCCESS)
1552
      return MS_FAILURE;
1553
  } else {
1554
    if (TEMPLATE_TYPE(mapserv->map->web.template) ==
×
1555
        MS_FILE) { /* if thers's an html template, then use it */
1556
      if (mapserv->sendheaders) {
×
1557
        msIO_setHeader("Content-Type", "%s",
×
1558
                       mapserv->map->web.browseformat); /* write MIME header */
1559
        msIO_sendHeaders();
×
1560
      }
1561
      if (msReturnPage(mapserv, mapserv->map->web.template, BROWSE, NULL) !=
×
1562
          MS_SUCCESS)
1563
        return MS_FAILURE;
1564
    } else {
1565
      if (msReturnURL(mapserv, mapserv->map->web.template, BROWSE) !=
×
1566
          MS_SUCCESS)
1567
        return MS_FAILURE;
1568
    }
1569
  }
1570
  return MS_SUCCESS;
1571
}
1572

1573
int msCGIDispatchCoordinateRequest(mapservObj *mapserv) {
×
1574
  setCoordinate(mapserv); /* mouse click => map coord */
×
1575
  msIO_printf("Your \"<i>click</i>\" corresponds to (approximately): (%g, %g).",
×
1576
              mapserv->mappnt.x, mapserv->mappnt.y);
1577

1578
  if (mapserv->map->projection.proj != NULL &&
×
1579
      !msProjIsGeographicCRS(&(mapserv->map->projection))) {
×
1580
    pointObj p = mapserv->mappnt;
×
1581
    msProjectPoint(&(mapserv->map->projection), &(mapserv->map->latlon), &p);
×
1582
    msIO_printf("Computed lat/lon value is (%g, %g).\n", p.x, p.y);
×
1583
  }
1584
  return MS_SUCCESS;
×
1585
}
1586

1587
int msCGIDispatchQueryRequest(mapservObj *mapserv) {
76✔
1588
  int status, i, j;
1589
  char buffer[1024];
1590
  if (mapserv->QueryFile) { /* already got a completed query */
76✔
1591
    status = msLoadQuery(mapserv->map, mapserv->QueryFile);
×
1592
    if (status != MS_SUCCESS)
×
1593
      return MS_FAILURE;
1594
  } else {
1595

1596
    if ((mapserv->QueryLayerIndex =
76✔
1597
             msGetLayerIndex(mapserv->map, mapserv->QueryLayer)) !=
76✔
1598
        -1) /* force the query layer on */
1599
      GET_LAYER(mapserv->map, mapserv->QueryLayerIndex)->status = MS_ON;
54✔
1600

1601
    switch (mapserv->Mode) {
76✔
1602
    case ITEMFEATUREQUERY:
×
1603
    case ITEMFEATURENQUERY:
1604
      if ((mapserv->SelectLayerIndex =
×
1605
               msGetLayerIndex(mapserv->map, mapserv->SelectLayer)) ==
×
1606
          -1) { /* force the selection layer on */
1607
        msSetError(MS_WEBERR,
×
1608
                   "Selection layer not set or references an invalid layer.",
1609
                   "mapserv()");
1610
        return MS_FAILURE;
×
1611
      }
1612
      GET_LAYER(mapserv->map, mapserv->SelectLayerIndex)->status = MS_ON;
×
1613

1614
      /* validate the qstring parameter */
1615
      if (msValidateParameter(
×
1616
              mapserv->QueryString,
×
1617
              msLookupHashTable(
1618
                  &(GET_LAYER(mapserv->map, mapserv->SelectLayerIndex)
×
1619
                        ->validation),
1620
                  "qstring"),
1621
              msLookupHashTable(&(mapserv->map->web.validation), "qstring"),
×
1622
              NULL, NULL) != MS_SUCCESS) {
1623
        msSetError(MS_WEBERR, "Parameter 'qstring' value fails to validate.",
×
1624
                   "mapserv()");
1625
        return MS_FAILURE;
×
1626
      }
1627

1628
      if (mapserv->QueryCoordSource != NONE && !mapserv->UseShapes)
×
1629
        if (MS_SUCCESS != setExtent(mapserv)) /* set user area of interest */
×
1630
          return MS_FAILURE;
1631

1632
      mapserv->map->query.type = MS_QUERY_BY_FILTER;
×
1633
      if (mapserv->QueryItem)
×
1634
        mapserv->map->query.filteritem = msStrdup(mapserv->QueryItem);
×
1635
      if (mapserv->QueryString) {
×
1636
        msInitExpression(&mapserv->map->query.filter);
×
1637
        msLoadExpressionString(&mapserv->map->query.filter,
×
1638
                               mapserv->QueryString);
×
1639
      }
1640

1641
      mapserv->map->query.rect = mapserv->map->extent;
×
1642

1643
      mapserv->map->query.mode = MS_QUERY_MULTIPLE;
×
1644
      if (mapserv->Mode == ITEMFEATUREQUERY)
×
1645
        mapserv->map->query.mode = MS_QUERY_SINGLE;
×
1646

1647
      mapserv->map->query.layer = mapserv->QueryLayerIndex;
×
1648
      mapserv->map->query.slayer =
×
1649
          mapserv->SelectLayerIndex; /* this will trigger the feature query
×
1650
                                        eventually */
1651
      break;
×
1652
    case FEATUREQUERY:
4✔
1653
    case FEATURENQUERY:
1654
      if ((mapserv->SelectLayerIndex =
4✔
1655
               msGetLayerIndex(mapserv->map, mapserv->SelectLayer)) ==
4✔
1656
          -1) { /* force the selection layer on */
1657
        msSetError(MS_WEBERR,
×
1658
                   "Selection layer not set or references an invalid layer.",
1659
                   "mapserv()");
1660
        return MS_FAILURE;
×
1661
      }
1662
      GET_LAYER(mapserv->map, mapserv->SelectLayerIndex)->status = MS_ON;
4✔
1663

1664
      if (mapserv->Mode == FEATUREQUERY) {
4✔
1665
        switch (mapserv->QueryCoordSource) {
4✔
1666
        case FROMIMGPNT:
×
1667
          mapserv->map->extent =
×
1668
              mapserv->ImgExt; /* use the existing map extent */
1669
          setCoordinate(mapserv);
×
1670
          break;
×
1671
        case FROMUSERPNT:
1672
          break;
1673
        default:
×
1674
          msSetError(
×
1675
              MS_WEBERR,
1676
              "No way to perform the initial search, not enough information.",
1677
              "mapserv()");
1678
          return MS_FAILURE;
×
1679
          break;
1680
        }
1681

1682
        mapserv->map->query.type = MS_QUERY_BY_POINT;
4✔
1683
      } else { /* FEATURENQUERY */
1684
        switch (mapserv->QueryCoordSource) {
×
1685
        case FROMIMGPNT:
×
1686
          mapserv->map->extent =
×
1687
              mapserv->ImgExt; /* use the existing map extent */
1688
          setCoordinate(mapserv);
×
1689
          mapserv->map->query.type = MS_QUERY_BY_POINT;
×
1690
          break;
×
1691
        case FROMIMGBOX:
1692
          /* TODO: this option was present but with no code to leverage the
1693
           * image box... */
1694
          break;
1695
        case FROMUSERPNT:
×
1696
          mapserv->map->query.type = MS_QUERY_BY_POINT;
×
1697
          break;
×
1698
        default:
×
1699
          if (MS_SUCCESS != setExtent(mapserv)) {
×
1700
            return MS_FAILURE;
1701
          }
1702
          mapserv->map->query.type = MS_QUERY_BY_RECT;
×
1703
          break;
×
1704
        }
1705
      }
1706

1707
      mapserv->map->query.mode = MS_QUERY_MULTIPLE;
4✔
1708

1709
      mapserv->map->query.rect = mapserv->map->extent;
4✔
1710
      mapserv->map->query.point = mapserv->mappnt;
4✔
1711
      mapserv->map->query.buffer = mapserv->Buffer;
4✔
1712

1713
      mapserv->map->query.layer = mapserv->QueryLayerIndex;
4✔
1714
      mapserv->map->query.slayer = mapserv->SelectLayerIndex;
4✔
1715
      break;
4✔
1716
    case ITEMQUERY:
15✔
1717
    case ITEMNQUERY:
1718
      if (mapserv->QueryLayerIndex < 0 ||
15✔
1719
          mapserv->QueryLayerIndex >= mapserv->map->numlayers) {
15✔
1720
        msSetError(MS_WEBERR,
×
1721
                   "Query layer not set or references an invalid layer.",
1722
                   "mapserv()");
1723
        return MS_FAILURE;
×
1724
      }
1725

1726
      /* validate the qstring parameter */
1727
      if (msValidateParameter(
15✔
1728
              mapserv->QueryString,
15✔
1729
              msLookupHashTable(
1730
                  &(GET_LAYER(mapserv->map, mapserv->QueryLayerIndex)
15✔
1731
                        ->validation),
1732
                  "qstring"),
1733
              msLookupHashTable(&(mapserv->map->web.validation), "qstring"),
15✔
1734
              NULL, NULL) != MS_SUCCESS) {
1735
        msSetError(MS_WEBERR, "Parameter 'qstring' value fails to validate.",
×
1736
                   "mapserv()");
1737
        return MS_FAILURE;
×
1738
      }
1739

1740
      if (mapserv->QueryCoordSource != NONE && !mapserv->UseShapes)
15✔
1741
        if (MS_SUCCESS != setExtent(mapserv)) /* set user area of interest */
×
1742
          return MS_FAILURE;
1743

1744
      mapserv->map->query.type = MS_QUERY_BY_FILTER;
15✔
1745
      mapserv->map->query.layer = mapserv->QueryLayerIndex;
15✔
1746
      if (mapserv->QueryItem)
15✔
1747
        mapserv->map->query.filteritem = msStrdup(mapserv->QueryItem);
11✔
1748
      if (mapserv->QueryString) {
15✔
1749
        msInitExpression(&mapserv->map->query.filter);
15✔
1750
        msLoadExpressionString(&mapserv->map->query.filter,
15✔
1751
                               mapserv->QueryString);
15✔
1752
      }
1753

1754
      mapserv->map->query.rect = mapserv->map->extent;
15✔
1755

1756
      mapserv->map->query.mode = MS_QUERY_MULTIPLE;
15✔
1757
      if (mapserv->Mode == ITEMQUERY)
15✔
1758
        mapserv->map->query.mode = MS_QUERY_SINGLE;
5✔
1759
      break;
1760
    case NQUERY:
45✔
1761
      mapserv->map->query.mode =
45✔
1762
          MS_QUERY_MULTIPLE; /* all of these cases return multiple results */
1763
      mapserv->map->query.layer = mapserv->QueryLayerIndex;
45✔
1764

1765
      switch (mapserv->QueryCoordSource) {
45✔
1766
      case FROMIMGPNT:
8✔
1767
        setCoordinate(mapserv);
8✔
1768

1769
        if (mapserv->SearchMap) { /* compute new extent, pan etc then search
8✔
1770
                                     that extent */
1771
          if (MS_SUCCESS != setExtent(mapserv)) /* set user area of interest */
×
1772
            return MS_FAILURE;
1773
          mapserv->map->cellsize =
×
1774
              msAdjustExtent(&(mapserv->map->extent), mapserv->map->width,
×
1775
                             mapserv->map->height);
×
1776
          if (msCalculateScale(mapserv->map->extent, mapserv->map->units,
×
1777
                               mapserv->map->width, mapserv->map->height,
1778
                               mapserv->map->resolution,
1779
                               &mapserv->map->scaledenom) != MS_SUCCESS)
×
1780
            return MS_FAILURE;
1781
          mapserv->map->query.rect = mapserv->map->extent;
×
1782
          mapserv->map->query.type = MS_QUERY_BY_RECT;
×
1783
        } else {
1784
          mapserv->map->extent =
8✔
1785
              mapserv->ImgExt; /* use the existing image parameters */
1786
          mapserv->map->width = mapserv->ImgCols;
8✔
1787
          mapserv->map->height = mapserv->ImgRows;
8✔
1788
          if (msCalculateScale(mapserv->map->extent, mapserv->map->units,
8✔
1789
                               mapserv->map->width, mapserv->map->height,
1790
                               mapserv->map->resolution,
1791
                               &mapserv->map->scaledenom) != MS_SUCCESS)
1792
            return MS_FAILURE;
1793
          mapserv->map->query.point = mapserv->mappnt;
8✔
1794
          mapserv->map->query.type = MS_QUERY_BY_POINT;
8✔
1795
        }
1796

1797
        break;
1798
      case FROMIMGBOX:
×
1799
        if (mapserv->SearchMap) { /* compute new extent, pan etc then search
×
1800
                                     that extent */
1801
          setExtent(mapserv);
×
1802
          if (msCalculateScale(mapserv->map->extent, mapserv->map->units,
×
1803
                               mapserv->map->width, mapserv->map->height,
1804
                               mapserv->map->resolution,
1805
                               &mapserv->map->scaledenom) != MS_SUCCESS)
×
1806
            return MS_FAILURE;
1807
          mapserv->map->cellsize =
×
1808
              msAdjustExtent(&(mapserv->map->extent), mapserv->map->width,
×
1809
                             mapserv->map->height);
×
1810
          mapserv->map->query.rect = mapserv->map->extent;
×
1811
          mapserv->map->query.type = MS_QUERY_BY_RECT;
×
1812
        } else {
1813
          double cellx, celly;
1814

1815
          mapserv->map->extent =
×
1816
              mapserv->ImgExt; /* use the existing image parameters */
1817
          mapserv->map->width = mapserv->ImgCols;
×
1818
          mapserv->map->height = mapserv->ImgRows;
×
1819
          if (msCalculateScale(mapserv->map->extent, mapserv->map->units,
×
1820
                               mapserv->map->width, mapserv->map->height,
1821
                               mapserv->map->resolution,
1822
                               &mapserv->map->scaledenom) != MS_SUCCESS)
1823
            return MS_FAILURE;
1824
          cellx = MS_CELLSIZE(
×
1825
              mapserv->ImgExt.minx, mapserv->ImgExt.maxx,
1826
              mapserv->ImgCols); /* calculate the new search extent */
1827
          celly = MS_CELLSIZE(mapserv->ImgExt.miny, mapserv->ImgExt.maxy,
×
1828
                              mapserv->ImgRows);
1829
          mapserv->RawExt.minx =
×
1830
              MS_IMAGE2MAP_X(mapserv->ImgBox.minx, mapserv->ImgExt.minx, cellx);
×
1831
          mapserv->RawExt.maxx =
×
1832
              MS_IMAGE2MAP_X(mapserv->ImgBox.maxx, mapserv->ImgExt.minx, cellx);
×
1833
          mapserv->RawExt.maxy =
×
1834
              MS_IMAGE2MAP_Y(mapserv->ImgBox.miny, mapserv->ImgExt.maxy,
×
1835
                             celly); /* y's are flip flopped because img/map
1836
                                        coordinate systems are */
1837
          mapserv->RawExt.miny =
×
1838
              MS_IMAGE2MAP_Y(mapserv->ImgBox.maxy, mapserv->ImgExt.maxy, celly);
×
1839

1840
          mapserv->map->query.rect = mapserv->RawExt;
×
1841
          mapserv->map->query.type = MS_QUERY_BY_RECT;
×
1842
        }
1843
        break;
1844
      case FROMIMGSHAPE:
×
1845
        mapserv->map->extent =
×
1846
            mapserv->ImgExt; /* use the existing image parameters */
1847
        mapserv->map->width = mapserv->ImgCols;
×
1848
        mapserv->map->height = mapserv->ImgRows;
×
1849
        mapserv->map->cellsize = msAdjustExtent(
×
1850
            &(mapserv->map->extent), mapserv->map->width, mapserv->map->height);
1851
        if (msCalculateScale(mapserv->map->extent, mapserv->map->units,
×
1852
                             mapserv->map->width, mapserv->map->height,
1853
                             mapserv->map->resolution,
1854
                             &mapserv->map->scaledenom) != MS_SUCCESS)
×
1855
          return MS_FAILURE;
1856

1857
        /* convert from image to map coordinates here (see setCoordinate) */
1858
        for (i = 0; i < mapserv->map->query.shape->numlines; i++) {
×
1859
          for (j = 0; j < mapserv->map->query.shape->line[i].numpoints; j++) {
×
1860
            mapserv->map->query.shape->line[i].point[j].x = MS_IMAGE2MAP_X(
×
1861
                mapserv->map->query.shape->line[i].point[j].x,
1862
                mapserv->map->extent.minx, mapserv->map->cellsize);
1863
            mapserv->map->query.shape->line[i].point[j].y = MS_IMAGE2MAP_Y(
×
1864
                mapserv->map->query.shape->line[i].point[j].y,
1865
                mapserv->map->extent.maxy, mapserv->map->cellsize);
1866
          }
1867
        }
1868

1869
        mapserv->map->query.type = MS_QUERY_BY_SHAPE;
×
1870
        break;
×
1871
      case FROMUSERPNT:
4✔
1872
        if (mapserv->Buffer == 0) { /* do a *pure* point query */
4✔
1873
          mapserv->map->query.point = mapserv->mappnt;
4✔
1874
          mapserv->map->query.type = MS_QUERY_BY_POINT;
4✔
1875
          setExtent(mapserv);
4✔
1876
        } else {
1877
          setExtent(mapserv);
×
1878
          if (mapserv->SearchMap) { /* the extent should be tied to a map, so we
×
1879
                                       need to "adjust" it */
1880
            if (msCalculateScale(mapserv->map->extent, mapserv->map->units,
×
1881
                                 mapserv->map->width, mapserv->map->height,
1882
                                 mapserv->map->resolution,
1883
                                 &mapserv->map->scaledenom) != MS_SUCCESS)
×
1884
              return MS_FAILURE;
1885
            mapserv->map->cellsize =
×
1886
                msAdjustExtent(&(mapserv->map->extent), mapserv->map->width,
×
1887
                               mapserv->map->height);
×
1888
          }
1889
          mapserv->map->query.rect = mapserv->map->extent;
×
1890
          mapserv->map->query.type = MS_QUERY_BY_RECT;
×
1891
        }
1892
        break;
1893
      case FROMUSERSHAPE:
8✔
1894
        setExtent(mapserv);
8✔
1895
        mapserv->map->query.type = MS_QUERY_BY_SHAPE;
8✔
1896
        break;
8✔
1897
      default: /* from an extent of some sort */
25✔
1898
        setExtent(mapserv);
25✔
1899
        if (mapserv->SearchMap) { /* the extent should be tied to a map, so we
25✔
1900
                                     need to "adjust" it */
1901
          if (msCalculateScale(mapserv->map->extent, mapserv->map->units,
×
1902
                               mapserv->map->width, mapserv->map->height,
1903
                               mapserv->map->resolution,
1904
                               &mapserv->map->scaledenom) != MS_SUCCESS)
×
1905
            return MS_FAILURE;
1906
          mapserv->map->cellsize =
×
1907
              msAdjustExtent(&(mapserv->map->extent), mapserv->map->width,
×
1908
                             mapserv->map->height);
×
1909
        }
1910

1911
        mapserv->map->query.rect = mapserv->map->extent;
25✔
1912
        mapserv->map->query.type = MS_QUERY_BY_RECT;
25✔
1913
        break;
25✔
1914
      }
1915
      break;
1916
    case QUERY:
8✔
1917
      switch (mapserv->QueryCoordSource) {
8✔
1918
      case FROMIMGPNT:
×
1919
        setCoordinate(mapserv);
×
1920
        mapserv->map->extent =
×
1921
            mapserv->ImgExt; /* use the existing image parameters */
1922
        mapserv->map->width = mapserv->ImgCols;
×
1923
        mapserv->map->height = mapserv->ImgRows;
×
1924
        if (msCalculateScale(mapserv->map->extent, mapserv->map->units,
×
1925
                             mapserv->map->width, mapserv->map->height,
1926
                             mapserv->map->resolution,
1927
                             &mapserv->map->scaledenom) != MS_SUCCESS)
1928
          return MS_FAILURE;
1929
        break;
1930
      case FROMUSERPNT: /* only a buffer makes sense, DOES IT? */
8✔
1931
        if (setExtent(mapserv) != MS_SUCCESS)
8✔
1932
          return MS_FAILURE;
1933
        break;
1934
      default:
×
1935
        msSetError(MS_WEBERR,
×
1936
                   "Query mode needs a point, imgxy and mapxy are not set.",
1937
                   "mapserv()");
1938
        return MS_FAILURE;
×
1939
        break;
1940
      }
1941

1942
      mapserv->map->query.type = MS_QUERY_BY_POINT;
8✔
1943
      mapserv->map->query.mode = MS_QUERY_SINGLE;
8✔
1944
      mapserv->map->query.layer = mapserv->QueryLayerIndex;
8✔
1945
      mapserv->map->query.point = mapserv->mappnt;
8✔
1946
      mapserv->map->query.buffer = mapserv->Buffer;
8✔
1947
      break;
8✔
1948
    case INDEXQUERY:
4✔
1949
      mapserv->map->query.type = MS_QUERY_BY_INDEX;
4✔
1950
      mapserv->map->query.mode = MS_QUERY_SINGLE;
4✔
1951
      mapserv->map->query.layer = mapserv->QueryLayerIndex;
4✔
1952
      mapserv->map->query.shapeindex = mapserv->ShapeIndex;
4✔
1953
      mapserv->map->query.tileindex = mapserv->TileIndex;
4✔
1954
      break;
4✔
1955
    } /* end mode switch */
1956

1957
    /* finally execute the query */
1958
    if (msExecuteQuery(mapserv->map) != MS_SUCCESS)
76✔
1959
      return MS_FAILURE;
1960

1961
    /* catch empty result set when web->empty is set (#6907) */
1962
    if (mapserv->map->web.empty != NULL ||
150✔
1963
        CPLGetConfigOption("MS_EMPTY_URL", NULL) != NULL) {
74✔
1964
      int empty = MS_TRUE;
1965
      for (int i = 0; i < mapserv->map->numlayers; i++) { // count results
5✔
1966
        if (mapserv->map->layers[i]->resultcache &&
3✔
1967
            mapserv->map->layers[i]->resultcache->numresults > 0) {
3✔
1968
          empty = MS_FALSE;
1969
          break;
1970
        }
1971
      }
1972
      if (empty == MS_TRUE) {
3✔
1973
        /* note: this error message will not be displayed */
1974
        msSetError(MS_NOTFOUND, "No matching record(s) found.",
2✔
1975
                   "msCGIDispatchQueryRequest()");
1976
        return MS_FAILURE;
2✔
1977
      }
1978
    }
1979
  }
1980

1981
  if (mapserv->map->querymap.width > 0 &&
74✔
1982
      mapserv->map->querymap.width <= mapserv->map->maxsize)
13✔
1983
    mapserv->map->width =
13✔
1984
        mapserv->map->querymap.width; /* make sure we use the right size */
1985
  if (mapserv->map->querymap.height > 0 &&
74✔
1986
      mapserv->map->querymap.height <= mapserv->map->maxsize)
13✔
1987
    mapserv->map->height = mapserv->map->querymap.height;
13✔
1988

1989
  if (mapserv->UseShapes)
74✔
1990
    if (MS_SUCCESS != setExtentFromShapes(mapserv))
×
1991
      return MS_FAILURE;
1992

1993
  if (msReturnTemplateQuery(mapserv, mapserv->map->web.queryformat, NULL) !=
74✔
1994
      MS_SUCCESS)
1995
    return MS_FAILURE;
1996

1997
  if (mapserv->savequery) {
73✔
1998
    snprintf(buffer, sizeof(buffer), "%s%s%s%s", mapserv->map->web.imagepath,
×
1999
             mapserv->map->name, mapserv->Id, MS_QUERY_EXTENSION);
×
2000
    if ((status = msSaveQuery(mapserv->map, buffer, MS_FALSE)) != MS_SUCCESS)
×
2001
      return status;
2002
  }
2003
  return MS_SUCCESS;
2004
}
2005

2006
int msCGIDispatchImageRequest(mapservObj *mapserv) {
48✔
2007
  int status;
2008
  imageObj *img = NULL;
2009
  switch (mapserv->Mode) {
48✔
2010
  case MAP:
28✔
2011
    if (mapserv->QueryFile) {
28✔
2012
      status = msLoadQuery(mapserv->map, mapserv->QueryFile);
×
2013
      if (status != MS_SUCCESS)
×
2014
        return MS_FAILURE;
2015
      img = msDrawMap(mapserv->map, MS_TRUE);
×
2016
    } else
2017
      img = msDrawMap(mapserv->map, MS_FALSE);
28✔
2018
    break;
2019
  case REFERENCE:
×
2020
    mapserv->map->cellsize = msAdjustExtent(
×
2021
        &(mapserv->map->extent), mapserv->map->width, mapserv->map->height);
×
2022
    img = msDrawReferenceMap(mapserv->map);
×
2023
    break;
×
2024
  case SCALEBAR:
×
2025
    img = msDrawScalebar(mapserv->map);
×
2026
    break;
×
2027
  case TILE:
5✔
2028
    msTileSetExtent(mapserv);
5✔
2029

2030
    if (!strcmp(MS_IMAGE_MIME_TYPE(mapserv->map->outputformat),
10✔
2031
                "application/vnd.mapbox-vector-tile") ||
5✔
2032
        !strcmp(MS_IMAGE_MIME_TYPE(mapserv->map->outputformat),
5✔
2033
                "application/x-protobuf")) {
2034
      if (msMVTWriteTile(mapserv->map, mapserv->sendheaders) != MS_SUCCESS)
×
2035
        return MS_FAILURE;
2036
      return MS_SUCCESS;
2037
    }
2038

2039
    img = msTileDraw(mapserv);
5✔
2040
    break;
5✔
2041
  case LEGEND:
15✔
2042
  case MAPLEGEND:
2043
    img = msDrawLegend(mapserv->map, MS_FALSE, mapserv->hittest);
15✔
2044
    break;
15✔
2045
  default:
×
2046
    msSetError(MS_CGIERR, "Invalid CGI mode", "msCGIDispatchImageRequest()");
×
2047
    break;
2048
  }
2049

2050
  if (!img)
48✔
2051
    return MS_FAILURE;
8✔
2052

2053
  /*
2054
   ** Set the Cache control headers if the option is set.
2055
   */
2056
  if (mapserv->sendheaders &&
80✔
2057
      msLookupHashTable(&(mapserv->map->web.metadata), "http_max_age")) {
40✔
2058
    msIO_setHeader(
×
2059
        "Cache-Control", "max-age=%s",
2060
        msLookupHashTable(&(mapserv->map->web.metadata), "http_max_age"));
×
2061
  }
2062

2063
  if (mapserv->sendheaders) {
40✔
2064
    const char *attachment =
2065
        msGetOutputFormatOption(mapserv->map->outputformat, "ATTACHMENT", NULL);
40✔
2066
    if (attachment)
40✔
2067
      msIO_setHeader("Content-disposition", "attachment; filename=%s",
×
2068
                     attachment);
2069

2070
    if (!strcmp(MS_IMAGE_MIME_TYPE(mapserv->map->outputformat),
80✔
2071
                "application/json")) {
2072
      msIO_setHeader("Content-Type", "application/json; charset=utf-8");
×
2073
    } else {
2074
      msIO_setHeader("Content-Type", "%s",
40✔
2075
                     MS_IMAGE_MIME_TYPE(mapserv->map->outputformat));
2076
    }
2077
    msIO_sendHeaders();
40✔
2078
  }
2079

2080
  if (mapserv->Mode == MAP || mapserv->Mode == TILE)
40✔
2081
    status = msSaveImage(mapserv->map, img, NULL);
25✔
2082
  else
2083
    status = msSaveImage(NULL, img, NULL);
15✔
2084

2085
  if (status != MS_SUCCESS)
40✔
2086
    return MS_FAILURE;
2087

2088
  msFreeImage(img);
40✔
2089
  return MS_SUCCESS;
40✔
2090
}
2091

2092
int msCGIDispatchLegendRequest(mapservObj *mapserv) {
15✔
2093
  int status;
2094
  if (mapserv->Mode == MAPLEGEND) {
15✔
2095
    if (setExtent(mapserv) != MS_SUCCESS)
2✔
2096
      return MS_FAILURE;
2097
    if (checkWebScale(mapserv) != MS_SUCCESS)
2✔
2098
      return MS_FAILURE;
2099
    mapserv->hittest = msSmallMalloc(sizeof(map_hittest));
2✔
2100
    initMapHitTests(mapserv->map, mapserv->hittest);
2✔
2101
    status = msHitTestMap(mapserv->map, mapserv->hittest);
2✔
2102
    if (status != MS_SUCCESS)
2✔
2103
      return MS_FAILURE;
2104
  }
2105
  if (mapserv->map->legend.template) {
15✔
2106
    char *legendTemplate;
2107
    legendTemplate = generateLegendTemplate(mapserv);
×
2108
    if (legendTemplate) {
×
2109
      if (mapserv->sendheaders) {
×
2110
        msIO_setHeader("Content-Type", "%s", mapserv->map->web.legendformat);
×
2111
        msIO_sendHeaders();
×
2112
      }
2113
      msIO_fwrite(legendTemplate, strlen(legendTemplate), 1, stdout);
×
2114

2115
      free(legendTemplate);
×
2116
      return MS_SUCCESS;
×
2117
    } else { /* error already generated by (generateLegendTemplate()) */
2118
      return MS_FAILURE;
2119
    }
2120
  } else {
2121
    return msCGIDispatchImageRequest(mapserv);
15✔
2122
  }
2123
}
2124

2125
int msCGIDispatchLegendIconRequest(mapservObj *mapserv) {
×
2126
  char **tokens = NULL;
2127
  int numtokens = 0;
×
2128
  int layerindex = -1, classindex = 0, status;
2129
  outputFormatObj *format = NULL;
×
2130
  imageObj *img = NULL;
2131

2132
  /* TODO: do we want to set scale here? */
2133

2134
  /* do we have enough information */
2135
  if (!mapserv->icon) {
×
2136
    msSetError(MS_WEBERR, "Mode=LEGENDICON requires an icon parameter.",
×
2137
               "mapserv()");
2138
    return MS_FAILURE;
×
2139
  }
2140

2141
  /* process the icon definition */
2142
  tokens = msStringSplit(mapserv->icon, ',', &numtokens);
×
2143

2144
  if (numtokens != 1 && numtokens != 2) {
×
2145
    msSetError(MS_WEBERR,
×
2146
               "%d Malformed icon parameter, should be 'layer,class' or just "
2147
               "'layer' if the layer has only 1 class defined.",
2148
               "mapserv()", numtokens);
2149
    status = MS_FAILURE;
2150
    goto li_cleanup;
×
2151
  }
2152

2153
  if ((layerindex = msGetLayerIndex(mapserv->map, tokens[0])) == -1) {
×
2154
    msSetError(MS_WEBERR, "Icon layer=%s not found in mapfile.", "mapserv()",
×
2155
               tokens[0]);
2156
    status = MS_FAILURE;
2157
    goto li_cleanup;
×
2158
  }
2159

2160
  if (numtokens == 2) { /* check the class index */
×
2161
    classindex = atoi(tokens[1]);
×
2162
    if (classindex < 0 ||
×
2163
        classindex >= GET_LAYER(mapserv->map, layerindex)->numclasses) {
×
2164
      msSetError(MS_WEBERR, "Icon class=%d not found in layer=%s.", "mapserv()",
×
2165
                 classindex, GET_LAYER(mapserv->map, layerindex)->name);
×
2166
      status = MS_FAILURE;
2167
      goto li_cleanup;
×
2168
    }
2169
  }
2170

2171
  if (mapserv->Mode == MAPLEGENDICON) {
×
2172
    if (setExtent(mapserv) != MS_SUCCESS) {
×
2173
      status = MS_FAILURE;
2174
      goto li_cleanup;
×
2175
    }
2176
    if (checkWebScale(mapserv) != MS_SUCCESS) {
×
2177
      status = MS_FAILURE;
2178
      goto li_cleanup;
×
2179
    }
2180
    mapserv->hittest = msSmallMalloc(sizeof(map_hittest));
×
2181
    initMapHitTests(mapserv->map, mapserv->hittest);
×
2182
    status = msHitTestLayer(mapserv->map, GET_LAYER(mapserv->map, layerindex),
×
2183
                            &mapserv->hittest->layerhits[layerindex]);
×
2184
    if (status != MS_SUCCESS)
×
2185
      goto li_cleanup;
×
2186
  }
2187

2188
  /* ensure we have an image format representing the options for the legend. */
2189
  msApplyOutputFormat(&format, mapserv->map->outputformat,
×
2190
                      mapserv->map->legend.transparent);
×
2191

2192
  /* initialize the legend image */
2193
  if (!MS_RENDERER_PLUGIN(format)) {
×
2194
    msSetError(MS_RENDERERERR, "unsupported renderer for legend icon",
×
2195
               "mapserv main()");
2196
    status = MS_FAILURE;
2197
    goto li_cleanup;
×
2198
  }
2199
  img = msImageCreate(mapserv->map->legend.keysizex,
×
2200
                      mapserv->map->legend.keysizey, format,
2201
                      mapserv->map->web.imagepath, mapserv->map->web.imageurl,
2202
                      mapserv->map->resolution, mapserv->map->defresolution,
2203
                      &(mapserv->map->legend.imagecolor));
×
2204
  if (!img) {
×
2205
    status = MS_FAILURE;
2206
    goto li_cleanup;
×
2207
  }
2208
  img->map = mapserv->map;
×
2209

2210
  /* drop this reference to output format */
2211
  msApplyOutputFormat(&format, NULL, MS_NOOVERRIDE);
×
2212

2213
  if (msDrawLegendIcon(mapserv->map, GET_LAYER(mapserv->map, layerindex),
×
2214
                       GET_LAYER(mapserv->map, layerindex)->class[classindex],
×
2215
                       mapserv -> map -> legend.keysizex,
2216
                       mapserv->map->legend.keysizey, img, 0, 0, MS_TRUE,
×
2217
                       ((mapserv->hittest)
×
2218
                            ? (&mapserv->hittest->layerhits[layerindex]
×
2219
                                    .classhits[classindex])
×
2220
                            : (NULL))) != MS_SUCCESS) {
2221
    status = MS_FAILURE;
2222
    goto li_cleanup;
×
2223
  }
2224

2225
  if (mapserv->sendheaders) {
×
2226
    msIO_setHeader("Content-Type", "%s",
×
2227
                   MS_IMAGE_MIME_TYPE(mapserv->map->outputformat));
×
2228
    msIO_sendHeaders();
×
2229
  }
2230
  /*
2231
   ** Set the Cache control headers if the option is set.
2232
   */
2233
  if (mapserv->sendheaders &&
×
2234
      msLookupHashTable(&(mapserv->map->web.metadata), "http_max_age")) {
×
2235
    msIO_printf(
×
2236
        "Cache-Control: max-age=%s%c",
2237
        msLookupHashTable(&(mapserv->map->web.metadata), "http_max_age"), 10);
×
2238
  }
2239

2240
  status = msSaveImage(NULL, img, NULL);
×
2241

2242
li_cleanup:
×
2243
  msFreeCharArray(tokens, numtokens);
×
2244
  msFreeImage(img);
×
2245
  return status;
×
2246
}
2247

2248
int msCGIDispatchRequest(mapservObj *mapserv) {
1,939✔
2249
  int i;
2250
  int status;
2251

2252
  /*
2253
   ** Determine 'mode': Check for MS_MODE env. var. and mode=... CGI param
2254
   */
2255
  mapserv->Mode = -1; /* Not set */
1,939✔
2256
  if (msCGISetMode(mapserv) != MS_SUCCESS) {
1,939✔
2257
    return MS_FAILURE;
2258
  }
2259

2260
  /*
2261
   ** Start by calling the WMS/WFS/WCS Dispatchers.  If they fail then we'll
2262
   ** process this as a regular MapServer request.
2263
   */
2264
  if ((mapserv->Mode == -1 || mapserv->Mode == OWS || mapserv->Mode == WFS) &&
3,752✔
2265
      (status = msOWSDispatch(mapserv->map, mapserv->request, mapserv->Mode)) !=
1,813✔
2266
          MS_DONE) {
2267
    /*
2268
     ** OWSDispatch returned either MS_SUCCESS or MS_FAILURE
2269
     */
2270
    if (status == MS_FAILURE) {
1,811✔
2271
      return MS_FAILURE;
2272
    }
2273

2274
    if (status == MS_SUCCESS &&
1,555✔
2275
        strcasecmp(mapserv->map->imagetype, "application/openlayers") == 0) {
1,555✔
2276
      char *service = NULL;
2277
      for (i = 0; i < mapserv->request->NumParams; i++) {
9✔
2278
        if (strcasecmp(mapserv->request->ParamNames[i], "SERVICE") == 0) {
9✔
2279
          service = mapserv->request->ParamValues[i];
3✔
2280
          break;
3✔
2281
        }
2282
      }
2283
      if (service && strcasecmp(service, "WMS") == 0) {
3✔
2284
        if (mapserv->sendheaders) {
3✔
2285
          msIO_setHeader("Content-Type", "text/html");
3✔
2286
          msIO_sendHeaders();
3✔
2287
        }
2288

2289
        if (msReturnOpenLayersPage(mapserv) != MS_SUCCESS)
3✔
2290
          return MS_FAILURE;
2291
      }
2292
    }
2293
    return MS_SUCCESS;
1,555✔
2294
  } /* done OGC/OWS case */
2295

2296
  /*
2297
  ** Do "traditional" mode processing.
2298
  */
2299
  if (mapserv->Mode == -1)
128✔
2300
    mapserv->Mode = BROWSE;
2✔
2301

2302
  if (MS_SUCCESS != msCGILoadForm(mapserv)) {
128✔
2303
    return MS_FAILURE;
2304
  }
2305

2306
  /* Insecure as implemented, need to save someplace non accessible by everyone
2307
     in the universe if(mapserv->savemap) { snprintf(buffer, sizeof(buffer),
2308
     "%s%s%s.map", mapserv->map->web.imagepath, mapserv->map->name,
2309
     mapserv->Id); if(msSaveMap(mapserv->map, buffer) == -1) return MS_FAILURE;
2310
      }
2311
  */
2312

2313
  if ((mapserv->CoordSource == FROMIMGPNT) ||
127✔
2314
      (mapserv->CoordSource == FROMIMGBOX)) /* make sure extent of existing
2315
                                               image matches shape of image */
2316
    mapserv->map->cellsize =
8✔
2317
        msAdjustExtent(&mapserv->ImgExt, mapserv->ImgCols, mapserv->ImgRows);
8✔
2318

2319
  /*
2320
  ** For each layer let's set layer status
2321
  */
2322
  for (i = 0; i < mapserv->map->numlayers; i++) {
625✔
2323
    if ((GET_LAYER(mapserv->map, i)->status != MS_DEFAULT)) {
498✔
2324
      if (isOn(mapserv, GET_LAYER(mapserv->map, i)->name,
435✔
2325
               GET_LAYER(mapserv->map, i)->group) ==
2326
          MS_TRUE) /* Set layer status */
2327
        GET_LAYER(mapserv->map, i)->status = MS_ON;
73✔
2328
      else
2329
        GET_LAYER(mapserv->map, i)->status = MS_OFF;
362✔
2330
    }
2331
  }
2332

2333
  if (mapserv->CoordSource ==
127✔
2334
      FROMREFPNT) /* force browse mode if the reference coords are set */
2335
    mapserv->Mode = BROWSE;
×
2336

2337
  if (mapserv->Mode == TILE) {
127✔
2338
    /*
2339
     ** Tile mode:
2340
     ** Set the projection up and test the parameters for legality.
2341
     */
2342
    if (msTileSetup(mapserv) != MS_SUCCESS) {
5✔
2343
      return MS_FAILURE;
2344
    }
2345
  }
2346
  if (mapserv->Mode == BROWSE) {
127✔
2347
    return msCGIDispatchBrowseRequest(mapserv);
3✔
2348
  } else if (mapserv->Mode == MAP || mapserv->Mode == SCALEBAR ||
2349
             mapserv->Mode == REFERENCE ||
2350
             mapserv->Mode == TILE) { /* "image" only modes */
2351
    /* tile, map, scalebar and reference all need the extent to be set up
2352
     * correctly */
2353
    if (setExtent(mapserv) != MS_SUCCESS)
33✔
2354
      return MS_FAILURE;
2355
    if (checkWebScale(mapserv) != MS_SUCCESS)
33✔
2356
      return MS_FAILURE;
2357
    return msCGIDispatchImageRequest(mapserv);
33✔
2358
  } else if (mapserv->Mode == LEGEND || mapserv->Mode == MAPLEGEND) {
2359
    return msCGIDispatchLegendRequest(mapserv);
15✔
2360
  } else if (mapserv->Mode == LEGENDICON || mapserv->Mode == MAPLEGENDICON) {
2361
    return msCGIDispatchLegendIconRequest(mapserv);
×
2362
  } else if (mapserv->Mode >= QUERY) {
76✔
2363
    return msCGIDispatchQueryRequest(mapserv);
76✔
2364
  } else if (mapserv->Mode == COORDINATE) {
×
2365
    return msCGIDispatchCoordinateRequest(mapserv);
×
2366
  } else {
2367
    msSetError(MS_WEBERR, "Bug: unsupported mode", "msDispatchRequest");
×
2368
    return MS_FAILURE;
×
2369
  }
2370
}
2371

2372
int msCGIHandler(const char *query_string, void **out_buffer,
×
2373
                 size_t *buffer_length) {
2374
  int m = 0;
2375
  struct mstimeval execstarttime = {0}, execendtime = {0};
×
2376
  struct mstimeval requeststarttime = {0}, requestendtime = {0};
×
2377
  mapservObj *mapserv = NULL;
2378
  char *queryString = NULL;
2379
  int maxParams = MS_DEFAULT_CGI_PARAMS;
2380
  msIOContext *ctx;
2381
  msIOBuffer *buf;
2382

2383
  configObj *config = NULL;
2384

2385
  msIO_installStdoutToBuffer();
×
2386

2387
  /* Use PROJ_DATA/PROJ_LIB env vars if set */
2388
  msProjDataInitFromEnv();
×
2389

2390
  /* Use MS_ERRORFILE and MS_DEBUGLEVEL env vars if set */
2391
  if (msDebugInitFromEnv() != MS_SUCCESS) {
×
2392
    msCGIWriteError(mapserv);
×
2393
    goto end_request;
×
2394
  }
2395

2396
  if (msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING)
×
2397
    msGettimeofday(&execstarttime, NULL);
×
2398

2399
  if (!query_string || !*query_string) {
×
2400
    msIO_setHeader("Content-Type", "text/html");
×
2401
    msIO_sendHeaders();
×
2402
    msIO_printf("No query information to decode. QUERY_STRING not set.\n");
×
2403
    goto end_request;
×
2404
  }
2405

2406
  config = msLoadConfig(NULL);
×
2407
  if (config == NULL) {
×
2408
    msCGIWriteError(mapserv);
×
2409
    goto end_request;
×
2410
  }
2411

2412
  mapserv = msAllocMapServObj();
×
2413
  mapserv->request->type = MS_GET_REQUEST;
×
2414

2415
  /* don't modify the string */
2416
  queryString = msStrdup(query_string);
×
2417
  while (queryString[0] != '\0') {
×
2418
    if (m >= maxParams) {
×
2419
      maxParams *= 2;
×
2420
      mapserv->request->ParamNames = (char **)realloc(
×
2421
          mapserv->request->ParamNames, sizeof(char *) * maxParams);
×
2422
      if (mapserv->request->ParamNames == NULL) {
×
2423
        msIO_printf("Out of memory trying to allocate name/value pairs.\n");
×
2424
        goto end_request;
×
2425
      }
2426
      mapserv->request->ParamValues = (char **)realloc(
×
2427
          mapserv->request->ParamValues, sizeof(char *) * maxParams);
×
2428
      if (mapserv->request->ParamValues == NULL) {
×
2429
        msIO_printf("Out of memory trying to allocate name/value pairs.\n");
×
2430
        goto end_request;
×
2431
      }
2432
    }
2433
    mapserv->request->ParamValues[m] = makeword(queryString, '&');
×
2434
    plustospace(mapserv->request->ParamValues[m]);
×
2435
    unescape_url(mapserv->request->ParamValues[m]);
×
2436
    mapserv->request->ParamNames[m] =
×
2437
        makeword(mapserv->request->ParamValues[m], '=');
×
2438
    m++;
×
2439
  }
2440
  mapserv->request->NumParams = m;
×
2441

2442
  if (mapserv->request->NumParams == 0) {
×
2443
    msCGIWriteError(mapserv);
×
2444
    goto end_request;
×
2445
  }
2446

2447
  mapserv->map = msCGILoadMap(mapserv, config);
×
2448
  if (!mapserv->map) {
×
2449
    msCGIWriteError(mapserv);
×
2450
    goto end_request;
×
2451
  }
2452

2453
  if (mapserv->map->debug >= MS_DEBUGLEVEL_TUNING)
×
2454
    msGettimeofday(&requeststarttime, NULL);
×
2455

2456
  if (msCGIDispatchRequest(mapserv) != MS_SUCCESS) {
×
2457
    msCGIWriteError(mapserv);
×
2458
    goto end_request;
×
2459
  }
2460

2461
end_request:
×
2462
  if (mapserv) {
×
2463
    if (mapserv->map && mapserv->map->debug >= MS_DEBUGLEVEL_TUNING) {
×
2464
      msGettimeofday(&requestendtime, NULL);
×
2465
      msDebug("mapserv request processing time (msLoadMap not incl.): %.3fs\n",
×
2466
              (requestendtime.tv_sec + requestendtime.tv_usec / 1.0e6) -
×
2467
                  (requeststarttime.tv_sec + requeststarttime.tv_usec / 1.0e6));
×
2468
    }
2469
    msFreeMapServObj(mapserv);
×
2470
    msFreeConfig(config);
×
2471
  }
2472

2473
  /* normal case, processing is complete */
2474
  if (msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) {
×
2475
    msGettimeofday(&execendtime, NULL);
×
2476
    msDebug("mapserv total execution time: %.3fs\n",
×
2477
            (execendtime.tv_sec + execendtime.tv_usec / 1.0e6) -
×
2478
                (execstarttime.tv_sec + execstarttime.tv_usec / 1.0e6));
×
2479
  }
2480
  ctx = msIO_getHandler((FILE *)"stdout");
×
2481
  buf = (msIOBuffer *)ctx->cbData;
×
2482
  *out_buffer = buf->data;
×
2483
  *buffer_length = buf->data_offset;
×
2484

2485
  free(queryString);
×
2486

2487
  return 0;
×
2488
}
2489

2490
int msCGIDispatchMapIndexRequest(mapservObj *mapserv, configObj *config) {
×
2491
  return msOGCAPIDispatchMapIndexRequest(mapserv, config);
×
2492
}
2493

2494
int msCGIDispatchIndexRequest(mapservObj *mapserv, configObj *config) {
1✔
2495
  return msOGCAPIDispatchIndexRequest(mapserv, config);
1✔
2496
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc