Index: generic/tclEncoding.c ================================================================== --- generic/tclEncoding.c +++ generic/tclEncoding.c @@ -2502,11 +2502,11 @@ UtfToUtf16Proc( ClientData clientData, /* != NULL means LE, == NUL means BE */ const char *src, /* Source string in UTF-8. */ int srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ - Tcl_EncodingState *statePtr,/* Place for conversion routine to store state + TCL_UNUSED(Tcl_EncodingState *),/* Place for conversion routine to store state * information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst, /* Output buffer in which converted string is @@ -2525,15 +2525,12 @@ * correspond to the bytes stored in the * output buffer. */ { const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd; int result, numChars; - Tcl_UniChar *chPtr = (Tcl_UniChar *) statePtr; + int ch; - if (flags & TCL_ENCODING_START) { - *statePtr = 0; - } srcStart = src; srcEnd = src + srcLen; srcClose = srcEnd; if ((flags & TCL_ENCODING_END) == 0) { srcClose -= TCL_UTF_MAX; @@ -2542,11 +2539,11 @@ dstStart = dst; dstEnd = dst + dstLen - sizeof(Tcl_UniChar); result = TCL_OK; for (numChars = 0; src < srcEnd; numChars++) { - if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) { + if ((src > srcClose) && (!TclUCS4Complete(src, srcEnd - src))) { /* * If there is more string to follow, this will ensure that the * last UTF-8 character in the source buffer hasn't been cut off. */ @@ -2555,42 +2552,32 @@ } if (dst > dstEnd) { result = TCL_CONVERT_NOSPACE; break; } - src += TclUtfToUniChar(src, chPtr); + src += TclUtfToUCS4(src, &ch); if (clientData) { -#if TCL_UTF_MAX > 3 - if (*chPtr <= 0xFFFF) { - *dst++ = (*chPtr & 0xFF); - *dst++ = (*chPtr >> 8); - } else { - *dst++ = (((*chPtr - 0x10000) >> 10) & 0xFF); - *dst++ = (((*chPtr - 0x10000) >> 18) & 0x3) | 0xD8; - *dst++ = (*chPtr & 0xFF); - *dst++ = ((*chPtr & 0x3) >> 8) | 0xDC; - } -#else - *dst++ = (*chPtr & 0xFF); - *dst++ = (*chPtr >> 8); -#endif - } else { -#if TCL_UTF_MAX > 3 - if (*chPtr <= 0xFFFF) { - *dst++ = (*chPtr >> 8); - *dst++ = (*chPtr & 0xFF); - } else { - *dst++ = ((*chPtr & 0x3) >> 8) | 0xDC; - *dst++ = (*chPtr & 0xFF); - *dst++ = (((*chPtr - 0x10000) >> 18) & 0x3) | 0xD8; - *dst++ = (((*chPtr - 0x10000) >> 10) & 0xFF); - } -#else - *dst++ = (*chPtr >> 8); - *dst++ = (*chPtr & 0xFF); -#endif + if (ch <= 0xFFFF) { + *dst++ = (ch & 0xFF); + *dst++ = (ch >> 8); + } else { + *dst++ = (((ch - 0x10000) >> 10) & 0xFF); + *dst++ = (((ch - 0x10000) >> 18) & 0x3) | 0xD8; + *dst++ = (ch & 0xFF); + *dst++ = ((ch & 0x3) >> 8) | 0xDC; + } + } else { + if (ch <= 0xFFFF) { + *dst++ = (ch >> 8); + *dst++ = (ch & 0xFF); + } else { + *dst++ = ((ch & 0x3) >> 8) | 0xDC; + *dst++ = (ch & 0xFF); + *dst++ = (((ch - 0x10000) >> 18) & 0x3) | 0xD8; + *dst++ = (((ch - 0x10000) >> 10) & 0xFF); + } } } *srcReadPtr = src - srcStart; *dstWrotePtr = dst - dstStart; *dstCharsPtr = numChars; @@ -2636,14 +2623,11 @@ * correspond to the bytes stored in the * output buffer. */ { const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd; int result, numChars; -#if TCL_UTF_MAX <= 3 - int len; -#endif - Tcl_UniChar ch = 0; + int ch; srcStart = src; srcEnd = src + srcLen; srcClose = srcEnd; if ((flags & TCL_ENCODING_END) == 0) { @@ -2653,11 +2637,11 @@ dstStart = dst; dstEnd = dst + dstLen - sizeof(Tcl_UniChar); result = TCL_OK; for (numChars = 0; src < srcEnd; numChars++) { - if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) { + if ((src > srcClose) && (!TclUCS4Complete(src, srcEnd - src))) { /* * If there is more string to follow, this will ensure that the * last UTF-8 character in the source buffer hasn't been cut off. */ @@ -2666,22 +2650,18 @@ } if (dst > dstEnd) { result = TCL_CONVERT_NOSPACE; break; } -#if TCL_UTF_MAX <= 3 - src += (len = TclUtfToUniChar(src, &ch)); - if ((ch >= 0xD800) && (len < 3)) { - src += TclUtfToUniChar(src, &ch); + src += TclUtfToUCS4(src, &ch); + if (ch & ~0xFFFF) { + if (flags & TCL_ENCODING_STOPONERROR) { + result = TCL_CONVERT_UNKNOWN; + break; + } ch = 0xFFFD; } -#else - src += TclUtfToUniChar(src, &ch); - if (ch > 0xFFFF) { - ch = 0xFFFD; - } -#endif /* * Need to handle this in a way that won't cause misalignment by * casting dst to a Tcl_UniChar. [Bug 1122671] */ @@ -2850,11 +2830,11 @@ * correspond to the bytes stored in the * output buffer. */ { const char *srcStart, *srcEnd, *srcClose; const char *dstStart, *dstEnd, *prefixBytes; - Tcl_UniChar ch = 0; + int ch; int result, len, word, numChars; TableEncodingData *dataPtr = (TableEncodingData *)clientData; const unsigned short *const *fromUnicode; result = TCL_OK; @@ -2871,36 +2851,26 @@ dstStart = dst; dstEnd = dst + dstLen - 1; for (numChars = 0; src < srcEnd; numChars++) { - if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) { + if ((src > srcClose) && (!TclUCS4Complete(src, srcEnd - src))) { /* * If there is more string to follow, this will ensure that the * last UTF-8 character in the source buffer hasn't been cut off. */ result = TCL_CONVERT_MULTIBYTE; break; } - len = TclUtfToUniChar(src, &ch); - -#if TCL_UTF_MAX > 3 - /* - * This prevents a crash condition. More evaluation is required for - * full support of int Tcl_UniChar. [Bug 1004065] - */ - - if (ch & 0xFFFF0000) { - word = 0; - } else -#else - if (!len) { - word = 0; - } else -#endif - word = fromUnicode[(ch >> 8)][ch & 0xFF]; + len = TclUtfToUCS4(src, &ch); + + if (ch & ~0xFFFF) { + word = 0; + } else { + word = fromUnicode[(ch >> 8)][ch & 0xFF]; + } if ((word == 0) && (ch != 0)) { if (flags & TCL_ENCODING_STOPONERROR) { result = TCL_CONVERT_UNKNOWN; break; @@ -3052,11 +3022,11 @@ * output buffer. */ { const char *srcStart, *srcEnd, *srcClose; const char *dstStart, *dstEnd; int result = TCL_OK, numChars; - Tcl_UniChar ch = 0; + int ch; srcStart = src; srcEnd = src + srcLen; srcClose = srcEnd; if ((flags & TCL_ENCODING_END) == 0) { @@ -3067,42 +3037,35 @@ dstEnd = dst + dstLen - 1; for (numChars = 0; src < srcEnd; numChars++) { int len; - if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) { + if ((src > srcClose) && (!TclUCS4Complete(src, srcEnd - src))) { /* * If there is more string to follow, this will ensure that the * last UTF-8 character in the source buffer hasn't been cut off. */ result = TCL_CONVERT_MULTIBYTE; break; } - len = TclUtfToUniChar(src, &ch); + len = TclUtfToUCS4(src, &ch); /* * Check for illegal characters. */ - if (ch > 0xFF -#if TCL_UTF_MAX <= 3 - || ((ch >= 0xD800) && (len < 3)) -#endif - ) { + if (ch > 0xFF) { if (flags & TCL_ENCODING_STOPONERROR) { result = TCL_CONVERT_UNKNOWN; break; } -#if TCL_UTF_MAX <= 3 - if ((ch >= 0xD800) && (len < 3)) len = 4; -#endif /* * Plunge on, using '?' as a fallback character. */ - ch = (Tcl_UniChar) '?'; + ch = '?'; } if (dst > dstEnd) { result = TCL_CONVERT_NOSPACE; break; @@ -3417,11 +3380,11 @@ const char *dstStart, *dstEnd; int state, result, numChars; const TableEncodingData *tableDataPtr; const char *tablePrefixBytes; const unsigned short *const *tableFromUnicode; - Tcl_UniChar ch = 0; + int ch; result = TCL_OK; srcStart = src; srcEnd = src + srcLen; @@ -3459,31 +3422,39 @@ for (numChars = 0; src < srcEnd; numChars++) { unsigned len; int word; - if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) { + if ((src > srcClose) && (!TclUCS4Complete(src, srcEnd - src))) { /* * If there is more string to follow, this will ensure that the * last UTF-8 character in the source buffer hasn't been cut off. */ result = TCL_CONVERT_MULTIBYTE; break; } - len = TclUtfToUniChar(src, &ch); - word = tableFromUnicode[(ch >> 8)][ch & 0xFF]; + len = TclUtfToUCS4(src, &ch); + if (ch & ~0xFFFF) { + word = 0; + } else { + word = tableFromUnicode[(ch >> 8)][ch & 0xFF]; + } if ((word == 0) && (ch != 0)) { int oldState; const EscapeSubTable *subTablePtr; oldState = state; for (state = 0; state < dataPtr->numSubTables; state++) { encodingPtr = GetTableEncoding(dataPtr, state); tableDataPtr = (const TableEncodingData *)encodingPtr->clientData; - word = tableDataPtr->fromUnicode[(ch >> 8)][ch & 0xFF]; + if (ch & ~0xFFFF) { + word = 0; + } else { + word = tableDataPtr->fromUnicode[(ch >> 8)][ch & 0xFF]; + } if (word != 0) { break; } }