summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpooryorick <com.digitalsmarties@pooryorick.com>2023-03-22 17:01:25 (GMT)
committerpooryorick <com.digitalsmarties@pooryorick.com>2023-03-22 17:01:25 (GMT)
commitf8a7412ae36954f8089e4f4f078f8061f37497de (patch)
tree284504d0be36767113bb87fd7b3940097dae4a18
parenteaad662c18c1c672b21a70d24190ce025a0dacfc (diff)
parent494b4c8127e703f7b20f85dbb342921e36a8b557 (diff)
downloadtcl-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.c39
-rw-r--r--win/tclWinTest.c10
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 |