s-pu upload to fix no-dsa security issues in mapserver

Guilhem Moulin guilhem at debian.org
Mon Mar 23 16:33:05 GMT 2026


Hi,

While working on an upload for bullseye LTS I noticed the version of
src:mapserver currently found in bookworm is vulnerable to CVE-2025-59431
(marked no-dsa by the security team) [0].

The issue is already fixed in trixie, and is now fixed in
bullseye-security so it probably makes sense to fix it Bookworm as well.
In addition, I backported fixes for various memory issues in the lexer.

I attach a tested debdiff excluding d/p/9999-Update-maplexer.c.patch
(maplexer.c is generated, but unfortunately not as part of the build
process, and the resulting patch adds a lot of clutter).  I separately
attach this patch anyway.

Individual commits and tag can be found on the LTS team fork [1].

Unless you object I'm planing to file a bookworm-pu bug with these
changes.

Cheers,
-- 
Guilhem.

[0] https://security-tracker.debian.org/tracker/CVE-2025-59431
[1] https://salsa.debian.org/lts-team/packages/mapserver/-/tree/debian/bookworm
-------------- next part --------------
diffstat for mapserver-8.0.0 mapserver-8.0.0

 changelog                                                               |   10 
 libmapserver2.symbols                                                   |    3 
 patches/0005-maplexer.l-avoid-non-null-terminated-msyystring_buff.patch |  250 +++++++++
 patches/0006-maplexer.l-fix-heap-buffer-overflow-issues-with-NUL-.patch |  200 +++++++
 patches/0007-mapfile-parser-fix-double-free-when-included-file-do.patch |   36 +
 patches/CVE-2025-59431.patch                                            |  255 ++++++++++
 patches/series                                                          |    5 
 salsa-ci.yml                                                            |    9 
 8 files changed, 766 insertions(+), 2 deletions(-)

diff -Nru --exclude 9999-Update-maplexer.c.patch mapserver-8.0.0/debian/changelog mapserver-8.0.0/debian/changelog
--- mapserver-8.0.0/debian/changelog	2022-11-05 14:38:38.000000000 +0100
+++ mapserver-8.0.0/debian/changelog	2026-03-23 15:02:59.000000000 +0100
@@ -1,3 +1,13 @@
+mapserver (8.0.0-3+deb12u1) bookworm; urgency=high
+
+  * Non-maintainer upload.
+  * Fix CVE-2025-59431: Boolean-based SQL injection vulnerability in directive
+    PropertyName of the XML Filter Query.
+  * Fix heap-buffer-overflow and double-free issues in maplexer.
+  * Add d/salsa-ci.yml for Salsa CI.
+
+ -- Guilhem Moulin <guilhem at debian.org>  Mon, 23 Mar 2026 15:02:59 +0100
+
 mapserver (8.0.0-3) unstable; urgency=medium
 
   * Move from experimental to unstable.
diff -Nru --exclude 9999-Update-maplexer.c.patch mapserver-8.0.0/debian/libmapserver2.symbols mapserver-8.0.0/debian/libmapserver2.symbols
--- mapserver-8.0.0/debian/libmapserver2.symbols	2022-11-03 20:18:11.000000000 +0100
+++ mapserver-8.0.0/debian/libmapserver2.symbols	2026-03-23 15:02:59.000000000 +0100
@@ -2938,6 +2938,7 @@
  msStringTrimBlanks at Base 6.2.1
  msStringTrimEOL at Base 6.2.1
  msStringTrimLeft at Base 6.2.1
+ msStringUnescape at Base 8.0.0-3+deb12u1~
  msStripPath at Base 6.2.1
  msStrptime at Base 6.2.1
  msStyleGetGeomTransform at Base 6.2.1
@@ -3135,12 +3136,10 @@
  msyystring_begin at Base 6.2.1
  msyystring_begin_state at Base 6.2.1
  msyystring_buffer at Base 6.2.1
- msyystring_buffer_ptr at Base 6.2.1
  msyystring_buffer_size at Base 6.2.1
  msyystring_icase at Base 6.2.1
  msyystring_return_state at Base 6.2.1
  msyystring_size at Base 6.2.1
- msyystring_size_tmp at Base 6.2.1
  msyytext at Base 6.2.1
  msyywrap at Base 6.2.1
  mvtWriteShape at Base 7.2.0
diff -Nru --exclude 9999-Update-maplexer.c.patch mapserver-8.0.0/debian/patches/0005-maplexer.l-avoid-non-null-terminated-msyystring_buff.patch mapserver-8.0.0/debian/patches/0005-maplexer.l-avoid-non-null-terminated-msyystring_buff.patch
--- mapserver-8.0.0/debian/patches/0005-maplexer.l-avoid-non-null-terminated-msyystring_buff.patch	1970-01-01 01:00:00.000000000 +0100
+++ mapserver-8.0.0/debian/patches/0005-maplexer.l-avoid-non-null-terminated-msyystring_buff.patch	2026-03-23 15:02:59.000000000 +0100
@@ -0,0 +1,250 @@
+From: Even Rouault <even.rouault at spatialys.com>
+Date: Fri, 7 Oct 2022 13:11:43 +0200
+Subject: maplexer.l: avoid non-null terminated msyystring_buffer that can
+ cause read heap-buffer-overflow
+
+Origin: https://github.com/MapServer/MapServer/commit/76c504a8acacde15781179c4b29e4123d0858c52
+Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52175
+---
+ maplexer.l | 81 ++++++++++++++++++++++++++++----------------------------------
+ 1 file changed, 36 insertions(+), 45 deletions(-)
+
+diff --git a/maplexer.l b/maplexer.l
+index a3987da..00b3c85 100644
+--- a/maplexer.l
++++ b/maplexer.l
+@@ -46,7 +46,6 @@ double msyynumber;
+ int msyystate=MS_TOKENIZE_DEFAULT;
+ char *msyystring=NULL;
+ char *msyybasepath=NULL;
+-char *msyystring_buffer_ptr;
+ int  msyystring_buffer_size = 0;
+ int  msyystring_size;
+ char msyystring_begin;
+@@ -54,25 +53,21 @@ char *msyystring_buffer = NULL;
+ int  msyystring_icase = MS_FALSE;
+ int  msyystring_return_state;
+ int  msyystring_begin_state;
+-int  msyystring_size_tmp;
+ 
+ int msyyreturncomments = 0;
+ 
+-#define MS_LEXER_STRING_REALLOC(string, string_size, max_size, string_ptr)   \
++#define MS_LEXER_STRING_REALLOC(string, string_size, max_size)   \
+   do { \
+    const int string_size_macro = (int)(string_size); \
+    if (string_size_macro >= (int)(max_size)) {         \
+-       msyystring_size_tmp = (max_size);     \
+        max_size = (((int)(max_size)*2) > string_size_macro) ? ((int)(max_size))*2 : string_size_macro+1;   \
+        string = (char *) msSmallRealloc(string, sizeof(char *) * (max_size));  \
+-       string_ptr = string;    \
+-       string_ptr += msyystring_size_tmp; \
+    } \
+   } while(0)
+ 
+ #define MS_LEXER_RETURN_TOKEN(token) \
+    MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext),  \
+-                           msyystring_buffer_size, msyystring_buffer_ptr); \
++                           msyystring_buffer_size); \
+    strcpy(msyystring_buffer, msyytext); \
+    return(token); 
+ 
+@@ -491,7 +486,7 @@ char path[MS_MAXPATHLEN];
+                                                  msyytext++;
+                                                  msyytext[strlen(msyytext)-1] = '\0';
+                                                  MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
+-                                                                         msyystring_buffer_size, msyystring_buffer_ptr);
++                                                                         msyystring_buffer_size);
+                                                  strcpy(msyystring_buffer,msyytext);
+                                                  return(MS_BINDING);
+                                                }
+@@ -513,7 +508,7 @@ char path[MS_MAXPATHLEN];
+   msyytext++;
+   msyytext[strlen(msyytext)-1] = '\0';
+   MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
+-                          msyystring_buffer_size, msyystring_buffer_ptr);
++                          msyystring_buffer_size);
+   strcpy(msyystring_buffer, msyytext);
+   return(MS_TOKEN_BINDING_DOUBLE);
+ }
+@@ -522,7 +517,7 @@ char path[MS_MAXPATHLEN];
+   msyytext+=2;
+   msyytext[strlen(msyytext)-2] = '\0';
+   MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
+-                          msyystring_buffer_size, msyystring_buffer_ptr);
++                          msyystring_buffer_size);
+   strcpy(msyystring_buffer, msyytext);
+   return(MS_TOKEN_BINDING_STRING);
+ }
+@@ -531,14 +526,14 @@ char path[MS_MAXPATHLEN];
+   msyytext+=2;
+   msyytext[strlen(msyytext)-2] = '\0';
+   MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext),
+-                          msyystring_buffer_size, msyystring_buffer_ptr);
++                          msyystring_buffer_size);
+   strcpy(msyystring_buffer, msyytext);
+   return(MS_TOKEN_BINDING_TIME);
+ }
+ 
+ <INITIAL>-?[0-9]+|-?[0-9]+\.[0-9]*|-?\.[0-9]*|-?[0-9]+[eE][+-]?[0-9]+|-?[0-9]+\.[0-9]*[eE][+-]?[0-9]+|-?\.[0-9]*[eE][+-]?[0-9]+ {
+   MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
+-                          msyystring_buffer_size, msyystring_buffer_ptr);
++                          msyystring_buffer_size);
+   strcpy(msyystring_buffer,msyytext);
+   msyynumber = atof(msyytext);
+   return(MS_NUMBER); 
+@@ -546,7 +541,7 @@ char path[MS_MAXPATHLEN];
+ 
+ <EXPRESSION_STRING>-?[0-9]+|-?[0-9]+\.[0-9]*|-?\.[0-9]*|-?[0-9]+[eE][+-]?[0-9]+|-?[0-9]+\.[0-9]*[eE][+-]?[0-9]+|-?\.[0-9]*[eE][+-]?[0-9]+ {
+   MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
+-                          msyystring_buffer_size, msyystring_buffer_ptr);
++                          msyystring_buffer_size);
+   strcpy(msyystring_buffer,msyytext);
+   msyynumber = atof(msyytext);
+   return(MS_TOKEN_LITERAL_NUMBER);
+@@ -556,7 +551,7 @@ char path[MS_MAXPATHLEN];
+   msyytext++;
+   msyytext[strlen(msyytext)-1] = '\0';
+   MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
+-                          msyystring_buffer_size, msyystring_buffer_ptr);
++                          msyystring_buffer_size);
+   strcpy(msyystring_buffer, msyytext);
+   return(MS_TOKEN_LITERAL_TIME);
+ }
+@@ -565,7 +560,7 @@ char path[MS_MAXPATHLEN];
+                                                  msyytext++;
+                                                  msyytext[strlen(msyytext)-2] = '\0';
+                                                  MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
+-                                                                         msyystring_buffer_size, msyystring_buffer_ptr);
++                                                                         msyystring_buffer_size);
+                                                  strcpy(msyystring_buffer, msyytext);
+                                                  return(MS_IREGEX);
+                                                }
+@@ -574,7 +569,7 @@ char path[MS_MAXPATHLEN];
+                                                  msyytext++;
+                                                  msyytext[strlen(msyytext)-1] = '\0';
+                                                  MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
+-                                                                         msyystring_buffer_size, msyystring_buffer_ptr);
++                                                                         msyystring_buffer_size);
+                                                  strcpy(msyystring_buffer, msyytext);
+                                                  return(MS_REGEX);
+                                                }
+@@ -583,7 +578,7 @@ char path[MS_MAXPATHLEN];
+                                                  msyytext++;
+                                                  msyytext[strlen(msyytext)-1] = '\0';
+                                                  MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
+-                                                                         msyystring_buffer_size, msyystring_buffer_ptr);
++                                                                         msyystring_buffer_size);
+                                                  strcpy(msyystring_buffer, msyytext);
+                                                  return(MS_EXPRESSION);
+                                                }
+@@ -592,7 +587,7 @@ char path[MS_MAXPATHLEN];
+                                                  msyytext++;
+                                                  msyytext[strlen(msyytext)-1] = '\0';
+                                                  MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
+-                                                                         msyystring_buffer_size, msyystring_buffer_ptr);
++                                                                         msyystring_buffer_size);
+                                                  strcpy(msyystring_buffer, msyytext);
+                                                  return(MS_LIST);
+                                                }
+@@ -601,18 +596,13 @@ char path[MS_MAXPATHLEN];
+                                                  msyystring_return_state = MS_STRING;
+                                                  msyystring_begin = msyytext[0]; 
+                                                  msyystring_size = 0;
+-                                                 msyystring_buffer_ptr = msyystring_buffer;
++                                                 msyystring_buffer[0] = '\0';
+                                                  BEGIN(MSSTRING);
+                                               }
+ 
+ <MSSTRING>\'|\"|\"i|\'i                       {
+-                                                MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, 
+-                                                                                           msyystring_buffer_size, msyystring_buffer_ptr);
+                                                 if (msyystring_begin == msyytext[0]) {
+                                                    BEGIN(msyystring_begin_state);
+-
+-                                                   *msyystring_buffer_ptr = '\0';
+-
+                                                    if (msyystring_return_state == MS_STRING) {
+                                                       if (msyystring_icase && strlen(msyytext)==2) {
+                                                          msyystring_icase = MS_FALSE; // reset
+@@ -624,36 +614,37 @@ char path[MS_MAXPATHLEN];
+ 
+                                                 }
+                                                 else {
+-                                                  ++msyystring_size;
+-                                                  *msyystring_buffer_ptr++ = *msyytext;
++                                                  int old_size = msyystring_size;
++                                                  msyystring_size += (strlen(msyytext)==2) ? 2 : 1;
++                                                  MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size,
++                                                                          msyystring_buffer_size);
++                                                  msyystring_buffer[old_size] = *msyytext;
+                                                   if (strlen(msyytext)==2) {
+-                                                      MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, 
+-                                                                              msyystring_buffer_size, msyystring_buffer_ptr);
+-                                                     ++msyystring_size;
+-                                                     *msyystring_buffer_ptr++ = msyytext[1];
++                                                     msyystring_buffer[old_size+1] = msyytext[1];
+                                                   }
++                                                  msyystring_buffer[msyystring_size] = '\0';
+                                                 }
+                                               }
+ 
+ <MSSTRING>\\\'|\\\"|\\\\|\\                  { 
+-                                                MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, 
+-                                                                                           msyystring_buffer_size, msyystring_buffer_ptr);
+-
+                                                 ++msyystring_size;
++                                                MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size,
++                                                                        msyystring_buffer_size);
++
+                                                 if (strlen(msyytext) == 2)
+-                                                    *msyystring_buffer_ptr++ = msyytext[1]; 
++                                                    msyystring_buffer[msyystring_size-1] = msyytext[1]; 
+                                                 else
+-                                                    *msyystring_buffer_ptr++ = msyytext[0];
++                                                    msyystring_buffer[msyystring_size-1] = msyytext[0];
++                                                msyystring_buffer[msyystring_size] = '\0';
+                                              }
+ 
+ <MSSTRING>[^\\\'\\\"]+                       {
+-                                                 char *yptr = msyytext;
+-                                                 while ( *yptr ) { 
+-                                                   MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, 
+-                                                                           msyystring_buffer_size, msyystring_buffer_ptr);
+-                                                   ++msyystring_size;
+-                                                   *msyystring_buffer_ptr++ = *yptr++;
+-                                                 }
++                                                 int old_size = msyystring_size;
++                                                 int msyytext_len = (int)strlen(msyytext);
++                                                 msyystring_size += msyytext_len;
++                                                 MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size,
++                                                                         msyystring_buffer_size);
++                                                 memcpy(msyystring_buffer + old_size, msyytext, msyytext_len + 1);
+                                              }
+ 
+ <INCLUDE>\"[^\"]*\"|\'[^\']*\'                 {
+@@ -686,13 +677,13 @@ char path[MS_MAXPATHLEN];
+                                                  msyystring_return_state = MS_TOKEN_LITERAL_STRING;
+                                                  msyystring_begin = msyytext[0]; 
+                                                  msyystring_size = 0;
+-                                                 msyystring_buffer_ptr = msyystring_buffer;
++                                                 msyystring_buffer[0] = '\0';
+                                                  BEGIN(MSSTRING);
+                                               }
+ 
+ <INITIAL,CONFIG_FILE>[a-z/\.][a-z0-9/\._\-\=]*   { 
+                                                     MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
+-                                                                            msyystring_buffer_size, msyystring_buffer_ptr);
++                                                                            msyystring_buffer_size);
+                                                     strcpy(msyystring_buffer, msyytext); 
+                                                     return(MS_STRING); 
+                                                 }
+@@ -716,7 +707,7 @@ char path[MS_MAXPATHLEN];
+ 
+ <INITIAL,CONFIG_FILE>.                          { 
+                                                   MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
+-                                                                          msyystring_buffer_size, msyystring_buffer_ptr);
++                                                                          msyystring_buffer_size);
+                                                   strcpy(msyystring_buffer, msyytext); 
+                                                   return(0); 
+                                                 }
diff -Nru --exclude 9999-Update-maplexer.c.patch mapserver-8.0.0/debian/patches/0006-maplexer.l-fix-heap-buffer-overflow-issues-with-NUL-.patch mapserver-8.0.0/debian/patches/0006-maplexer.l-fix-heap-buffer-overflow-issues-with-NUL-.patch
--- mapserver-8.0.0/debian/patches/0006-maplexer.l-fix-heap-buffer-overflow-issues-with-NUL-.patch	1970-01-01 01:00:00.000000000 +0100
+++ mapserver-8.0.0/debian/patches/0006-maplexer.l-fix-heap-buffer-overflow-issues-with-NUL-.patch	2026-03-23 15:02:59.000000000 +0100
@@ -0,0 +1,200 @@
+From: Even Rouault <even.rouault at spatialys.com>
+Date: Tue, 11 Oct 2022 00:48:52 +0200
+Subject: maplexer.l: fix heap-buffer-overflow issues with NUL characters
+
+Origin: https://github.com/MapServer/MapServer/commit/700ea8243c496f3d574102c432deaf1a85472271
+Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52305
+---
+ maplexer.l | 59 +++++++++++++++++++++++++++++------------------------------
+ 1 file changed, 29 insertions(+), 30 deletions(-)
+
+diff --git a/maplexer.l b/maplexer.l
+index 00b3c85..7a67479c 100644
+--- a/maplexer.l
++++ b/maplexer.l
+@@ -484,8 +484,8 @@ char path[MS_MAXPATHLEN];
+ 
+ <INITIAL>\[[^\]]*\]                            {
+                                                  msyytext++;
+-                                                 msyytext[strlen(msyytext)-1] = '\0';
+-                                                 MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
++                                                 msyytext[msyyleng-1-1] = '\0';
++                                                 MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                                                                          msyystring_buffer_size);
+                                                  strcpy(msyystring_buffer,msyytext);
+                                                  return(MS_BINDING);
+@@ -506,8 +506,8 @@ char path[MS_MAXPATHLEN];
+ <EXPRESSION_STRING>\[[^\]]*\] {
+   /* attribute binding - numeric (no quotes) */
+   msyytext++;
+-  msyytext[strlen(msyytext)-1] = '\0';
+-  MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
++  msyytext[msyyleng-1-1] = '\0';
++  MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                           msyystring_buffer_size);
+   strcpy(msyystring_buffer, msyytext);
+   return(MS_TOKEN_BINDING_DOUBLE);
+@@ -515,8 +515,8 @@ char path[MS_MAXPATHLEN];
+ <EXPRESSION_STRING>\"\[[^\"]*\]\"|\'\[[^\']*\]\' {
+   /* attribute binding - string (single or double quotes) */
+   msyytext+=2;
+-  msyytext[strlen(msyytext)-2] = '\0';
+-  MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
++  msyytext[msyyleng-2-2] = '\0';
++  MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                           msyystring_buffer_size);
+   strcpy(msyystring_buffer, msyytext);
+   return(MS_TOKEN_BINDING_STRING);
+@@ -524,15 +524,15 @@ char path[MS_MAXPATHLEN];
+ <EXPRESSION_STRING>\`\[[^\`]*\]\` {
+   /* attribute binding - time */
+   msyytext+=2;
+-  msyytext[strlen(msyytext)-2] = '\0';
+-  MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext),
++  msyytext[msyyleng-2-2] = '\0';
++  MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng,
+                           msyystring_buffer_size);
+   strcpy(msyystring_buffer, msyytext);
+   return(MS_TOKEN_BINDING_TIME);
+ }
+ 
+ <INITIAL>-?[0-9]+|-?[0-9]+\.[0-9]*|-?\.[0-9]*|-?[0-9]+[eE][+-]?[0-9]+|-?[0-9]+\.[0-9]*[eE][+-]?[0-9]+|-?\.[0-9]*[eE][+-]?[0-9]+ {
+-  MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
++  MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                           msyystring_buffer_size);
+   strcpy(msyystring_buffer,msyytext);
+   msyynumber = atof(msyytext);
+@@ -540,7 +540,7 @@ char path[MS_MAXPATHLEN];
+ }
+ 
+ <EXPRESSION_STRING>-?[0-9]+|-?[0-9]+\.[0-9]*|-?\.[0-9]*|-?[0-9]+[eE][+-]?[0-9]+|-?[0-9]+\.[0-9]*[eE][+-]?[0-9]+|-?\.[0-9]*[eE][+-]?[0-9]+ {
+-  MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
++  MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                           msyystring_buffer_size);
+   strcpy(msyystring_buffer,msyytext);
+   msyynumber = atof(msyytext);
+@@ -549,8 +549,8 @@ char path[MS_MAXPATHLEN];
+ 
+ <EXPRESSION_STRING>\`[^\`]*\` {
+   msyytext++;
+-  msyytext[strlen(msyytext)-1] = '\0';
+-  MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
++  msyytext[msyyleng-1-1] = '\0';
++  MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                           msyystring_buffer_size);
+   strcpy(msyystring_buffer, msyytext);
+   return(MS_TOKEN_LITERAL_TIME);
+@@ -558,8 +558,8 @@ char path[MS_MAXPATHLEN];
+ 
+ <INITIAL>\/[^*]{1}[^\/]*\/i         {
+                                                  msyytext++;
+-                                                 msyytext[strlen(msyytext)-2] = '\0';
+-                                                 MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
++                                                 msyytext[msyyleng-1-2] = '\0';
++                                                 MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                                                                          msyystring_buffer_size);
+                                                  strcpy(msyystring_buffer, msyytext);
+                                                  return(MS_IREGEX);
+@@ -567,8 +567,8 @@ char path[MS_MAXPATHLEN];
+ 
+ <INITIAL>\/[^*]{1}[^\/]*\/          {
+                                                  msyytext++;
+-                                                 msyytext[strlen(msyytext)-1] = '\0';
+-                                                 MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
++                                                 msyytext[msyyleng-1-1] = '\0';
++                                                 MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                                                                          msyystring_buffer_size);
+                                                  strcpy(msyystring_buffer, msyytext);
+                                                  return(MS_REGEX);
+@@ -576,8 +576,8 @@ char path[MS_MAXPATHLEN];
+ 
+ <INITIAL>\(.*\)                     {
+                                                  msyytext++;
+-                                                 msyytext[strlen(msyytext)-1] = '\0';
+-                                                 MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
++                                                 msyytext[msyyleng-1-1] = '\0';
++                                                 MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                                                                          msyystring_buffer_size);
+                                                  strcpy(msyystring_buffer, msyytext);
+                                                  return(MS_EXPRESSION);
+@@ -585,8 +585,8 @@ char path[MS_MAXPATHLEN];
+ 
+ <INITIAL>\{.*\}                     {
+                                                  msyytext++;
+-                                                 msyytext[strlen(msyytext)-1] = '\0';
+-                                                 MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
++                                                 msyytext[msyyleng-1-1] = '\0';
++                                                 MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                                                                          msyystring_buffer_size);
+                                                  strcpy(msyystring_buffer, msyytext);
+                                                  return(MS_LIST);
+@@ -604,7 +604,7 @@ char path[MS_MAXPATHLEN];
+                                                 if (msyystring_begin == msyytext[0]) {
+                                                    BEGIN(msyystring_begin_state);
+                                                    if (msyystring_return_state == MS_STRING) {
+-                                                      if (msyystring_icase && strlen(msyytext)==2) {
++                                                      if (msyystring_icase && msyyleng==2) {
+                                                          msyystring_icase = MS_FALSE; // reset
+                                                          return MS_ISTRING;
+                                                       } else
+@@ -615,11 +615,11 @@ char path[MS_MAXPATHLEN];
+                                                 }
+                                                 else {
+                                                   int old_size = msyystring_size;
+-                                                  msyystring_size += (strlen(msyytext)==2) ? 2 : 1;
++                                                  msyystring_size += (msyyleng==2) ? 2 : 1;
+                                                   MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size,
+                                                                           msyystring_buffer_size);
+                                                   msyystring_buffer[old_size] = *msyytext;
+-                                                  if (strlen(msyytext)==2) {
++                                                  if (msyyleng==2) {
+                                                      msyystring_buffer[old_size+1] = msyytext[1];
+                                                   }
+                                                   msyystring_buffer[msyystring_size] = '\0';
+@@ -631,7 +631,7 @@ char path[MS_MAXPATHLEN];
+                                                 MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size,
+                                                                         msyystring_buffer_size);
+ 
+-                                                if (strlen(msyytext) == 2)
++                                                if (msyyleng == 2)
+                                                     msyystring_buffer[msyystring_size-1] = msyytext[1]; 
+                                                 else
+                                                     msyystring_buffer[msyystring_size-1] = msyytext[0];
+@@ -640,16 +640,15 @@ char path[MS_MAXPATHLEN];
+ 
+ <MSSTRING>[^\\\'\\\"]+                       {
+                                                  int old_size = msyystring_size;
+-                                                 int msyytext_len = (int)strlen(msyytext);
+-                                                 msyystring_size += msyytext_len;
++                                                 msyystring_size += msyyleng;
+                                                  MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size,
+                                                                          msyystring_buffer_size);
+-                                                 memcpy(msyystring_buffer + old_size, msyytext, msyytext_len + 1);
++                                                 memcpy(msyystring_buffer + old_size, msyytext, msyyleng + 1);
+                                              }
+ 
+ <INCLUDE>\"[^\"]*\"|\'[^\']*\'                 {
+                                                  msyytext++;
+-                                                 msyytext[strlen(msyytext)-1] = '\0';
++                                                 msyytext[msyyleng-1-1] = '\0';
+ 
+                                                  if(include_stack_ptr >= MAX_INCLUDE_DEPTH) {
+                                                    msSetError(MS_IOERR, "Includes nested to deeply.", "msyylex()");
+@@ -682,7 +681,7 @@ char path[MS_MAXPATHLEN];
+                                               }
+ 
+ <INITIAL,CONFIG_FILE>[a-z/\.][a-z0-9/\._\-\=]*   { 
+-                                                    MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
++                                                    MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                                                                             msyystring_buffer_size);
+                                                     strcpy(msyystring_buffer, msyytext); 
+                                                     return(MS_STRING); 
+@@ -706,7 +705,7 @@ char path[MS_MAXPATHLEN];
+ }
+ 
+ <INITIAL,CONFIG_FILE>.                          { 
+-                                                  MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), 
++                                                  MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                                                                           msyystring_buffer_size);
+                                                   strcpy(msyystring_buffer, msyytext); 
+                                                   return(0); 
diff -Nru --exclude 9999-Update-maplexer.c.patch mapserver-8.0.0/debian/patches/0007-mapfile-parser-fix-double-free-when-included-file-do.patch mapserver-8.0.0/debian/patches/0007-mapfile-parser-fix-double-free-when-included-file-do.patch
--- mapserver-8.0.0/debian/patches/0007-mapfile-parser-fix-double-free-when-included-file-do.patch	1970-01-01 01:00:00.000000000 +0100
+++ mapserver-8.0.0/debian/patches/0007-mapfile-parser-fix-double-free-when-included-file-do.patch	2026-03-23 15:02:59.000000000 +0100
@@ -0,0 +1,36 @@
+From: Even Rouault <even.rouault at spatialys.com>
+Date: Sat, 8 Apr 2023 13:18:50 +0200
+Subject: mapfile parser: fix double-free when included file doesn't exist
+
+Origin: https://github.com/MapServer/MapServer/commit/e3ca3cb2007c494d7dec8aec0e6443abd5ce62a2
+Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=57788
+---
+ maplexer.l | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/maplexer.l b/maplexer.l
+index 7a67479c..bc37858 100644
+--- a/maplexer.l
++++ b/maplexer.l
+@@ -655,10 +655,6 @@ char path[MS_MAXPATHLEN];
+                                                    return(-1);
+                                                  }
+ 
+-                                                 include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; /* save state */
+-                                                 include_lineno[include_stack_ptr] = msyylineno;
+-                                                 include_stack_ptr++;
+-
+                                                  msyyin = fopen(msBuildPath(path, msyybasepath, msyytext), "r");
+                                                  if(!msyyin) {
+                                                    msSetError(MS_IOERR, "Error opening included file \"%s\".", "msyylex()", msyytext);
+@@ -666,6 +662,10 @@ char path[MS_MAXPATHLEN];
+                                                    return(-1);
+                                                  }
+ 
++                                                 include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; /* save state */
++                                                 include_lineno[include_stack_ptr] = msyylineno;
++                                                 include_stack_ptr++;
++
+                                                  msyy_switch_to_buffer( msyy_create_buffer(msyyin, YY_BUF_SIZE) );
+                                                  msyylineno = 1;
+ 
diff -Nru --exclude 9999-Update-maplexer.c.patch mapserver-8.0.0/debian/patches/CVE-2025-59431.patch mapserver-8.0.0/debian/patches/CVE-2025-59431.patch
--- mapserver-8.0.0/debian/patches/CVE-2025-59431.patch	1970-01-01 01:00:00.000000000 +0100
+++ mapserver-8.0.0/debian/patches/CVE-2025-59431.patch	2026-03-23 15:02:59.000000000 +0100
@@ -0,0 +1,255 @@
+From: Even Rouault <even.rouault at spatialys.com>
+Date: Thu, 18 Sep 2025 20:22:23 +0200
+Subject: Add missing column name escaping in FLTGetCommonExpression()
+
+and use msLayerEscapePropertyName() insead of msOGRGetQuotedItem() in
+OGR backend
+
+Origin: https://github.com/MapServer/MapServer/commit/1c73acaa2d7a8b1d3955f076186e57fc8c06e0c6
+Bug: https://github.com/MapServer/MapServer/security/advisories/GHSA-256m-rx4h-r55w
+Bug: https://github.com/MapServer/MapServer/pull/7349
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-59431
+---
+ maplexer.l             | 14 ++++++++------
+ mapogcfiltercommon.cpp | 27 ++++++++++++++++++++++-----
+ mapogr.cpp             | 25 ++++++++++++++-----------
+ mapserver.h            |  1 +
+ mapstring.cpp          | 21 +++++++++++++++++++++
+ 5 files changed, 66 insertions(+), 22 deletions(-)
+
+diff --git a/maplexer.l b/maplexer.l
+index bc37858..3653fea 100644
+--- a/maplexer.l
++++ b/maplexer.l
+@@ -503,31 +503,33 @@ char path[MS_MAXPATHLEN];
+   /* attribute binding - data cellsize */
+   return(MS_TOKEN_BINDING_DATA_CELLSIZE);
+ }
+-<EXPRESSION_STRING>\[[^\]]*\] {
++<EXPRESSION_STRING>\[(?:\]\]|[^\]])*\] {
+   /* attribute binding - numeric (no quotes) */
+   msyytext++;
+   msyytext[msyyleng-1-1] = '\0';
+   MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                           msyystring_buffer_size);
+   strcpy(msyystring_buffer, msyytext);
++  msStringUnescape(msyystring_buffer, ']');
+   return(MS_TOKEN_BINDING_DOUBLE);
+ }
+-<EXPRESSION_STRING>\"\[[^\"]*\]\"|\'\[[^\']*\]\' {
++<EXPRESSION_STRING>\"\[(?:\"\"|[^\"])*\]\"|\'\[(?:\'\'|[^\'])*\]\' {
+   /* attribute binding - string (single or double quotes) */
+-  msyytext+=2;
+-  msyytext[msyyleng-2-2] = '\0';
++  msyytext[msyyleng-2] = '\0';
+   MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, 
+                           msyystring_buffer_size);
+-  strcpy(msyystring_buffer, msyytext);
++  strcpy(msyystring_buffer, msyytext + 2);
++  msStringUnescape(msyystring_buffer, msyytext[0]);
+   return(MS_TOKEN_BINDING_STRING);
+ }
+-<EXPRESSION_STRING>\`\[[^\`]*\]\` {
++<EXPRESSION_STRING>\`\[(?:\`\`|[^\`])*\]\` {
+   /* attribute binding - time */
+   msyytext+=2;
+   msyytext[msyyleng-2-2] = '\0';
+   MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng,
+                           msyystring_buffer_size);
+   strcpy(msyystring_buffer, msyytext);
++  msStringUnescape(msyystring_buffer, '`');
+   return(MS_TOKEN_BINDING_TIME);
+ }
+ 
+diff --git a/mapogcfiltercommon.cpp b/mapogcfiltercommon.cpp
+index f73d47b..c85ab8d 100644
+--- a/mapogcfiltercommon.cpp
++++ b/mapogcfiltercommon.cpp
+@@ -34,6 +34,20 @@
+ 
+ #include <string>
+ 
++static std::string FLTEscapePropertyName(const char *pszStr,
++                                         char chEscapeChar) {
++  std::string ret;
++  for (; *pszStr; ++pszStr) {
++    if (*pszStr == chEscapeChar) {
++      ret += chEscapeChar;
++      ret += chEscapeChar;
++    } else {
++      ret += *pszStr;
++    }
++  }
++  return ret;
++}
++
+ static std::string FLTGetIsLikeComparisonCommonExpression(FilterEncodingNode *psFilterNode)
+ {
+   /* From http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_04 */
+@@ -58,7 +72,7 @@ static std::string FLTGetIsLikeComparisonCommonExpression(FilterEncodingNode *ps
+   std::string expr("(\"[");
+ 
+   /* attribute */
+-  expr += psFilterNode->psLeftNode->pszValue;
++  expr += FLTEscapePropertyName(psFilterNode->psLeftNode->pszValue, '"');
+ 
+   /* #3521 */
+   if (bCaseInsensitive )
+@@ -171,7 +185,8 @@ static std::string FLTGetIsBetweenComparisonCommonExpresssion(FilterEncodingNode
+   else
+     expr += "([";
+ 
+-  expr += psFilterNode->psLeftNode->pszValue;
++  expr += FLTEscapePropertyName(psFilterNode->psLeftNode->pszValue,
++                                bString ? '"' : ']');
+ 
+   if (bString)
+     expr += "]\" ";
+@@ -264,7 +279,9 @@ std::string FLTGetBinaryComparisonCommonExpression(FilterEncodingNode *psFilterN
+     expr = "(\"[";
+   else
+     expr = "([";
+-  expr += psFilterNode->psLeftNode->pszValue;
++
++  expr += FLTEscapePropertyName(psFilterNode->psLeftNode->pszValue,
++                                bString ? '"' : ']');
+   
+   if (bString)
+     expr += "]\" ";
+@@ -542,13 +559,13 @@ static std::string FLTGetFeatureIdCommonExpression(FilterEncodingNode *psFilterN
+ 
+           if (bString) {
+             expr += "(\"[";
+-            expr += pszAttribute;
++            expr += FLTEscapePropertyName(pszAttribute, '"');
+             expr += "]\" == \"";
+             expr += pszId;
+             expr += "\")";
+           } else {
+             expr += "([";
+-            expr += pszAttribute;
++            expr += FLTEscapePropertyName(pszAttribute, ']');
+             expr += "] == ";
+             expr += pszId;
+             expr += ")";
+diff --git a/mapogr.cpp b/mapogr.cpp
+index 1b66219..e7b7833 100644
+--- a/mapogr.cpp
++++ b/mapogr.cpp
+@@ -2042,7 +2042,7 @@ char *msOGRGetToken(layerObj* layer, tokenListNodeObjPtr *node) {
+         break;
+     }
+     case MS_TOKEN_BINDING_INTEGER: {
+-        char *stresc = msOGRGetQuotedItem(layer, n->tokenval.bindval.item);
++        char *stresc = msLayerEscapePropertyName(layer, n->tokenval.bindval.item);
+         nOutSize = strlen(stresc)+ 20;
+         out = (char *)msSmallMalloc(nOutSize);
+ 
+@@ -2056,17 +2056,17 @@ char *msOGRGetToken(layerObj* layer, tokenListNodeObjPtr *node) {
+                              EQUAL(type, "Long") ||
+                              EQUAL(type, "Real")) )
+         {
+-            snprintf(out, nOutSize, "%s", stresc);
++            snprintf(out, nOutSize, "\"%s\"", stresc);
+         }
+         else
+         {
+-            snprintf(out, nOutSize, "CAST(%s AS integer)", stresc);
++            snprintf(out, nOutSize, "CAST(\"%s\" AS integer)", stresc);
+         }
+         msFree(stresc);
+         break;
+     }
+     case MS_TOKEN_BINDING_STRING: {
+-        char *stresc = msOGRGetQuotedItem(layer, n->tokenval.bindval.item);
++        char *stresc = msLayerEscapePropertyName(layer, n->tokenval.bindval.item);
+         nOutSize = strlen(stresc) + 30;
+         out = (char *)msSmallMalloc(nOutSize);
+ 
+@@ -2078,26 +2078,26 @@ char *msOGRGetToken(layerObj* layer, tokenListNodeObjPtr *node) {
+         // prevent using database indexes, such as for SQlite
+         if( type != NULL && EQUAL(type, "Character") )
+         {
+-            snprintf(out, nOutSize, "%s", stresc);
++            snprintf(out, nOutSize, "\"%s\"", stresc);
+         }
+         else
+         {
+-            snprintf(out, nOutSize, "CAST(%s AS text)", stresc);
++            snprintf(out, nOutSize, "CAST(\"%s\" AS text)", stresc);
+         }
+         msFree(stresc);
+         break;
+     }
+     case MS_TOKEN_BINDING_TIME: {
+         // won't get here unless col is parsed as time and they are not
+-        char *stresc = msOGRGetQuotedItem(layer, n->tokenval.bindval.item);
++        char *stresc = msLayerEscapePropertyName(layer, n->tokenval.bindval.item);
+         nOutSize = strlen(stresc)+ 10;
+         out = (char *)msSmallMalloc(nOutSize);
+-        snprintf(out, nOutSize, "%s", stresc);
++        snprintf(out, nOutSize, "\"%s\"", stresc);
+         msFree(stresc);
+         break;
+     }
+     case MS_TOKEN_BINDING_SHAPE: {
+-        char *stresc = msOGRGetQuotedItem(layer, OGR_L_GetGeometryColumn(info->hLayer)); // which geom field??
++        char *stresc = msLayerEscapePropertyName(layer, OGR_L_GetGeometryColumn(info->hLayer)); // which geom field??
+         nOutSize = strlen(stresc)+ 10;
+         out = (char *)msSmallMalloc(nOutSize);
+         snprintf(out, nOutSize, "%s", stresc);
+@@ -3783,8 +3783,11 @@ static std::string msOGRTranslatePartialInternal(layerObj* layer,
+         case MS_TOKEN_BINDING_STRING:
+         case MS_TOKEN_BINDING_TIME:
+         {
+-            char* pszTmp = msOGRGetQuotedItem(layer, expr->m_osVal.c_str());
+-            std::string osRet(pszTmp);
++            char *pszTmp = msLayerEscapePropertyName(layer, expr->m_osVal.c_str());
++            std::string osRet;
++            osRet += '"';
++            osRet += pszTmp;
++            osRet += '"';
+             msFree(pszTmp);
+             return osRet;
+         }
+diff --git a/mapserver.h b/mapserver.h
+index e811735..6c2dde7 100755
+--- a/mapserver.h
++++ b/mapserver.h
+@@ -2358,6 +2358,7 @@ void msPopulateTextSymbolForLabelAndString(textSymbolObj *ts, labelObj *l, char
+   MS_DLL_EXPORT int msUTF8ToUniChar(const char *str, unsigned int *chPtr); /* maptclutf.c */
+   MS_DLL_EXPORT char* msStringEscape( const char * pszString );
+   MS_DLL_EXPORT int msStringInArray( const char * pszString, char **array, int numelements);
++  void msStringUnescape(char *pszString, char chEscapeChar);
+ 
+   typedef struct msStringBuffer msStringBuffer;
+   MS_DLL_EXPORT msStringBuffer* msStringBufferAlloc(void);
+diff --git a/mapstring.cpp b/mapstring.cpp
+index 64a7ca8..f4d339a 100644
+--- a/mapstring.cpp
++++ b/mapstring.cpp
+@@ -2509,3 +2509,24 @@ int msStringBufferAppend(msStringBuffer* sb, const char* pszAppendedString)
+     sb->length += nAppendLen;
+     return MS_SUCCESS;
+ }
++
++/************************************************************************/
++/*                           msStringUnescape()                         */
++/************************************************************************/
++
++/** Modify in place pszString such that a sequence of two consecutive
++ * chEscapeChar is replaced by a single one.
++ * Does the reverse of FLTEscapePropertyName()
++ */
++void msStringUnescape(char *pszString, char chEscapeChar) {
++  char *pszDest = pszString;
++  for (; *pszString; ++pszString, ++pszDest) {
++    if (pszString[0] == chEscapeChar && pszString[1] == chEscapeChar) {
++      *pszDest = chEscapeChar;
++      ++pszString;
++    } else {
++      *pszDest = *pszString;
++    }
++  }
++  *pszDest = 0;
++}
diff -Nru --exclude 9999-Update-maplexer.c.patch mapserver-8.0.0/debian/patches/series mapserver-8.0.0/debian/patches/series
--- mapserver-8.0.0/debian/patches/series	2022-11-03 19:47:05.000000000 +0100
+++ mapserver-8.0.0/debian/patches/series	2026-03-23 15:02:59.000000000 +0100
@@ -2,3 +2,8 @@
 java-hardening.patch
 interpreter-path.path
 setuptools.patch
+0005-maplexer.l-avoid-non-null-terminated-msyystring_buff.patch
+0006-maplexer.l-fix-heap-buffer-overflow-issues-with-NUL-.patch
+0007-mapfile-parser-fix-double-free-when-included-file-do.patch
+CVE-2025-59431.patch
+9999-Update-maplexer.c.patch
diff -Nru --exclude 9999-Update-maplexer.c.patch mapserver-8.0.0/debian/salsa-ci.yml mapserver-8.0.0/debian/salsa-ci.yml
--- mapserver-8.0.0/debian/salsa-ci.yml	1970-01-01 01:00:00.000000000 +0100
+++ mapserver-8.0.0/debian/salsa-ci.yml	2026-03-23 15:02:59.000000000 +0100
@@ -0,0 +1,9 @@
+---
+include:
+  - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml
+
+variables:
+  RELEASE: 'bookworm'
+  SALSA_CI_DISABLE_LINTIAN: 1
+  SALSA_CI_DISABLE_REPROTEST: 1
+  SALSA_CI_DISABLE_BLHC: 1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 9999-Update-maplexer.c.patch.gz
Type: application/gzip
Size: 39700 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20260323/8417e0e4/attachment-0001.gz>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20260323/8417e0e4/attachment-0001.sig>


More information about the Pkg-grass-devel mailing list