diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2018-10-03 19:24:13 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2018-10-03 19:24:13 (GMT) |
commit | 50a13754610c04730f483b8100a8b9c0fccb1e3e (patch) | |
tree | aafde258c1aa77d96056ac741540ffc2f3ad3729 /generic/tclUtf.c | |
parent | 3d5f129cb0f1208fab8b96b4a86777ea25744163 (diff) | |
download | tcl-50a13754610c04730f483b8100a8b9c0fccb1e3e.zip tcl-50a13754610c04730f483b8100a8b9c0fccb1e3e.tar.gz tcl-50a13754610c04730f483b8100a8b9c0fccb1e3e.tar.bz2 |
Tcl_UniCharToUtfDString: Don't allocate too much memory for this function.
Tcl_UtfToUniCharDString: Don't allocate too much memory for this function. And make sure that we never access more than 'length' bytes from the string, not even when encountering invalid UTF-8.
Diffstat (limited to 'generic/tclUtf.c')
-rw-r--r-- | generic/tclUtf.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/generic/tclUtf.c b/generic/tclUtf.c index c2963bf..b33bf5f 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -243,7 +243,7 @@ Tcl_UniCharToUtfDString( */ oldLength = Tcl_DStringLength(dsPtr); - Tcl_DStringSetLength(dsPtr, (oldLength + uniLength + 1) * TCL_UTF_MAX); + Tcl_DStringSetLength(dsPtr, oldLength + (uniLength + 1) * TCL_UTF_MAX); string = Tcl_DStringValue(dsPtr) + oldLength; p = string; @@ -432,17 +432,27 @@ Tcl_UtfToUniCharDString( */ oldLength = Tcl_DStringLength(dsPtr); -/* TODO: fix overreach! */ + Tcl_DStringSetLength(dsPtr, - (int) ((oldLength + length + 1) * sizeof(Tcl_UniChar))); + oldLength + (int) ((length + 1) * sizeof(Tcl_UniChar))); wString = (Tcl_UniChar *) (Tcl_DStringValue(dsPtr) + oldLength); w = wString; - end = src + length; - for (p = src; p < end; ) { + p = src; + end = src + length - TCL_UTF_MAX; + while (p < end) { p += TclUtfToUniChar(p, &ch); *w++ = ch; } + end += TCL_UTF_MAX; + while (p < end) { + if (Tcl_UtfCharComplete(p, end-p)) { + p += TclUtfToUniChar(p, &ch); + } else { + ch = UCHAR(*p++); + } + *w++ = ch; + } *w = '\0'; Tcl_DStringSetLength(dsPtr, (oldLength + ((char *) w - (char *) wString))); |