diff options
author | Eduardo Chappa <chappa@washington.edu> | 2021-05-31 17:18:47 -0600 |
---|---|---|
committer | Eduardo Chappa <chappa@washington.edu> | 2021-05-31 17:18:47 -0600 |
commit | e10411bf0ecb248b65ca83882e945e15f906a6d4 (patch) | |
tree | 1a7bedd8085c8dfca3055b5d4b96a2b08414ba8e /pith/charconv | |
parent | f17aaf0dc56c44e220f51f10b898b8c4a20f9dac (diff) | |
download | alpine-e10411bf0ecb248b65ca83882e945e15f906a6d4.tar.xz |
* 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.
Diffstat (limited to 'pith/charconv')
-rw-r--r-- | pith/charconv/utf8.c | 43 | ||||
-rw-r--r-- | pith/charconv/utf8.h | 1 |
2 files changed, 44 insertions, 0 deletions
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); |