summaryrefslogtreecommitdiffstats
path: root/generic/tclUtf.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2018-09-28 09:18:49 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2018-09-28 09:18:49 (GMT)
commit9dabbdf40b10e3f0419d5ad5b96f4d7c3189bc6a (patch)
tree233faf46a3a4bde6f5a4c5ad45db18d7e7cdd69e /generic/tclUtf.c
parent0d36d5f3d85b79ed2c3565112c78bbd18d1a7990 (diff)
parent2f3fc1cfa29f6a4dac413ac62258bfb235feb257 (diff)
downloadtcl-9dabbdf40b10e3f0419d5ad5b96f4d7c3189bc6a.zip
tcl-9dabbdf40b10e3f0419d5ad5b96f4d7c3189bc6a.tar.gz
tcl-9dabbdf40b10e3f0419d5ad5b96f4d7c3189bc6a.tar.bz2
merge core-8-branch
Diffstat (limited to 'generic/tclUtf.c')
-rw-r--r--generic/tclUtf.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/generic/tclUtf.c b/generic/tclUtf.c
index 693e210..c8292a2 100644
--- a/generic/tclUtf.c
+++ b/generic/tclUtf.c
@@ -173,6 +173,13 @@ Tcl_UniCharToUtf(
buf[0] = (char) ((ch >> 18) | 0xF0);
return 4;
}
+ } else if (ch == -1) {
+ if (((buf[0] & 0xF8) == 0xF0) && ((buf[1] & 0xC0) == 0x80)
+ && ((buf[2] & 0xCF) == 0)) {
+ ch = 0xD7C0 + ((buf[0] & 0x07) << 8) + ((buf[1] & 0x3F) << 2)
+ + ((buf[2] & 0x30) >> 4);
+ goto three;
+ }
}
ch = 0xFFFD;
@@ -211,7 +218,7 @@ Tcl_UniCharToUtfDString(
{
const Tcl_UniChar *w, *wEnd;
char *p, *string;
- int oldLength;
+ int oldLength, len = 1;
/*
* UTF-8 string length in bytes will be <= Unicode string length * 4.
@@ -224,9 +231,18 @@ Tcl_UniCharToUtfDString(
p = string;
wEnd = uniStr + uniLength;
for (w = uniStr; w < wEnd; ) {
- p += Tcl_UniCharToUtf(*w, p);
+ if (!len && ((*w & 0xFC00) != 0xDC00)) {
+ /* Special case for handling upper surrogates. */
+ p += Tcl_UniCharToUtf(-1, p);
+ }
+ len = Tcl_UniCharToUtf(*w, p);
+ p += len;
w++;
}
+ if (!len) {
+ /* Special case for handling upper surrogates. */
+ p += Tcl_UniCharToUtf(-1, p);
+ }
Tcl_DStringSetLength(dsPtr, oldLength + (p - string));
return string;
@@ -892,7 +908,7 @@ Tcl_UtfToUpper(
* char to dst if its size is <= the original char.
*/
- if (bytes < TclUtfCount(upChar)) {
+ if ((bytes < TclUtfCount(upChar)) || ((upChar & 0xF800) == 0xD800)) {
memcpy(dst, src, (size_t) bytes);
dst += bytes;
} else {
@@ -955,7 +971,7 @@ Tcl_UtfToLower(
* char to dst if its size is <= the original char.
*/
- if (bytes < TclUtfCount(lowChar)) {
+ if ((bytes < TclUtfCount(lowChar)) || ((lowChar & 0xF800) == 0xD800)) {
memcpy(dst, src, (size_t) bytes);
dst += bytes;
} else {
@@ -1015,7 +1031,7 @@ Tcl_UtfToTitle(
#endif
titleChar = Tcl_UniCharToTitle(titleChar);
- if (bytes < TclUtfCount(titleChar)) {
+ if ((bytes < TclUtfCount(titleChar)) || ((titleChar & 0xF800) == 0xD800)) {
memcpy(dst, src, (size_t) bytes);
dst += bytes;
} else {
@@ -1039,7 +1055,7 @@ Tcl_UtfToTitle(
lowChar = Tcl_UniCharToLower(lowChar);
}
- if (bytes < TclUtfCount(lowChar)) {
+ if ((bytes < TclUtfCount(lowChar)) || ((lowChar & 0xF800) == 0xD800)) {
memcpy(dst, src, (size_t) bytes);
dst += bytes;
} else {