diff options
author | pooryorick <com.digitalsmarties@pooryorick.com> | 2023-03-22 17:01:25 (GMT) |
---|---|---|
committer | pooryorick <com.digitalsmarties@pooryorick.com> | 2023-03-22 17:01:25 (GMT) |
commit | f8a7412ae36954f8089e4f4f078f8061f37497de (patch) | |
tree | 284504d0be36767113bb87fd7b3940097dae4a18 | |
parent | eaad662c18c1c672b21a70d24190ce025a0dacfc (diff) | |
parent | 494b4c8127e703f7b20f85dbb342921e36a8b557 (diff) | |
download | tcl-f8a7412ae36954f8089e4f4f078f8061f37497de.zip tcl-f8a7412ae36954f8089e4f4f078f8061f37497de.tar.gz tcl-f8a7412ae36954f8089e4f4f078f8061f37497de.tar.bz2 |
Merge trunk bb76745df2: Fix cmdAH-4.3.13.00D80000.solo.utf-32le.tcl8.a testcase
from tip-656-tcl9 branch, when TCL_UTF_MAX=3.
-rw-r--r-- | generic/tclEncoding.c | 39 | ||||
-rw-r--r-- | win/tclWinTest.c | 10 |
2 files changed, 41 insertions, 8 deletions
diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 61e3236..fc3397a 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2545,7 +2545,7 @@ Utf32ToUtfProc( const char *srcStart, *srcEnd; const char *dstEnd, *dstStart; int result, numChars, charLimit = INT_MAX; - int ch, bytesLeft = srcLen % 4; + int ch = 0, bytesLeft = srcLen % 4; flags |= PTR2INT(clientData); if (flags & TCL_ENCODING_CHAR_LIMIT) { @@ -2562,6 +2562,21 @@ Utf32ToUtfProc( srcLen -= bytesLeft; } +#if TCL_UTF_MAX < 4 + /* + * If last code point is a high surrogate, we cannot handle that yet, + * unless we are at the end. + */ + + if (!(flags & TCL_ENCODING_END) && (srcLen >= 4) && + ((src[srcLen - ((flags & TCL_ENCODING_LE)?3:2)] & 0xFC) == 0xD8) && + ((src[srcLen - ((flags & TCL_ENCODING_LE)?2:3)]) == 0) && + ((src[srcLen - ((flags & TCL_ENCODING_LE)?1:4)]) == 0)) { + result = TCL_CONVERT_MULTIBYTE; + srcLen-= 4; + } +#endif + srcStart = src; srcEnd = src + srcLen; @@ -2574,21 +2589,33 @@ Utf32ToUtfProc( break; } +#if TCL_UTF_MAX < 4 + int prev = ch; +#endif if (flags & TCL_ENCODING_LE) { ch = (src[3] & 0xFF) << 24 | (src[2] & 0xFF) << 16 | (src[1] & 0xFF) << 8 | (src[0] & 0xFF); } else { ch = (src[0] & 0xFF) << 24 | (src[1] & 0xFF) << 16 | (src[2] & 0xFF) << 8 | (src[3] & 0xFF); } - if ((unsigned)ch > 0x10FFFF) { +#if TCL_UTF_MAX < 4 + if (((prev & ~0x3FF) == 0xD800) && ((ch & ~0x3FF) != 0xDC00)) { + /* Bug [10c2c17c32]. If Hi surrogate not followed by Lo surrogate, finish 3-byte UTF-8 */ + dst += Tcl_UniCharToUtf(-1, dst); + } +#endif + if ((unsigned)ch > 0x10FFFF) { + ch = 0xFFFD; if (STOPONERROR) { result = TCL_CONVERT_SYNTAX; break; } - ch = 0xFFFD; } else if (((flags & TCL_ENCODING_STRICT) == TCL_ENCODING_STRICT) && ((ch & ~0x7FF) == 0xD800)) { if (STOPONERROR) { result = TCL_CONVERT_SYNTAX; +#if TCL_UTF_MAX < 4 + ch = 0; +#endif break; } } @@ -2606,6 +2633,12 @@ Utf32ToUtfProc( src += sizeof(unsigned int); } +#if TCL_UTF_MAX < 4 + if ((ch & ~0x3FF) == 0xD800) { + /* Bug [10c2c17c32]. If Hi surrogate, finish 3-byte UTF-8 */ + dst += Tcl_UniCharToUtf(-1, dst); + } +#endif if ((flags & TCL_ENCODING_END) && (result == TCL_CONVERT_MULTIBYTE)) { /* We have a single byte left-over at the end */ if (dst > dstEnd) { diff --git a/win/tclWinTest.c b/win/tclWinTest.c index c7abcdc..29bdfe4 100644 --- a/win/tclWinTest.c +++ b/win/tclWinTest.c @@ -398,7 +398,7 @@ TestplatformChmod( const char *nativePath, int pmode) { - /* + /* * Note FILE_DELETE_CHILD missing from dirWriteMask because we do * not want overriding of child's delete setting when testing */ @@ -406,7 +406,7 @@ TestplatformChmod( FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY | STANDARD_RIGHTS_WRITE | DELETE | SYNCHRONIZE; - static const DWORD dirReadMask = + static const DWORD dirReadMask = FILE_READ_ATTRIBUTES | FILE_READ_EA | FILE_LIST_DIRECTORY | STANDARD_RIGHTS_READ | SYNCHRONIZE; /* Note - default user privileges allow ignoring TRAVERSE setting */ @@ -416,7 +416,7 @@ TestplatformChmod( static const DWORD fileWriteMask = FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_WRITE_DATA | FILE_APPEND_DATA | STANDARD_RIGHTS_WRITE | DELETE | SYNCHRONIZE; - static const DWORD fileReadMask = + static const DWORD fileReadMask = FILE_READ_ATTRIBUTES | FILE_READ_EA | FILE_READ_DATA | STANDARD_RIGHTS_READ | SYNCHRONIZE; static const DWORD fileExecuteMask = @@ -450,7 +450,7 @@ TestplatformChmod( if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { goto done; } - + /* Get process SID */ if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &dw) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { @@ -468,7 +468,7 @@ TestplatformChmod( Tcl_Free(aceEntry[nSids].pSid); /* Since we have not ++'ed nSids */ goto done; } - /* + /* * Always include DACL modify rights so we don't get locked out */ aceEntry[nSids].mask = READ_CONTROL | WRITE_DAC | WRITE_OWNER | SYNCHRONIZE | |