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 +++++++++++++++++++++++++++++++++++++++++++ pith/charconv/utf8.h | 1 + 2 files changed, 44 insertions(+) (limited to 'pith/charconv') 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 /* diff --git a/pith/charconv/utf8.h b/pith/charconv/utf8.h index f9597cbf..954821cc 100644 --- a/pith/charconv/utf8.h +++ b/pith/charconv/utf8.h @@ -66,6 +66,7 @@ UCS *ucs4_particular_width(UCS*, int); UCS *utf8_to_ucs4_cpystr(char *); char *ucs4_to_utf8_cpystr(UCS *); char *ucs4_to_utf8_cpystr_n(UCS *, int); +char *ucs4_to_utf8_n_cpystr(UCS *, int); #ifdef _WINDOWS LPTSTR utf8_to_lptstr(LPSTR); LPSTR lptstr_to_utf8(LPTSTR); -- cgit v1.2.3-70-g09d2