diff options
| -rw-r--r-- | doc/GetIndex.3 | 5 | ||||
| -rw-r--r-- | doc/try.n | 2 | ||||
| -rw-r--r-- | generic/tcl.decls | 2 | ||||
| -rw-r--r-- | generic/tclDecls.h | 9 | ||||
| -rw-r--r-- | generic/tclExecute.c | 6 | ||||
| -rw-r--r-- | generic/tclIndexObj.c | 41 | ||||
| -rw-r--r-- | generic/tclStringObj.c | 4 | ||||
| -rw-r--r-- | generic/tclTest.c | 13 |
8 files changed, 54 insertions, 28 deletions
diff --git a/doc/GetIndex.3 b/doc/GetIndex.3 index 1af1663..fa8455a 100644 --- a/doc/GetIndex.3 +++ b/doc/GetIndex.3 @@ -55,9 +55,10 @@ Null-terminated string describing what is being looked up, such as OR-ed combination of bits providing additional information for operation. The only bits that are currently defined are \fBTCL_EXACT\fR , \fBTCL_INDEX_TEMP_TABLE\fR, and \fBTCL_INDEX_NULL_OK\fR. -.AP int *indexPtr out +.AP enum|char|short|int|long *indexPtr out The index of the string in \fItablePtr\fR that matches the value of -\fIobjPtr\fR is returned here. +\fIobjPtr\fR is returned here. The variable can be any integer type, +signed or unsigned, char, short, long or long long. It can also be an enum. .BE .SH DESCRIPTION .PP @@ -87,7 +87,7 @@ Handle different reasons for a file to not be openable for reading: .PP .CS \fBtry\fR { - set f [open /some/file/name w] + set f [open /some/file/name r] } \fBtrap\fR {POSIX EISDIR} {} { puts "failed to open /some/file/name: it's a directory" } \fBtrap\fR {POSIX ENOENT} {} { diff --git a/generic/tcl.decls b/generic/tcl.decls index bd9800a..c137a88 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -1092,7 +1092,7 @@ declare 303 { declare 304 { int Tcl_GetIndexFromObjStruct(Tcl_Interp *interp, Tcl_Obj *objPtr, const void *tablePtr, int offset, const char *msg, int flags, - int *indexPtr) + void *indexPtr) } declare 305 { void *Tcl_GetThreadData(Tcl_ThreadDataKey *keyPtr, int size) diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 6ca7633..4995f74 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -945,7 +945,7 @@ EXTERN void Tcl_GetEncodingNames(Tcl_Interp *interp); EXTERN int Tcl_GetIndexFromObjStruct(Tcl_Interp *interp, Tcl_Obj *objPtr, const void *tablePtr, int offset, const char *msg, int flags, - int *indexPtr); + void *indexPtr); /* 305 */ EXTERN void * Tcl_GetThreadData(Tcl_ThreadDataKey *keyPtr, int size); @@ -2287,7 +2287,7 @@ typedef struct TclStubs { Tcl_Encoding (*tcl_GetEncoding) (Tcl_Interp *interp, const char *name); /* 301 */ const char * (*tcl_GetEncodingName) (Tcl_Encoding encoding); /* 302 */ void (*tcl_GetEncodingNames) (Tcl_Interp *interp); /* 303 */ - int (*tcl_GetIndexFromObjStruct) (Tcl_Interp *interp, Tcl_Obj *objPtr, const void *tablePtr, int offset, const char *msg, int flags, int *indexPtr); /* 304 */ + int (*tcl_GetIndexFromObjStruct) (Tcl_Interp *interp, Tcl_Obj *objPtr, const void *tablePtr, int offset, const char *msg, int flags, void *indexPtr); /* 304 */ void * (*tcl_GetThreadData) (Tcl_ThreadDataKey *keyPtr, int size); /* 305 */ Tcl_Obj * (*tcl_GetVar2Ex) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 306 */ ClientData (*tcl_InitNotifier) (void); /* 307 */ @@ -4209,6 +4209,7 @@ extern const TclStubs *tclStubsPtr; #define Tcl_GetUnicode(objPtr) \ Tcl_GetUnicodeFromObj(objPtr, (int *)NULL) #undef Tcl_GetBytesFromObj +#undef Tcl_GetIndexFromObjStruct #ifdef TCL_NO_DEPRECATED #undef Tcl_GetStringFromObj #undef Tcl_GetUnicodeFromObj @@ -4217,6 +4218,8 @@ extern const TclStubs *tclStubsPtr; #if defined(USE_TCL_STUBS) #define Tcl_GetBytesFromObj(interp, objPtr, sizePtr) \ (sizeof(*sizePtr) <= sizeof(int) ? tclStubsPtr->tclGetBytesFromObj(interp, objPtr, (int *)sizePtr) : tclStubsPtr->tcl_GetBytesFromObj(interp, objPtr, (size_t *)sizePtr)) +#define Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, indexPtr) \ + (tclStubsPtr->tcl_GetIndexFromObjStruct((interp), (objPtr), (tablePtr), (offset), (msg), (flags)|(int)(sizeof(*indexPtr)<<8), (indexPtr))) #ifdef TCL_NO_DEPRECATED #define Tcl_GetStringFromObj(objPtr, sizePtr) \ (sizeof(*sizePtr) <= sizeof(int) ? tclStubsPtr->tcl_GetStringFromObj(objPtr, (int *)sizePtr) : tclStubsPtr->tclGetStringFromObj(objPtr, (size_t *)sizePtr)) @@ -4228,6 +4231,8 @@ extern const TclStubs *tclStubsPtr; #else #define Tcl_GetBytesFromObj(interp, objPtr, sizePtr) \ (sizeof(*sizePtr) <= sizeof(int) ? (TclGetBytesFromObj)(interp, objPtr, (int *)sizePtr) : (Tcl_GetBytesFromObj)(interp, objPtr, (size_t *)sizePtr)) +#define Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, indexPtr) \ + ((Tcl_GetIndexFromObjStruct)((interp), (objPtr), (tablePtr), (offset), (msg), (flags)|(int)(sizeof(*indexPtr)<<8), (indexPtr))) #ifdef TCL_NO_DEPRECATED #define Tcl_GetStringFromObj(objPtr, sizePtr) \ (sizeof(*sizePtr) <= sizeof(int) ? (Tcl_GetStringFromObj)(objPtr, (int *)sizePtr) : (TclGetStringFromObj)(objPtr, (size_t *)sizePtr)) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 73bd0e9..bbb7dee 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -6017,10 +6017,10 @@ TEBCresume( * Handle shifts within the native long range. */ - if ((size_t) shift < CHAR_BIT*sizeof(long) && (w1 != 0) + if (((size_t) shift < CHAR_BIT*sizeof(long)) && !((w1>0 ? w1 : ~w1) & - -(1L<<(CHAR_BIT*sizeof(long) - 1 - shift)))) { - wResult = w1 << shift; + -(1UL<<(CHAR_BIT*sizeof(long) - 1 - shift)))) { + wResult = (unsigned long)w1 << shift; goto wideResultOfArithmetic; } } diff --git a/generic/tclIndexObj.c b/generic/tclIndexObj.c index c6dd15a..cb376f3 100644 --- a/generic/tclIndexObj.c +++ b/generic/tclIndexObj.c @@ -73,7 +73,7 @@ typedef struct { #define NEXT_ENTRY(table, offset) \ (&(STRING_AT(table, offset))) #define EXPAND_OF(indexRep) \ - STRING_AT((indexRep)->tablePtr, (indexRep)->offset*(indexRep)->index) + (((indexRep)->index >= 0) ? STRING_AT((indexRep)->tablePtr, (indexRep)->offset*(indexRep)->index) : "") /* *---------------------------------------------------------------------- @@ -249,6 +249,7 @@ GetIndexFromObjList( *---------------------------------------------------------------------- */ +#undef Tcl_GetIndexFromObjStruct int Tcl_GetIndexFromObjStruct( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ @@ -262,7 +263,7 @@ Tcl_GetIndexFromObjStruct( const char *msg, /* Identifying word to use in error * messages. */ int flags, /* 0, TCL_EXACT, TCL_INDEX_TEMP_TABLE or TCL_INDEX_NULL_OK */ - int *indexPtr) /* Place to store resulting integer index. */ + void *indexPtr) /* Place to store resulting index. */ { int index, idx, numAbbrev; const char *key, *p1; @@ -280,16 +281,15 @@ Tcl_GetIndexFromObjStruct( * See if there is a valid cached result from a previous lookup. */ - if (!objPtr && (flags & TCL_INDEX_NULL_OK)) { - *indexPtr = -1; - return TCL_OK; - } else if (objPtr && !(flags & TCL_INDEX_TEMP_TABLE)) { + if (objPtr && !(flags & TCL_INDEX_TEMP_TABLE)) { irPtr = TclFetchInternalRep(objPtr, &indexType); if (irPtr) { indexRep = (IndexRep *)irPtr->twoPtrValue.ptr1; - if (indexRep->tablePtr==tablePtr && indexRep->offset==offset) { - *indexPtr = indexRep->index; - return TCL_OK; + if ((indexRep->tablePtr == tablePtr) + && (indexRep->offset == offset) + && (indexRep->index >= 0)) { + index = indexRep->index; + goto uncachedDone; } } } @@ -304,8 +304,7 @@ Tcl_GetIndexFromObjStruct( numAbbrev = 0; if (!*key && (flags & TCL_INDEX_NULL_OK)) { - *indexPtr = -1; - return TCL_OK; + goto uncachedDone; } /* * Scan the table looking for one of: @@ -351,7 +350,7 @@ Tcl_GetIndexFromObjStruct( * operation. */ - if (objPtr && !(flags & TCL_INDEX_TEMP_TABLE)) { + if (objPtr && (index >= 0) && !(flags & TCL_INDEX_TEMP_TABLE)) { irPtr = TclFetchInternalRep(objPtr, &indexType); if (irPtr) { indexRep = (IndexRep *)irPtr->twoPtrValue.ptr1; @@ -367,7 +366,23 @@ Tcl_GetIndexFromObjStruct( indexRep->index = index; } - *indexPtr = index; + uncachedDone: + if ((flags>>8) & (int)~sizeof(int)) { + if ((flags>>8) == sizeof(uint64_t)) { + *(uint64_t *)indexPtr = index; + return TCL_OK; + } else if ((flags>>8) == sizeof(uint32_t)) { + *(uint32_t *)indexPtr = index; + return TCL_OK; + } else if ((flags>>8) == sizeof(uint16_t)) { + *(uint16_t *)indexPtr = index; + return TCL_OK; + } else if ((flags>>8) == sizeof(uint8_t)) { + *(uint8_t *)indexPtr = index; + return TCL_OK; + } + } + *(int *)indexPtr = index; return TCL_OK; error: diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 4735f43..428f758 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1674,10 +1674,10 @@ AppendUtfToUtfRep( objPtr->length = 0; } oldLength = objPtr->length; - newLength = numBytes + oldLength; - if (newLength < 0) { + if (numBytes > INT_MAX - oldLength) { Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); } + newLength = numBytes + oldLength; stringPtr = GET_STRING(objPtr); if (newLength > stringPtr->allocated) { diff --git a/generic/tclTest.c b/generic/tclTest.c index 0ac79a6..1c9e605 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -6285,7 +6285,8 @@ TestGetIndexFromObjStructObjCmd( const char *const ary[] = { "a", "b", "c", "d", "ee", "ff", NULL, NULL }; - int idx,target, flags = 0; + int target, flags = 0; + signed char idx[8]; if (objc != 3 && objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, "argument targetvalue ?flags?"); @@ -6297,13 +6298,17 @@ TestGetIndexFromObjStructObjCmd( if ((objc > 3) && (Tcl_GetIntFromObj(interp, objv[3], &flags) != TCL_OK)) { return TCL_ERROR; } + memset(idx, 85, sizeof(idx)); if (Tcl_GetIndexFromObjStruct(interp, (Tcl_GetString(objv[1])[0] ? objv[1] : NULL), ary, 2*sizeof(char *), - "dummy", flags, &idx) != TCL_OK) { + "dummy", flags, &idx[0]) != TCL_OK) { return TCL_ERROR; } - if (idx != target) { + if (idx[1] != 85) { + Tcl_AppendResult(interp, "Tcl_GetIndexFromObjStruct overwrites size", NULL); + return TCL_ERROR; + } else if (idx[0] != target) { char buffer[64]; - sprintf(buffer, "%d", idx); + sprintf(buffer, "%d", idx[0]); Tcl_AppendResult(interp, "index value comparison failed: got ", buffer, NULL); sprintf(buffer, "%d", target); |
