summaryrefslogtreecommitdiffstats
path: root/generic/tclEncoding.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclEncoding.c')
-rw-r--r--generic/tclEncoding.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c
index bdf06c9..3f26ab7 100644
--- a/generic/tclEncoding.c
+++ b/generic/tclEncoding.c
@@ -1544,7 +1544,7 @@ Tcl_UtfToExternalDStringEx(
* and loop. Otherwise, return the result we got.
*/
if ((result != TCL_CONVERT_NOSPACE) &&
- !(result == TCL_CONVERT_MULTIBYTE && (flags & TCL_ENCODING_END))) {
+ (result != TCL_CONVERT_MULTIBYTE || (flags & TCL_ENCODING_END))) {
Tcl_Size nBytesProcessed = (src - srcStart);
Tcl_Size i = soFar + encodingPtr->nullSize - 1;
/* Loop as DStringSetLength only stores one nul byte at a time */
@@ -4067,6 +4067,30 @@ EscapeToUtfProc(
numChars++;
}
+ if ((flags & TCL_ENCODING_END) && (result == TCL_CONVERT_MULTIBYTE)) {
+ /* We have a code fragment left-over at the end */
+ if (dst > dstEnd) {
+ result = TCL_CONVERT_NOSPACE;
+ } else {
+ /* destination is not full, so we really are at the end now */
+ if (PROFILE_STRICT(flags)) {
+ result = TCL_CONVERT_SYNTAX;
+ } else {
+ /*
+ * PROFILE_REPLACE or PROFILE_TCL8. The latter is treated
+ * similar to former because Tcl8 was broken in this regard
+ * as it just ignored the byte and truncated which is really
+ * a no-no as per Unicode recommendations.
+ */
+ result = TCL_OK;
+ dst += Tcl_UniCharToUtf(UNICODE_REPLACE_CHAR, dst);
+ numChars++;
+ /* TCL_CONVERT_MULTIBYTE means all source consumed */
+ src = srcEnd;
+ }
+ }
+ }
+
*statePtr = (Tcl_EncodingState) INT2PTR(state);
*srcReadPtr = src - srcStart;
*dstWrotePtr = dst - dstStart;