From e10411bf0ecb248b65ca83882e945e15f906a6d4 Mon Sep 17 00:00:00 2001 From: Eduardo Chappa Date: Mon, 31 May 2021 17:18:47 -0600 Subject: * Bug fix: Memory corruption when alpine searches for a string that is an incomplete utf8 string in a local folder. This could happen by chopping a string to make it fit a buffer without regard to its content. We fix the string so that chopping it does not damage it. Reported by Andrew. --- pith/charconv/utf8.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'pith/charconv/utf8.c') diff --git a/pith/charconv/utf8.c b/pith/charconv/utf8.c index 6b1e2e9d..ee5ab852 100644 --- a/pith/charconv/utf8.c +++ b/pith/charconv/utf8.c @@ -683,6 +683,49 @@ ucs4_to_utf8_cpystr_n(UCS *ucs4src, int ucs4src_len) return ((char *) ret); } +/* + * Similar to above but copy what is possible to a + * string of a size at most the given retlen. + */ +char * +ucs4_to_utf8_n_cpystr(UCS *ucs4src, int retlen) +{ + unsigned char *ret = NULL; + unsigned char *writeptr; + int i, oldlen, len; + + if(!ucs4src) + return NULL; + + /* + * Over-allocate and then resize at the end. + */ + + /* count characters in source */ + for(i = 0; ucs4src[i]; i++) + ; + + ret = (unsigned char *) fs_get((6*i + 1) * sizeof(unsigned char)); + memset(ret, 0, (6*i + 1) * sizeof(unsigned char)); + + writeptr = ret; + oldlen = len = 0; + for(i = 0; ucs4src[i] && (len < retlen); i++){ + oldlen = len; + writeptr = utf8_put(writeptr, (unsigned long) ucs4src[i]); + len = strlen(ret); + } + if(len > retlen){ + ret[oldlen] = '\0'; + len = oldlen; + } + + /* get rid of excess size */ + fs_resize((void **) &ret, (len + 1) * sizeof(unsigned char)); + + return ((char *) ret); +} + #ifdef _WINDOWS /* -- cgit v1.2.3-54-g00ecf