From 769d959f080ba9349c760f556b1064c47a88b28d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 9 Jan 2013 12:33:45 +0000 Subject: Restore API compatibility with public Tcl_*Scan and Tcl_*Convert functions (changes in private functions are OK) Increase LOCAL_SIZE to 64, and remove two Panic's which cannot occur any more as a result of the improvements. --- generic/tcl.decls | 8 ++++---- generic/tclDecls.h | 16 ++++++++-------- generic/tclDictObj.c | 7 ++----- generic/tclListObj.c | 4 ++-- generic/tclUtil.c | 32 +++++++------------------------- 5 files changed, 23 insertions(+), 44 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index 1084144..fe1d763 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -310,11 +310,11 @@ declare 83 { char *Tcl_Concat(int argc, const char *const *argv) } declare 84 { - int Tcl_ConvertElement(const char *src, char *dst, char flags) + int Tcl_ConvertElement(const char *src, char *dst, int flags) } declare 85 { int Tcl_ConvertCountedElement(const char *src, int length, char *dst, - char flags) + int flags) } declare 86 { int Tcl_CreateAlias(Tcl_Interp *slave, const char *slaveCmd, @@ -778,10 +778,10 @@ declare 217 { void Tcl_ResetResult(Tcl_Interp *interp) } declare 218 { - int Tcl_ScanElement(const char *src, char *flagPtr) + int Tcl_ScanElement(const char *src, int *flagPtr) } declare 219 { - int Tcl_ScanCountedElement(const char *src, int length, char *flagPtr) + int Tcl_ScanCountedElement(const char *src, int length, int *flagPtr) } # Removed in Tcl 9 #declare 220 { diff --git a/generic/tclDecls.h b/generic/tclDecls.h index e6c63b3..0770e98 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -257,10 +257,10 @@ TCLAPI int Tcl_CommandComplete(const char *cmd); TCLAPI char * Tcl_Concat(int argc, const char *const *argv); /* 84 */ TCLAPI int Tcl_ConvertElement(const char *src, char *dst, - char flags); + int flags); /* 85 */ TCLAPI int Tcl_ConvertCountedElement(const char *src, - int length, char *dst, char flags); + int length, char *dst, int flags); /* 86 */ TCLAPI int Tcl_CreateAlias(Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, @@ -625,10 +625,10 @@ TCLAPI void Tcl_Release(ClientData clientData); /* 217 */ TCLAPI void Tcl_ResetResult(Tcl_Interp *interp); /* 218 */ -TCLAPI int Tcl_ScanElement(const char *src, char *flagPtr); +TCLAPI int Tcl_ScanElement(const char *src, int *flagPtr); /* 219 */ TCLAPI int Tcl_ScanCountedElement(const char *src, int length, - char *flagPtr); + int *flagPtr); /* Slot 220 is reserved */ /* 221 */ TCLAPI int Tcl_ServiceAll(void); @@ -1877,8 +1877,8 @@ typedef struct TclStubs { int (*tcl_Close) (Tcl_Interp *interp, Tcl_Channel chan); /* 81 */ int (*tcl_CommandComplete) (const char *cmd); /* 82 */ char * (*tcl_Concat) (int argc, const char *const *argv); /* 83 */ - int (*tcl_ConvertElement) (const char *src, char *dst, char flags); /* 84 */ - int (*tcl_ConvertCountedElement) (const char *src, int length, char *dst, char flags); /* 85 */ + int (*tcl_ConvertElement) (const char *src, char *dst, int flags); /* 84 */ + int (*tcl_ConvertCountedElement) (const char *src, int length, char *dst, int flags); /* 85 */ int (*tcl_CreateAlias) (Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, const char *targetCmd, int argc, const char *const *argv); /* 86 */ int (*tcl_CreateAliasObj) (Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, const char *targetCmd, int objc, Tcl_Obj *const objv[]); /* 87 */ Tcl_Channel (*tcl_CreateChannel) (const Tcl_ChannelType *typePtr, const char *chanName, ClientData instanceData, int mask); /* 88 */ @@ -2019,8 +2019,8 @@ typedef struct TclStubs { void (*tcl_RegExpRange) (Tcl_RegExp regexp, int index, const char **startPtr, const char **endPtr); /* 215 */ void (*tcl_Release) (ClientData clientData); /* 216 */ void (*tcl_ResetResult) (Tcl_Interp *interp); /* 217 */ - int (*tcl_ScanElement) (const char *src, char *flagPtr); /* 218 */ - int (*tcl_ScanCountedElement) (const char *src, int length, char *flagPtr); /* 219 */ + int (*tcl_ScanElement) (const char *src, int *flagPtr); /* 218 */ + int (*tcl_ScanCountedElement) (const char *src, int length, int *flagPtr); /* 219 */ void (*reserved220)(void); int (*tcl_ServiceAll) (void); /* 221 */ int (*tcl_ServiceEvent) (int flags); /* 222 */ diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 25124a1..2bc5f81 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -487,7 +487,7 @@ static void UpdateStringOfDict( Tcl_Obj *dictPtr) { -#define LOCAL_SIZE 20 +#define LOCAL_SIZE 64 char localFlags[LOCAL_SIZE], *flagPtr = NULL; Dict *dict = dictPtr->internalRep.otherValuePtr; ChainEntry *cPtr; @@ -495,7 +495,6 @@ UpdateStringOfDict( int i, length, bytesNeeded = 0; const char *elem; char *dst; - const int maxFlags = UINT_MAX / sizeof(int); /* * This field is the most useful one in the whole hash structure, and it @@ -517,10 +516,8 @@ UpdateStringOfDict( if (numElems <= LOCAL_SIZE) { flagPtr = localFlags; - } else if (numElems > maxFlags) { - Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); } else { - flagPtr = ckalloc(numElems * sizeof(char)); + flagPtr = ckalloc(numElems); } for (i=0,cPtr=dict->entryChainHead; inextPtr) { /* diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 63db812..6cbb10f 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -1923,7 +1923,7 @@ static void UpdateStringOfList( Tcl_Obj *listPtr) /* List object with string rep to update. */ { -# define LOCAL_SIZE 20 +# define LOCAL_SIZE 64 char localFlags[LOCAL_SIZE], *flagPtr = NULL; List *listRepPtr = ListRepPtr(listPtr); int numElems = listRepPtr->elemCount; @@ -1961,7 +1961,7 @@ UpdateStringOfList( * We know numElems <= LIST_MAX, so this is safe. */ - flagPtr = ckalloc(numElems * sizeof(char)); + flagPtr = ckalloc(numElems); } elemPtrs = &listRepPtr->elements; for (i = 0; i < numElems; i++) { diff --git a/generic/tclUtil.c b/generic/tclUtil.c index c8cb75c..c6dd464 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -872,7 +872,7 @@ Tcl_SplitList( int Tcl_ScanElement( const char *src, /* String to convert to list element. */ - char *flagPtr) /* Where to store information to guide + int *flagPtr) /* Where to store information to guide * Tcl_ConvertCountedElement. */ { return Tcl_ScanCountedElement(src, -1, flagPtr); @@ -905,7 +905,7 @@ int Tcl_ScanCountedElement( const char *src, /* String to convert to Tcl list element. */ int length, /* Number of bytes in src, or -1. */ - char *flagPtr) /* Where to store information to guide + int *flagPtr) /* Where to store information to guide * Tcl_ConvertElement. */ { char flags = CONVERT_ANY; @@ -1236,7 +1236,7 @@ int Tcl_ConvertElement( const char *src, /* Source information for list element. */ char *dst, /* Place to put list-ified element. */ - char flags) /* Flags produced by Tcl_ScanElement. */ + int flags) /* Flags produced by Tcl_ScanElement. */ { return Tcl_ConvertCountedElement(src, -1, dst, flags); } @@ -1267,7 +1267,7 @@ Tcl_ConvertCountedElement( register const char *src, /* Source information for list element. */ int length, /* Number of bytes in src, or -1. */ char *dst, /* Place to put list-ified element. */ - char flags) /* Flags produced by Tcl_ScanElement. */ + int flags) /* Flags produced by Tcl_ScanElement. */ { int numBytes = TclConvertElement(src, length, dst, flags); dst[numBytes] = '\0'; @@ -1481,11 +1481,10 @@ Tcl_Merge( int argc, /* How many strings to merge. */ const char *const *argv) /* Array of string values. */ { -#define LOCAL_SIZE 20 +#define LOCAL_SIZE 64 char localFlags[LOCAL_SIZE]; int i, bytesNeeded = 0; char *result, *dst, *flagPtr = NULL; - const int maxFlags = UINT_MAX / sizeof(int); /* * Handle empty list case first, so logic of the general case can be @@ -1504,33 +1503,16 @@ Tcl_Merge( if (argc <= LOCAL_SIZE) { flagPtr = localFlags; - } else if (argc > maxFlags) { - /* - * We cannot allocate a large enough flag array to format this list in - * one pass. We could imagine converting this routine to a multi-pass - * implementation, but for sizeof(int) == 4, the limit is a max of - * 2^30 list elements and since each element is at least one byte - * formatted, and requires one byte space between it and the next one, - * that a minimum space requirement of 2^31 bytes, which is already - * INT_MAX. If we tried to format a list of > maxFlags elements, we're - * just going to overflow the size limits on the formatted string - * anyway, so just issue that same panic early. - */ - - Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); } else { - flagPtr = ckalloc(argc * sizeof(char)); + flagPtr = ckalloc(argc); } for (i = 0; i < argc; i++) { flagPtr[i] = ( i ? TCL_DONT_QUOTE_HASH : 0 ); bytesNeeded += TclScanElement(argv[i], -1, &flagPtr[i]); - if (bytesNeeded < 0) { + if ((bytesNeeded < 0) || (bytesNeeded > INT_MAX - argc + 1)) { Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); } } - if (bytesNeeded > INT_MAX - argc + 1) { - Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); - } bytesNeeded += argc; /* -- cgit v0.12