From 523ea309ce99ee289cf8bea083fbc10f7d0f5320 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 25 Jan 2019 13:43:59 +0000 Subject: Do not assume that literals have a non-NULL bytes field; user code could purge it. --- generic/tclLiteral.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/generic/tclLiteral.c b/generic/tclLiteral.c index fb7c28a..b6c45ac 100644 --- a/generic/tclLiteral.c +++ b/generic/tclLiteral.c @@ -198,25 +198,36 @@ TclCreateLiteral( for (globalPtr=globalTablePtr->buckets[globalHash] ; globalPtr!=NULL; globalPtr = globalPtr->nextPtr) { objPtr = globalPtr->objPtr; - if ((globalPtr->nsPtr == nsPtr) - && (objPtr->length == length) && ((length == 0) - || ((objPtr->bytes[0] == bytes[0]) - && (memcmp(objPtr->bytes, bytes, (unsigned) length) == 0)))) { + if (globalPtr->nsPtr == nsPtr) { /* - * A literal was found: return it + * Literals should always have UTF-8 representations... but this + * is not guaranteed so we need to be careful anyway. + * + * https://stackoverflow.com/q/54337750/301832 */ - if (newPtr) { - *newPtr = 0; - } - if (globalPtrPtr) { - *globalPtrPtr = globalPtr; - } - if (flags & LITERAL_ON_HEAP) { - ckfree(bytes); + int objLength; + char *objBytes = TclGetStringFromObj(objPtr, &objLength); + + if ((objLength == length) && ((length == 0) + || ((objBytes[0] == bytes[0]) + && (memcmp(objBytes, bytes, (unsigned) length) == 0)))) { + /* + * A literal was found: return it + */ + + if (newPtr) { + *newPtr = 0; + } + if (globalPtrPtr) { + *globalPtrPtr = globalPtr; + } + if (flags & LITERAL_ON_HEAP) { + ckfree(bytes); + } + globalPtr->refCount++; + return objPtr; } - globalPtr->refCount++; - return objPtr; } } if (!newPtr) { -- cgit v0.12 From fa64afb29a232d853b04e8e7bb5ad53c3d02f019 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 26 Jan 2019 16:50:21 +0000 Subject: Replace isspace() -> TclIsSpaceProc() _everywhere_. Change TclIsSpaceProc() and TclIsBareWord so it works with both signed and unsigned characters. Actually, this is not a signature change, as "char" arguments are enlarged to "int" by the C-compiler anyway. --- compat/strtol.c | 2 +- compat/strtoul.c | 2 +- generic/tclBinary.c | 14 +++++++------- generic/tclGetDate.y | 2 +- generic/tclInt.h | 4 ++-- generic/tclParse.c | 4 ++-- generic/tclParse.h | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/compat/strtol.c b/compat/strtol.c index 811006a..b7f6919 100644 --- a/compat/strtol.c +++ b/compat/strtol.c @@ -53,7 +53,7 @@ strtol( */ p = string; - while (isspace(UCHAR(*p))) { + while (TclIsSpaceProc(*p)) { p += 1; } diff --git a/compat/strtoul.c b/compat/strtoul.c index 15587f1..e37eb05 100644 --- a/compat/strtoul.c +++ b/compat/strtoul.c @@ -74,7 +74,7 @@ strtoul( */ p = string; - while (isspace(UCHAR(*p))) { + while (TclIsSpaceProc(*p)) { p += 1; } if (*p == '-') { diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 571eb07..2874ea8 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -2395,7 +2395,7 @@ BinaryDecodeHex( c = *data++; if (!isxdigit((int) c)) { - if (strict || !isspace(c)) { + if (strict || !TclIsSpaceProc(c)) { goto badChar; } i--; @@ -2742,7 +2742,7 @@ BinaryDecodeUu( if (lineLen < 0) { c = *data++; if (c < 32 || c > 96) { - if (strict || !isspace(c)) { + if (strict || !TclIsSpaceProc(c)) { goto badUu; } i--; @@ -2760,7 +2760,7 @@ BinaryDecodeUu( d[i] = c = *data++; if (c < 32 || c > 96) { if (strict) { - if (!isspace(c)) { + if (!TclIsSpaceProc(c)) { goto badUu; } else if (c == '\n') { goto shortUu; @@ -2804,7 +2804,7 @@ BinaryDecodeUu( } else if (c >= 32 && c <= 96) { data--; break; - } else if (strict || !isspace(c)) { + } else if (strict || !TclIsSpaceProc(c)) { goto badUu; } } while (data < dataend); @@ -2934,7 +2934,7 @@ BinaryDecode64( if (c == '=' && i > 1) { value <<= 6; cut++; - } else if (!strict && isspace(c)) { + } else if (!strict && TclIsSpaceProc(c)) { i--; } else { goto bad64; @@ -2954,7 +2954,7 @@ BinaryDecode64( ) { value <<= 6; if (i) cut++; - } else if (strict || !isspace(c)) { + } else if (strict || !TclIsSpaceProc(c)) { goto bad64; } else { i--; @@ -2975,7 +2975,7 @@ BinaryDecode64( goto bad64; } for (; data < dataend; data++) { - if (!isspace(*data)) { + if (!TclIsSpaceProc(*data)) { goto bad64; } } diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y index da4c3fd..ce7c2ce 100644 --- a/generic/tclGetDate.y +++ b/generic/tclGetDate.y @@ -897,7 +897,7 @@ TclDatelex( location->first_column = yyInput - info->dateStart; for ( ; ; ) { - while (isspace(UCHAR(*yyInput))) { + while (TclIsSpaceProc(*yyInput)) { yyInput++; } diff --git a/generic/tclInt.h b/generic/tclInt.h index 03cb5ae..0b67709 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3025,8 +3025,8 @@ MODULE_SCOPE void TclInitNotifier(void); MODULE_SCOPE void TclInitObjSubsystem(void); MODULE_SCOPE void TclInitSubsystems(void); MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp); -MODULE_SCOPE int TclIsSpaceProc(char byte); -MODULE_SCOPE int TclIsBareword(char byte); +MODULE_SCOPE int TclIsSpaceProc(int byte); +MODULE_SCOPE int TclIsBareword(int byte); MODULE_SCOPE Tcl_Obj * TclJoinPath(int elements, Tcl_Obj * const objv[], int forceRelative); MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result); diff --git a/generic/tclParse.c b/generic/tclParse.c index f26f933..74b02ce 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -613,7 +613,7 @@ Tcl_ParseCommand( int TclIsSpaceProc( - char byte) + int byte) { return CHAR_TYPE(byte) & (TYPE_SPACE) || byte == '\n'; } @@ -642,7 +642,7 @@ TclIsSpaceProc( int TclIsBareword( - char byte) + int byte) { if (byte < '0' || byte > 'z') { return 0; diff --git a/generic/tclParse.h b/generic/tclParse.h index 20c609c..9247602 100644 --- a/generic/tclParse.h +++ b/generic/tclParse.h @@ -12,6 +12,6 @@ #define TYPE_CLOSE_BRACK 0x20 #define TYPE_BRACE 0x40 -#define CHAR_TYPE(c) (tclCharTypeTable+128)[(int)(c)] +#define CHAR_TYPE(c) (tclCharTypeTable+128)[(unsigned char)(c)] MODULE_SCOPE const char tclCharTypeTable[]; -- cgit v0.12