Re: [PATCH] Fix incorrect imap_wordcasecmp() comparison for large strings.
Alejandro Colomar via Mutt-dev <[email protected]> Fri, 19 Jun 2026 11:50:49 +0200
| Newsgroups | gmane.mail.mutt.devel |
|---|---|
| Message-ID | <ajUPEJx2Mm-Ejnjd@devuan> |
On 2026-06-19T15:46:44+0800, Kevin J. McCarthy wrote:
> Previously, if "b" was length 127, the loop would terminate after
> copying bytes 0..125. The final for loop increment would set i=126.
> Then, "tmp[i+1] = 0" would nul-terminate the string at byte 127. So
> byte 126 would be unset.
>
> Note that since none of the Capabilities mutt were passing are that
> long, the bug wouldn't matter, but it was a confusing and buggy
> function in any case. :D
>
> Thanks to Acts1631 for the bug report.
>
> Thanks to Alejandro Colomar for his discussion and proposed patches,
> which motivated the use of strcspn() here, along with defining
> ASCII_WS.
>
> Also thanks to Kurt Hackenberg and Ian Collier for their discussion
> and proposals, leading to the removal of the tmp[] array completely.
> ---
>
> I'm tossing this out for review. I have compiled and tested it, but
> I'm tired enough that I probably shouldn't be sending patches right now.
>
> But I'll email this out for semi-official review, and I will take
> another look and test it a bit more over the next few days!
>
> imap/util.c | 23 ++++++-----------------
> lib.h | 1 +
> 2 files changed, 7 insertions(+), 17 deletions(-)
>
> diff --git a/imap/util.c b/imap/util.c
> index 9b6ef7b4..66b41917 100644
> --- a/imap/util.c
> +++ b/imap/util.c
> @@ -880,26 +880,15 @@ void imap_unmunge_mbox_name(IMAP_DATA *idata, char *s)
> FREE(&buf);
> }
>
> -/* imap_wordcasecmp: find word a in word list b */
> +/* imap_wordcasecmp: compares word a against the initial ASCII_WS
> + * delimited word in word list b */
> int imap_wordcasecmp(const char *a, const char *b)
> {
> - char tmp[SHORT_STRING];
> - const char *s = b;
> - int i;
> + size_t a_len, b_len;
>
> - tmp[SHORT_STRING-1] = 0;
> - for (i=0;i < SHORT_STRING-2;i++,s++)
> - {
> - if (!*s || IS_ASCII_WS(*s))
> - {
> - tmp[i] = 0;
> - break;
> - }
> - tmp[i] = *s;
> - }
> - tmp[i+1] = 0;
> -
> - return ascii_strcasecmp(a, tmp);
> + a_len = mutt_strlen(a);
> + b_len = b ? strcspn(b, ASCII_WS) : 0;
> + return ascii_strncasecmp(a, b, MAX(a_len, b_len));
Reviewed-by: Alejandro Colomar <[email protected]>
> }
>
> /*
> diff --git a/lib.h b/lib.h
> index 830459d6..72e3a498 100644
> --- a/lib.h
> +++ b/lib.h
> @@ -113,6 +113,7 @@
> * 0x09-0x0d (\t \n \v \f \r)
> * 0x20 (space)
> */
> +#define ASCII_WS " \t\n\v\f\r"
> #define IS_ASCII_WS(c) ((9 <= (c) && (c) <= 13) || (c) == 32)
>
> #define SKIP_ASCII_WS(c) while (IS_ASCII_WS(*(c))) c++;
> --
> 2.54.0
>
--
<https://www.alejandro-colomar.es>
signature.asc
(application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEES7Jt9u9GbmlWADAi64mZXMKQwqkFAmo1EPMACgkQ64mZXMKQ wqlZ5A/8DwlGHqs1oPte7EVBezgbY3+J5ttadpnzP7ScoFhX01pnGKLZAtoscvDB m58LZDZ9XwqZAMHMT6X16eBPa749wwJAJgXzPZ/GDFfF6pdBj+VgIiMnaCPtp9be jFOCEHwYJza5QbtPr1K9yxQDF8834CwlecCXiZhi8ld7uxTAbTtLy5o0zY2J7hRR 4TZapjwL9WfbWR19uCqg90yaJ06sr74GMi0yi7Az+HyrvyLu+XdJlKMNIL7PAV2p /JiRHW4b+i4Uu8YLywFfFpO5i14pVgoDnolCvZnhDNDS985NEsMhtkj63GHnnqnR B8j04kG0vEIlQsoyIdk21OTCkBLKzkf5dDKzv4t1z8TftF7qd4Yn8GeVdHpSqQBj VR6p+tf04hlWzvQg/bJpZ0CQhplno4NXYcIWYzHc1THtcKUyRv1tw/N94tUfWSr6 5DzX4AQ6xXPNMjNaXufx4THYFIxj9/kxySQEyZM0zoxzQNdq8AkYv0WZ6uv+VxQO b99BKk4F0sjDxD0h7XH+r29RTUKHO59gJFH2OwHiVlg3/8dSxQyVlWzdI99tt4Ap bjtSfUM+IilLmQCrRUwpFfJisrsUqFVU5YznwkSGtsofInYqju1AoF/SL0l0wjbd lEdgrF3Le6Gt/Cb5jVnhYBvZsAR10gvAQ/VHurToPGOJZ1niMCQ= =vp6j -----END PGP SIGNATURE-----