Re: Fwd: report 3/3: latent unterminated buffer in imap_wordcasecmp()

"Kevin J. McCarthy" <[email protected]> Fri, 19 Jun 2026 14:50:04 +0800
Newsgroups gmane.mail.mutt.devel
Message-ID <[email protected]>
On Fri, Jun 19, 2026 at 02:27:15AM -0400, Kurt Hackenberg wrote:
>On Fri, Jun 19, 2026 at 13:37 +0800, Kevin J. McCarthy wrote:
>
>>Ah, sorry, that's right.  I meant to propose ascii_strncasecmp()
>
>I assumed that. Question is, do we have to call some external function 
>to do that caseless compare, or can we code it directly in this 
>function?
>
>    int match;
>
>    for (i = 0; ; i++)
>        if ( !(match = (toupper(a[i]) == toupper(b[i])))
>             || b[i] == '\0' || isspace(b[i]))
>            break;
>
>    return match;
>
>Just whomped up, and untested.

Mutt uses its own ascii_* functions because the built-in ones are 
problematic for some locales.  The isspace() has weird issues too, and I 
just spent some time recently removing it throughout the code.  See 
4fb4575a4bc23a739a16db810c13f2a4942786f8 for instance.

However, I realized this function was confusing me too, because it's not 
just checking if "a" matches the first word in the "b" list.  It's 
returning the comparison value.  :-) My brain was thinking it was 
similar to mechlist_contains() in gsasl.c

We could change the retval of the function to true/false and use the 
ascii_toupper() and IS_ASCII_WS() function in your loop above.  Or keep 
the comparison and just do something like:

   size_t a_len, b_len;

   a_len = mutt_strlen(a);
   b_len = b ? strcspn(b, " \t\n\v\f\r") : 0;
   return ascii_strncasecmp(a, b, MAX(a_len, b_len));

(Also untested)

-- 
Kevin J. McCarthy
GPG Fingerprint: 8975 A9B3 3AA3 7910 385C  5308 ADEF 7684 8031 6BDA
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEiXWpszqjeRA4XFMIre92hIAxa9oFAmo05pwACgkQre92hIAx
a9oZURAA2KxIJo20D3QvNkDiKHvuCRAXE+TRCyAuu2wLdiffidfq/YIoyr0ru3Gh
7G01it+OehY7CdQi0EmQPK4oBYD76er2LGNSPTQtTTdnRJcjX4yCF3VX6mbTipaF
3/94RwNJALp5qOOv7iNaBvTqcwIfKIotjd+pij2mJzQuk1iIN7nZHpt9a1h8+cyp
XP8KrfjN7d6EEcux6HehrqOO0vMJsN0yhBJFxY4ncDEEHLw8r6oG59BmIwOJ0WCV
2j3vb1wToFHLSbIEOEzPIW33o0Z5neBpcpviDU6MSfjvjlEwkE4BAI7eVYDLMw8q
J9teboNH2b+hMBwRINDPb7ow611Uf7zqHukbwmhGlCmmKdXsVBQI9WPyZ79/nL6N
YSA2FAwh9vlj96aIFKXrrYCpx/X4HQdHAaU7NzYf6sbMdk+NcjlZQBE4B3kTD5FT
z2CTbTmls5BOu4ze282M8ojMs4Q8beK1WaMJ5RG4ZlQIkgjAAxDVcEqbUx/APWDl
BLwmn1oh9qz3B0hPSkoJWb6wjOQrUYaJ2EJzvOO7oNtFATJ2AOx0VbNZQ9un5Nw2
Ju2lJ3YaogdUsOnrfjrnzi7TbE3l0TsoCI4o4ZTdaEv7iEUjRAFQ3ZAZnYDMB0aa
c+QyT8iHlPHfYnPNWolyKVZEbsAxJKfb2XfroJ+CJOJqMqe28CQ=
=aNQN
-----END PGP SIGNATURE-----