From 071017965f469c88b10467205f30ea3e609e56dc Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Wed, 8 Mar 2017 21:26:55 -0800 Subject: 40763: count wide characters and Cmatcher pointers more sanely in cfp_matcher_pats(), and count characters in pattern_match() the same way to stay in sync Might not fix wide-char matching in completion matcher-lists but should avoid wild pointer crash --- Src/utils.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'Src/utils.c') diff --git a/Src/utils.c b/Src/utils.c index 9669944f6..b3fa3d24c 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -4787,6 +4787,48 @@ unmeta(const char *file_name) return fn; } +/* + * Unmetafy just one character and store the number of bytes it occupied. + */ +/**/ +mod_export convchar_t +unmeta_one(const char *in, int *sz) +{ + convchar_t wc; + int newsz; +#ifdef MULTIBYTE_SUPPORT + int ulen; + mbstate_t wstate; +#endif + + if (!sz) + sz = &newsz; + *sz = 0; + + if (!in || !*in) + return 0; + +#ifdef MULTIBYTE_SUPPORT + memset(&wstate, 0, sizeof(wstate)); + ulen = mb_metacharlenconv_r(in, &wc, &wstate); + while (ulen-- > 0) { + if (in[*sz] == Meta) + *sz += 2; + else + *sz += 1; + } +#else + if (in[0] == Meta) { + *sz = 2; + wc = STOUC(in[1] ^ 32); + } else { + *sz = 1; + wc = STOUC(in[0]); + } +#endif + return wc; +} + /* * Unmetafy and compare two strings, comparing unsigned character values. * "a\0" sorts after "a". -- cgit 1.4.1