diff options
Diffstat (limited to 'generic/tclBinary.c')
-rw-r--r-- | generic/tclBinary.c | 658 |
1 files changed, 281 insertions, 377 deletions
diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 5ac08e9..c93494e 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -2,7 +2,7 @@ * tclBinary.c -- * * This file contains the implementation of the "binary" Tcl built-in - * command and the Tcl value internal representation for binary data. + * command and the Tcl binary data object. * * Copyright © 1997 Sun Microsystems, Inc. * Copyright © 1998-1999 Scriptics Corporation. @@ -22,8 +22,8 @@ * special conditions in the parsing of a format specifier. */ -#define BINARY_ALL -1 /* Use all elements in the argument. */ -#define BINARY_NOCOUNT -2 /* No count was specified in format. */ +#define BINARY_ALL ((size_t)-1) /* Use all elements in the argument. */ +#define BINARY_NOCOUNT ((size_t)-2) /* No count was specified in format. */ /* * The following flags may be ORed together and returned by GetFormatSpec @@ -55,25 +55,22 @@ * Prototypes for local procedures defined in this file: */ -static void DupByteArrayInternalRep(Tcl_Obj *srcPtr, - Tcl_Obj *copyPtr); static void DupProperByteArrayInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); static int FormatNumber(Tcl_Interp *interp, int type, Tcl_Obj *src, unsigned char **cursorPtr); -static void FreeByteArrayInternalRep(Tcl_Obj *objPtr); static void FreeProperByteArrayInternalRep(Tcl_Obj *objPtr); static int GetFormatSpec(const char **formatPtr, char *cmdPtr, - int *countPtr, int *flagsPtr); + size_t *countPtr, int *flagsPtr); static Tcl_Obj * ScanNumber(unsigned char *buffer, int type, int flags, Tcl_HashTable **numberCachePtr); -static int SetByteArrayFromAny(Tcl_Interp *interp, +static int SetByteArrayFromAny(Tcl_Interp *interp, size_t limit, Tcl_Obj *objPtr); static void UpdateStringOfByteArray(Tcl_Obj *listPtr); static void DeleteScanNumberCache(Tcl_HashTable *numberCachePtr); static int NeedReversing(int format); static void CopyNumber(const void *from, void *to, - unsigned int length, int type); + size_t length, int type); /* Binary ensemble commands */ static Tcl_ObjCmdProc BinaryFormatCmd; static Tcl_ObjCmdProc BinaryScanCmd; @@ -143,14 +140,11 @@ static const EnsembleImplMap decodeMap[] = { }; /* - * The following object types represent an array of bytes. The intent is to + * The following Tcl_ObjType represents an array of bytes. The intent is to * allow arbitrary binary data to pass through Tcl as a Tcl value without loss * or damage. Such values are useful for things like encoded strings or Tk * images to name just two. * - * It's strange to have two Tcl_ObjTypes in place for this task when one would - * do, so a bit of detail and history will aid understanding. - * * A bytearray is an ordered sequence of bytes. Each byte is an integer value * in the range [0-255]. To be a Tcl value type, we need a way to encode each * value in the value set as a Tcl string. A simple encoding is to @@ -158,50 +152,9 @@ static const EnsembleImplMap decodeMap[] = { * bytes is encoded into a Tcl string of N characters where the codepoint of * each character is the value of corresponding byte. This approach creates a * one-to-one map between all bytearray values and a subset of Tcl string - * values. - * - * When converting a Tcl string value to the bytearray internal rep, the - * question arises what to do with strings outside that subset? That is, - * those Tcl strings containing at least one codepoint greater than 255? The - * obviously correct answer is to raise an error! That string value does not - * represent any valid bytearray value. - * - * Unfortunately this was not the path taken by the authors of the original - * tclByteArrayType. They chose to accept all Tcl string values as acceptable - * string encodings of the bytearray values that result from masking away the - * high bits of any codepoint value at all. This meant that every bytearray - * value had multiple accepted string representations. - * - * The implications of this choice are truly ugly, and motivated the proposal - * of TIP 568 to migrate away from it and to the more sensible design where - * each bytearray value has only one string representation. Full details are - * recorded in that TIP for those who seek them. - * - * The Tcl_ObjType "properByteArrayType" is (nearly) a correct implementation - * of bytearrays. Any Tcl value with the type properByteArrayType can have - * its bytearray value fetched and used with confidence that acting on that - * value is equivalent to acting on the true Tcl string value. This still - * implies a side testing burden -- past mistakes will not let us avoid that - * immediately, but it is at least a conventional test of type, and can be - * implemented entirely by examining the objPtr fields, with no need to query - * the internalrep, as a canonical flag would require. This benefit is made - * available to extensions through the public routine Tcl_GetBytesFromObj(), - * first available in Tcl 8.7. - * - * The public routines Tcl_GetByteArrayFromObj() and Tcl_SetByteArrayLength() - * must continue to follow their documented behavior through the 8.* series of - * releases. To support that legacy operation, we need a mechanism to retain - * compatibility with the deployed callers of the broken interface. That's - * what the retained "tclByteArrayType" provides. In those unusual - * circumstances where we convert an invalid bytearray value to a bytearray - * type, it is to this legacy type. Essentially any time this legacy type - * shows up, it's a signal of a bug being ignored. - * - * In Tcl 9, the incompatibility in the behavior of these public routines - * has been approved, and the legacy internal rep is no longer retained. - * The internal changes seen below are the limit of what can be done - * in a Tcl 8.* release. They provide a great expansion of the histories - * over which bytearray values can be useful. + * values. Tcl string values outside that subset do no represent any valid + * bytearray value. Attempts to treat those values as bytearrays will lead + * to errors. See TIP 568 for how this differs from Tcl 8. */ static const Tcl_ObjType properByteArrayType = { @@ -212,14 +165,6 @@ static const Tcl_ObjType properByteArrayType = { NULL }; -const Tcl_ObjType tclByteArrayType = { - "bytearray", - FreeByteArrayInternalRep, - DupByteArrayInternalRep, - NULL, - SetByteArrayFromAny -}; - /* * The following structure is the internal rep for a ByteArray object. Keeps * track of how much memory has been used and how much has been allocated for @@ -227,17 +172,13 @@ const Tcl_ObjType tclByteArrayType = { * fewer mallocs. */ -typedef struct ByteArray { - unsigned int bad; /* Index of first character that is a nonbyte. - * If all characters are bytes, bad = used. */ - unsigned int used; /* The number of bytes used in the byte - * array. Must be <= allocated. The bytes - * used to store the value are indexed from - * 0 to used-1. */ - unsigned int allocated; /* The number of bytes of space allocated. */ - unsigned char bytes[TCLFLEXARRAY]; - /* The array of bytes. The actual size of this - * field is stored in the 'allocated' field +typedef struct { + size_t used; /* The number of bytes used in the byte + * array. */ + size_t allocated; /* The amount of space actually allocated + * minus 1 byte. */ + unsigned char bytes[TCLFLEXARRAY]; /* The array of bytes. The actual size of this + * field depends on the 'allocated' field * above. */ } ByteArray; @@ -245,8 +186,8 @@ typedef struct ByteArray { (offsetof(ByteArray, bytes) + (len)) #define GET_BYTEARRAY(irPtr) ((ByteArray *) (irPtr)->twoPtrValue.ptr1) #define SET_BYTEARRAY(irPtr, baPtr) \ - (irPtr)->twoPtrValue.ptr1 = (void *) (baPtr) - + (irPtr)->twoPtrValue.ptr1 = (baPtr) + int TclIsPureByteArray( Tcl_Obj * objPtr) @@ -263,7 +204,7 @@ TclIsPureByteArray( * from the given array of bytes. * * Results: - * The newly created object is returned. This object has no initial + * The newly create object is returned. This object will have no initial * string representation. The returned object has a ref count of 0. * * Side effects: @@ -278,8 +219,7 @@ Tcl_Obj * Tcl_NewByteArrayObj( const unsigned char *bytes, /* The array of bytes used to initialize the * new object. */ - int numBytes) /* Number of bytes in the array, - * must be >= 0. */ + size_t numBytes) /* Number of bytes in the array */ { #ifdef TCL_MEM_DEBUG return Tcl_DbNewByteArrayObj(bytes, numBytes, "unknown", 0); @@ -322,8 +262,7 @@ Tcl_Obj * Tcl_DbNewByteArrayObj( const unsigned char *bytes, /* The array of bytes used to initialize the * new object. */ - int numBytes, /* Number of bytes in the array, - * must be >= 0. */ + size_t numBytes, /* Number of bytes in the array */ const char *file, /* The name of the source file calling this * procedure; used for debugging. */ int line) /* Line number in the source file; used for @@ -340,8 +279,7 @@ Tcl_Obj * Tcl_DbNewByteArrayObj( const unsigned char *bytes, /* The array of bytes used to initialize the * new object. */ - int numBytes, /* Number of bytes in the array, - * must be >= 0. */ + size_t numBytes, /* Number of bytes in the array */ TCL_UNUSED(const char *) /*file*/, TCL_UNUSED(int) /*line*/) { @@ -372,8 +310,7 @@ Tcl_SetByteArrayObj( Tcl_Obj *objPtr, /* Object to initialize as a ByteArray. */ const unsigned char *bytes, /* The array of bytes to use as the new value. * May be NULL even if numBytes > 0. */ - int numBytes) /* Number of bytes in the array, - * must be >= 0. */ + size_t numBytes) /* Number of bytes in the array */ { ByteArray *byteArrayPtr; Tcl_ObjInternalRep ir; @@ -383,9 +320,7 @@ Tcl_SetByteArrayObj( } TclInvalidateStringRep(objPtr); - assert(numBytes >= 0); - byteArrayPtr = (ByteArray *)ckalloc(BYTEARRAY_SIZE(numBytes)); - byteArrayPtr->bad = numBytes; + byteArrayPtr = (ByteArray *)Tcl_Alloc(BYTEARRAY_SIZE(numBytes)); byteArrayPtr->used = numBytes; byteArrayPtr->allocated = numBytes; @@ -400,11 +335,11 @@ Tcl_SetByteArrayObj( /* *---------------------------------------------------------------------- * - * Tcl_GetBytesFromObj/TclGetBytesFromObj -- + * TclGetBytesFromObj -- * * Attempt to extract the value from objPtr in the representation * of a byte sequence. On success return the extracted byte sequence. - * On failure, return NULL and record error message and code in + * On failures, return NULL and record error message and code in * interp (if not NULL). * * Results: @@ -414,36 +349,23 @@ Tcl_SetByteArrayObj( *---------------------------------------------------------------------- */ +#undef Tcl_GetBytesFromObj unsigned char * -TclGetBytesFromObj( +Tcl_GetBytesFromObj( Tcl_Interp *interp, /* For error reporting */ Tcl_Obj *objPtr, /* Value to extract from */ - int *numBytesPtr) /* If non-NULL, write the number of bytes + size_t *numBytesPtr) /* If non-NULL, write the number of bytes * in the array here */ { ByteArray *baPtr; - const Tcl_ObjInternalRep *irPtr = TclFetchInternalRep(objPtr, &properByteArrayType); + const Tcl_ObjInternalRep *irPtr + = TclFetchInternalRep(objPtr, &properByteArrayType); if (irPtr == NULL) { - SetByteArrayFromAny(NULL, objPtr); - irPtr = TclFetchInternalRep(objPtr, &properByteArrayType); - if (irPtr == NULL) { - if (interp) { - const char *nonbyte; - int ucs4; - - irPtr = TclFetchInternalRep(objPtr, &tclByteArrayType); - baPtr = GET_BYTEARRAY(irPtr); - nonbyte = Tcl_UtfAtIndex(Tcl_GetString(objPtr), baPtr->bad); - TclUtfToUCS4(nonbyte, &ucs4); - - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "expected byte sequence but character %d " - "was '%1s' (U+%06X)", baPtr->bad, nonbyte, ucs4)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "BYTES", NULL); - } + if (TCL_ERROR == SetByteArrayFromAny(interp, TCL_INDEX_NONE, objPtr)) { return NULL; } + irPtr = TclFetchInternalRep(objPtr, &properByteArrayType); } baPtr = GET_BYTEARRAY(irPtr); @@ -452,50 +374,39 @@ TclGetBytesFromObj( } return baPtr->bytes; } -#undef Tcl_GetBytesFromObj + unsigned char * -Tcl_GetBytesFromObj( +TclGetBytesFromObj( Tcl_Interp *interp, /* For error reporting */ Tcl_Obj *objPtr, /* Value to extract from */ - size_t *numBytesPtr) /* If non-NULL, write the number of bytes + int *numBytesPtr) /* If non-NULL, write the number of bytes * in the array here */ { - ByteArray *baPtr; - const Tcl_ObjInternalRep *irPtr = TclFetchInternalRep(objPtr, &properByteArrayType); - - if (irPtr == NULL) { - SetByteArrayFromAny(NULL, objPtr); - irPtr = TclFetchInternalRep(objPtr, &properByteArrayType); - if (irPtr == NULL) { - if (interp) { - const char *nonbyte; - int ucs4; + size_t numBytes = 0; + unsigned char *bytes = Tcl_GetBytesFromObj(interp, objPtr, &numBytes); - irPtr = TclFetchInternalRep(objPtr, &tclByteArrayType); - baPtr = GET_BYTEARRAY(irPtr); - nonbyte = Tcl_UtfAtIndex(Tcl_GetString(objPtr), baPtr->bad); - TclUtfToUCS4(nonbyte, &ucs4); + if (bytes && numBytesPtr) { + if (numBytes > INT_MAX) { + /* Caller asked for numBytes to be written to an int, but the + * value is outside the int range. */ - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "expected byte sequence but character %d " - "was '%1s' (U+%06X)", baPtr->bad, nonbyte, ucs4)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "BYTES", NULL); + if (interp) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "byte sequence length exceeds INT_MAX", -1)); + Tcl_SetErrorCode(interp, "TCL", "API", "OUTDATED", NULL); } return NULL; + } else { + *numBytesPtr = (int) numBytes; } } - baPtr = GET_BYTEARRAY(irPtr); - - if (numBytesPtr != NULL) { - *numBytesPtr = baPtr->used; - } - return baPtr->bytes; + return bytes; } /* *---------------------------------------------------------------------- * - * Tcl_GetByteArrayFromObj/TclGetByteArrayFromObj -- + * Tcl_GetByteArrayFromObj -- * * Attempt to get the array of bytes from the Tcl object. If the object * is not already a ByteArray object, an attempt will be made to convert @@ -512,58 +423,21 @@ Tcl_GetBytesFromObj( #undef Tcl_GetByteArrayFromObj unsigned char * -Tcl_GetByteArrayFromObj( +TclGetByteArrayFromObj( Tcl_Obj *objPtr, /* The ByteArray object. */ int *numBytesPtr) /* If non-NULL, write the number of bytes * in the array here */ { - ByteArray *baPtr; - const Tcl_ObjInternalRep *irPtr; - unsigned char *result = TclGetBytesFromObj(NULL, objPtr, numBytesPtr); - - if (result) { - return result; - } - - irPtr = TclFetchInternalRep(objPtr, &tclByteArrayType); - assert(irPtr != NULL); - - baPtr = GET_BYTEARRAY(irPtr); - - if (numBytesPtr != NULL) { - *numBytesPtr = baPtr->used; - } - return (unsigned char *) baPtr->bytes; + return TclGetBytesFromObj(NULL, objPtr, numBytesPtr); } unsigned char * -TclGetByteArrayFromObj( +Tcl_GetByteArrayFromObj( Tcl_Obj *objPtr, /* The ByteArray object. */ size_t *numBytesPtr) /* If non-NULL, write the number of bytes * in the array here */ { - ByteArray *baPtr; - const Tcl_ObjInternalRep *irPtr; - unsigned char *result = Tcl_GetBytesFromObj(NULL, objPtr, numBytesPtr); - - if (result) { - return result; - } - - irPtr = TclFetchInternalRep(objPtr, &tclByteArrayType); - assert(irPtr != NULL); - - baPtr = GET_BYTEARRAY(irPtr); - - if (numBytesPtr != NULL) { -#if TCL_MAJOR_VERSION > 8 - *numBytesPtr = baPtr->used; -#else - /* TODO: What's going on here? Document or eliminate. */ - *numBytesPtr = ((size_t)(unsigned int)(baPtr->used + 1)) - 1; -#endif - } - return baPtr->bytes; + return Tcl_GetBytesFromObj(NULL, objPtr, numBytesPtr); } /* @@ -591,110 +465,156 @@ TclGetByteArrayFromObj( unsigned char * Tcl_SetByteArrayLength( Tcl_Obj *objPtr, /* The ByteArray object. */ - int numBytes) /* Number of bytes in resized array */ + size_t numBytes) /* Number of bytes in resized array */ { ByteArray *byteArrayPtr; - unsigned newLength; Tcl_ObjInternalRep *irPtr; - assert(numBytes >= 0); - newLength = (unsigned int)numBytes; - if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayLength"); } irPtr = TclFetchInternalRep(objPtr, &properByteArrayType); if (irPtr == NULL) { - irPtr = TclFetchInternalRep(objPtr, &tclByteArrayType); - if (irPtr == NULL) { - SetByteArrayFromAny(NULL, objPtr); - irPtr = TclFetchInternalRep(objPtr, &properByteArrayType); - if (irPtr == NULL) { - irPtr = TclFetchInternalRep(objPtr, &tclByteArrayType); - } + if (TCL_ERROR == SetByteArrayFromAny(NULL, numBytes, objPtr)) { + return NULL; } + irPtr = TclFetchInternalRep(objPtr, &properByteArrayType); } - /* Note that during truncation, the implementation does not free - * memory that is no longer needed. */ - byteArrayPtr = GET_BYTEARRAY(irPtr); - if (newLength > byteArrayPtr->allocated) { - byteArrayPtr = (ByteArray *)ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(newLength)); - byteArrayPtr->allocated = newLength; + if (numBytes > byteArrayPtr->allocated) { + byteArrayPtr = (ByteArray *)Tcl_Realloc(byteArrayPtr, + BYTEARRAY_SIZE(numBytes)); + byteArrayPtr->allocated = numBytes; SET_BYTEARRAY(irPtr, byteArrayPtr); } TclInvalidateStringRep(objPtr); - objPtr->typePtr = &properByteArrayType; - byteArrayPtr->bad = newLength; - byteArrayPtr->used = newLength; + byteArrayPtr->used = numBytes; return byteArrayPtr->bytes; } /* *---------------------------------------------------------------------- * + * MakeByteArray -- + * + * Generate a ByteArray internal rep from the string rep of objPtr. + * The generated byte sequence may have no more than limit bytes. The + * value of TCL_INDEX_NONE for limit indicates no limit imposed. If + * boolean argument demandProper is true, then no byte sequence should + * be output to the caller (write NULL instead). When no bytes sequence + * is output and interp is not NULL, leave an error message and error + * code in interp explaining why a proper byte sequence could not be + * made. + * + * Results: + * Returns a boolean indicating whether the bytes generated (up to + * limit bytes) are a proper representation of (a limited prefix of) + * the string. Writes a pointer to the generated ByteArray to + * *byteArrayPtrPtr. If not NULL it needs to be released with Tcl_Free(). + * + *---------------------------------------------------------------------- + */ + +static int +MakeByteArray( + Tcl_Interp *interp, + Tcl_Obj *objPtr, + size_t limit, + int demandProper, + ByteArray **byteArrayPtrPtr) +{ + size_t length; + const char *src = Tcl_GetStringFromObj(objPtr, &length); + size_t numBytes + = (limit != TCL_INDEX_NONE && limit < length) ? limit : length; + ByteArray *byteArrayPtr = (ByteArray *)Tcl_Alloc(BYTEARRAY_SIZE(numBytes)); + unsigned char *dst = byteArrayPtr->bytes; + unsigned char *dstEnd = dst + numBytes; + const char *srcEnd = src + length; + int proper = 1; + + for (; src < srcEnd && dst < dstEnd; ) { + int ch; + int count = TclUtfToUCS4(src, &ch); + + if (ch > 255) { + proper = 0; + if (demandProper) { + if (interp) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "expected byte sequence but character %" + TCL_Z_MODIFIER "u was '%1s' (U+%06X)", + dst - byteArrayPtr->bytes, src, ch)); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "BYTES", NULL); + } + Tcl_Free(byteArrayPtr); + *byteArrayPtrPtr = NULL; + return proper; + } + } + src += count; + *dst++ = UCHAR(ch); + } + byteArrayPtr->used = dst - byteArrayPtr->bytes; + byteArrayPtr->allocated = numBytes; + + *byteArrayPtrPtr = byteArrayPtr; + return proper; +} + +Tcl_Obj * +TclNarrowToBytes( + Tcl_Obj *objPtr) +{ + if (NULL == TclFetchInternalRep(objPtr, &properByteArrayType)) { + Tcl_ObjInternalRep ir; + ByteArray *byteArrayPtr; + + if (0 == MakeByteArray(NULL, objPtr, TCL_INDEX_NONE, 0, &byteArrayPtr)) { + TclNewObj(objPtr); + TclInvalidateStringRep(objPtr); + } + SET_BYTEARRAY(&ir, byteArrayPtr); + Tcl_StoreInternalRep(objPtr, &properByteArrayType, &ir); + } + Tcl_IncrRefCount(objPtr); + return objPtr; +} + + +/* + *---------------------------------------------------------------------- + * * SetByteArrayFromAny -- * * Generate the ByteArray internal rep from the string rep. * * Results: - * The return value is always TCL_OK. + * Tcl return code indicating OK or ERROR. * * Side effects: - * A ByteArray object is stored as the internal rep of objPtr. + * A ByteArray struct may be stored as the internal rep of objPtr. * *---------------------------------------------------------------------- */ static int SetByteArrayFromAny( - TCL_UNUSED(Tcl_Interp *), + Tcl_Interp *interp, /* For error reporting. */ + size_t limit, /* Create no more than this many bytes */ Tcl_Obj *objPtr) /* The object to convert to type ByteArray. */ { - size_t length, bad; - const char *src, *srcEnd; - unsigned char *dst; - Tcl_UniChar ch = 0; ByteArray *byteArrayPtr; Tcl_ObjInternalRep ir; - if (TclHasInternalRep(objPtr, &properByteArrayType)) { - return TCL_OK; - } - if (TclHasInternalRep(objPtr, &tclByteArrayType)) { - return TCL_OK; - } - - src = TclGetString(objPtr); - length = bad = objPtr->length; - srcEnd = src + length; - - /* Note the allocation is over-sized, possibly by a factor of four, - * or even a factor of two with a proper byte array value. */ - - byteArrayPtr = (ByteArray *)ckalloc(BYTEARRAY_SIZE(length)); - for (dst = byteArrayPtr->bytes; src < srcEnd; ) { - src += TclUtfToUniChar(src, &ch); - if ((bad == length) && (ch > 255)) { - bad = dst - byteArrayPtr->bytes; - } - *dst++ = UCHAR(ch); + if (0 == MakeByteArray(interp, objPtr, limit, 1, &byteArrayPtr)) { + return TCL_ERROR; } SET_BYTEARRAY(&ir, byteArrayPtr); - byteArrayPtr->allocated = length; - byteArrayPtr->used = dst - byteArrayPtr->bytes; - - if (bad == length) { - byteArrayPtr->bad = byteArrayPtr->used; - Tcl_StoreInternalRep(objPtr, &properByteArrayType, &ir); - } else { - byteArrayPtr->bad = bad; - Tcl_StoreInternalRep(objPtr, &tclByteArrayType, &ir); - } - + Tcl_StoreInternalRep(objPtr, &properByteArrayType, &ir); return TCL_OK; } @@ -716,17 +636,10 @@ SetByteArrayFromAny( */ static void -FreeByteArrayInternalRep( - Tcl_Obj *objPtr) /* Object with internal rep to free. */ -{ - ckfree(GET_BYTEARRAY(TclFetchInternalRep(objPtr, &tclByteArrayType))); -} - -static void FreeProperByteArrayInternalRep( Tcl_Obj *objPtr) /* Object with internal rep to free. */ { - ckfree(GET_BYTEARRAY(TclFetchInternalRep(objPtr, &properByteArrayType))); + Tcl_Free(GET_BYTEARRAY(TclFetchInternalRep(objPtr, &properByteArrayType))); } /* @@ -747,41 +660,18 @@ FreeProperByteArrayInternalRep( */ static void -DupByteArrayInternalRep( - Tcl_Obj *srcPtr, /* Object with internal rep to copy. */ - Tcl_Obj *copyPtr) /* Object with internal rep to set. */ -{ - unsigned int length; - ByteArray *srcArrayPtr, *copyArrayPtr; - Tcl_ObjInternalRep ir; - - srcArrayPtr = GET_BYTEARRAY(TclFetchInternalRep(srcPtr, &tclByteArrayType)); - length = srcArrayPtr->used; - - copyArrayPtr = (ByteArray *)ckalloc(BYTEARRAY_SIZE(length)); - copyArrayPtr->bad = srcArrayPtr->bad; - copyArrayPtr->used = length; - copyArrayPtr->allocated = length; - memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, length); - - SET_BYTEARRAY(&ir, copyArrayPtr); - Tcl_StoreInternalRep(copyPtr, &tclByteArrayType, &ir); -} - -static void DupProperByteArrayInternalRep( Tcl_Obj *srcPtr, /* Object with internal rep to copy. */ Tcl_Obj *copyPtr) /* Object with internal rep to set. */ { - unsigned int length; + size_t length; ByteArray *srcArrayPtr, *copyArrayPtr; Tcl_ObjInternalRep ir; srcArrayPtr = GET_BYTEARRAY(TclFetchInternalRep(srcPtr, &properByteArrayType)); length = srcArrayPtr->used; - copyArrayPtr = (ByteArray *)ckalloc(BYTEARRAY_SIZE(length)); - copyArrayPtr->bad = length; + copyArrayPtr = (ByteArray *)Tcl_Alloc(BYTEARRAY_SIZE(length)); copyArrayPtr->used = length; copyArrayPtr->allocated = length; memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, length); @@ -815,21 +705,18 @@ UpdateStringOfByteArray( const Tcl_ObjInternalRep *irPtr = TclFetchInternalRep(objPtr, &properByteArrayType); ByteArray *byteArrayPtr = GET_BYTEARRAY(irPtr); unsigned char *src = byteArrayPtr->bytes; - unsigned int i, length = byteArrayPtr->used; - unsigned int size = length; + size_t i, length = byteArrayPtr->used; + size_t size = length; /* * How much space will string rep need? */ - for (i = 0; i < length && size <= INT_MAX; i++) { + for (i = 0; i < length; i++) { if ((src[i] == 0) || (src[i] > 127)) { size++; } } - if (size > INT_MAX) { - Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); - } if (size == length) { char *dst = Tcl_InitStringRep(objPtr, (char *)src, size); @@ -868,16 +755,16 @@ void TclAppendBytesToByteArray( Tcl_Obj *objPtr, const unsigned char *bytes, - int len) + size_t len) { ByteArray *byteArrayPtr; - unsigned int length, needed; + size_t needed; Tcl_ObjInternalRep *irPtr; if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray"); } - if (len < 0) { + if (len == TCL_INDEX_NONE) { Tcl_Panic("%s must be called with definite number of bytes to append", "TclAppendBytesToByteArray"); } @@ -889,33 +776,32 @@ TclAppendBytesToByteArray( return; } - length = (unsigned int) len; - irPtr = TclFetchInternalRep(objPtr, &properByteArrayType); if (irPtr == NULL) { - irPtr = TclFetchInternalRep(objPtr, &tclByteArrayType); - if (irPtr == NULL) { - SetByteArrayFromAny(NULL, objPtr); - irPtr = TclFetchInternalRep(objPtr, &properByteArrayType); - if (irPtr == NULL) { - irPtr = TclFetchInternalRep(objPtr, &tclByteArrayType); - } + if (TCL_ERROR == SetByteArrayFromAny(NULL, TCL_INDEX_NONE, objPtr)) { + Tcl_Panic("attempt to append bytes to non-bytearray"); } + irPtr = TclFetchInternalRep(objPtr, &properByteArrayType); } byteArrayPtr = GET_BYTEARRAY(irPtr); - if (length > INT_MAX - byteArrayPtr->used) { - Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); + /* Size limit check now commented out. Used to protect calls to + * Tcl_*Alloc*() limited by unsigned int arguments. + * + if (len > UINT_MAX - byteArrayPtr->used) { + Tcl_Panic("max size for a Tcl value (%u bytes) exceeded", UINT_MAX); } + * + */ - needed = byteArrayPtr->used + length; + needed = byteArrayPtr->used + len; /* * If we need to, resize the allocated space in the byte array. */ if (needed > byteArrayPtr->allocated) { ByteArray *ptr = NULL; - unsigned int attempt; + size_t attempt; if (needed <= INT_MAX/2) { /* @@ -923,19 +809,15 @@ TclAppendBytesToByteArray( */ attempt = 2 * needed; - ptr = (ByteArray *)attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); + ptr = (ByteArray *)Tcl_AttemptRealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); } if (ptr == NULL) { /* * Try to allocate double the increment that is needed (plus). */ - unsigned int limit = INT_MAX - needed; - unsigned int extra = length + TCL_MIN_GROWTH; - int growth = (int) ((extra > limit) ? limit : extra); - - attempt = needed + growth; - ptr = (ByteArray *)attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); + attempt = needed + len + TCL_MIN_GROWTH; + ptr = (ByteArray *)Tcl_AttemptRealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); } if (ptr == NULL) { /* @@ -943,7 +825,7 @@ TclAppendBytesToByteArray( */ attempt = needed; - ptr = (ByteArray *)ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); + ptr = (ByteArray *)Tcl_Realloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); } byteArrayPtr = ptr; byteArrayPtr->allocated = attempt; @@ -951,11 +833,10 @@ TclAppendBytesToByteArray( } if (bytes) { - memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, length); + memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, len); } - byteArrayPtr->used += length; + byteArrayPtr->used += len; TclInvalidateStringRep(objPtr); - objPtr->typePtr = &properByteArrayType; } /* @@ -1005,7 +886,7 @@ TclInitBinaryCmd( static int BinaryFormatCmd( - TCL_UNUSED(ClientData), + TCL_UNUSED(void *), Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ @@ -1014,7 +895,7 @@ BinaryFormatCmd( int value = 0; /* Current integer value to be packed. * Initialized to avoid compiler warning. */ char cmd; /* Current format character. */ - int count; /* Count associated with current format + size_t count; /* Count associated with current format * character. */ int flags; /* Format field flags */ const char *format; /* Pointer to current position in format @@ -1026,7 +907,8 @@ BinaryFormatCmd( * cursor has visited.*/ const char *errorString; const char *errorValue, *str; - int offset, size, length; + int offset, size; + size_t length; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "formatString ?arg ...?"); @@ -1065,7 +947,9 @@ BinaryFormatCmd( goto badIndex; } if (count == BINARY_ALL) { - Tcl_GetByteArrayFromObj(objv[arg], &count); + Tcl_Obj *copy = TclNarrowToBytes(objv[arg]); + (void)Tcl_GetByteArrayFromObj(copy, &count); + Tcl_DecrRefCount(copy); } else if (count == BINARY_NOCOUNT) { count = 1; } @@ -1137,7 +1021,7 @@ BinaryFormatCmd( if (count == BINARY_ALL) { count = listc; - } else if (count > listc) { + } else if (count > (size_t)listc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "number of elements in list does not match count", -1)); @@ -1161,16 +1045,16 @@ BinaryFormatCmd( if (count == BINARY_NOCOUNT) { count = 1; } - if ((count > offset) || (count == BINARY_ALL)) { + if ((count > (size_t)offset) || (count == BINARY_ALL)) { count = offset; } - if (offset > length) { + if (offset > (int)length) { length = offset; } offset -= count; break; case '@': - if (offset > length) { + if (offset > (int)length) { length = offset; } if (count == BINARY_ALL) { @@ -1186,7 +1070,7 @@ BinaryFormatCmd( goto badField; } } - if (offset > length) { + if (offset > (int)length) { length = offset; } if (length == 0) { @@ -1228,8 +1112,9 @@ BinaryFormatCmd( case 'A': { char pad = (char) (cmd == 'a' ? '\0' : ' '); unsigned char *bytes; + Tcl_Obj *copy = TclNarrowToBytes(objv[arg++]); - bytes = Tcl_GetByteArrayFromObj(objv[arg++], &length); + bytes = Tcl_GetByteArrayFromObj(copy, &length); if (count == BINARY_ALL) { count = length; @@ -1243,13 +1128,14 @@ BinaryFormatCmd( memset(cursor + length, pad, count - length); } cursor += count; + Tcl_DecrRefCount(copy); break; } case 'b': case 'B': { unsigned char *last; - str = TclGetStringFromObj(objv[arg], &length); + str = Tcl_GetStringFromObj(objv[arg], &length); arg++; if (count == BINARY_ALL) { count = length; @@ -1263,7 +1149,7 @@ BinaryFormatCmd( value = 0; errorString = "binary"; if (cmd == 'B') { - for (offset = 0; offset < count; offset++) { + for (offset = 0; (size_t)offset < count; offset++) { value <<= 1; if (str[offset] == '1') { value |= 1; @@ -1278,7 +1164,7 @@ BinaryFormatCmd( } } } else { - for (offset = 0; offset < count; offset++) { + for (offset = 0; (size_t)offset < count; offset++) { value >>= 1; if (str[offset] == '1') { value |= 128; @@ -1311,7 +1197,7 @@ BinaryFormatCmd( unsigned char *last; int c; - str = TclGetStringFromObj(objv[arg], &length); + str = Tcl_GetStringFromObj(objv[arg], &length); arg++; if (count == BINARY_ALL) { count = length; @@ -1325,7 +1211,7 @@ BinaryFormatCmd( value = 0; errorString = "hexadecimal"; if (cmd == 'H') { - for (offset = 0; offset < count; offset++) { + for (offset = 0; (size_t)offset < count; offset++) { value <<= 4; if (!isxdigit(UCHAR(str[offset]))) { /* INTL: digit */ errorValue = str; @@ -1346,7 +1232,7 @@ BinaryFormatCmd( } } } else { - for (offset = 0; offset < count; offset++) { + for (offset = 0; (size_t)offset < count; offset++) { value >>= 4; if (!isxdigit(UCHAR(str[offset]))) { /* INTL: digit */ @@ -1417,7 +1303,7 @@ BinaryFormatCmd( } } arg++; - for (i = 0; i < count; i++) { + for (i = 0; (size_t)i < count; i++) { if (FormatNumber(interp, cmd, listv[i], &cursor) != TCL_OK) { Tcl_DecrRefCount(resultPtr); return TCL_ERROR; @@ -1439,7 +1325,7 @@ BinaryFormatCmd( if (count == BINARY_NOCOUNT) { count = 1; } - if ((count == BINARY_ALL) || (count > (cursor - buffer))) { + if ((count == BINARY_ALL) || (count > (size_t)(cursor - buffer))) { cursor = buffer; } else { cursor -= count; @@ -1510,7 +1396,7 @@ BinaryFormatCmd( static int BinaryScanCmd( - TCL_UNUSED(ClientData), + TCL_UNUSED(void *), Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ @@ -1519,7 +1405,7 @@ BinaryScanCmd( int value = 0; /* Current integer value to be packed. * Initialized to avoid compiler warning. */ char cmd; /* Current format character. */ - int count; /* Count associated with current format + size_t count; /* Count associated with current format * character. */ int flags; /* Format field flags */ const char *format; /* Pointer to current position in format @@ -1528,7 +1414,8 @@ BinaryScanCmd( unsigned char *buffer; /* Start of result buffer. */ const char *errorString; const char *str; - int offset, size, length, i; + int offset, size, i; + size_t length = 0; Tcl_Obj *valuePtr, *elementPtr; Tcl_HashTable numberCacheHash; @@ -1539,9 +1426,12 @@ BinaryScanCmd( "value formatString ?varName ...?"); return TCL_ERROR; } + buffer = Tcl_GetBytesFromObj(interp, objv[1], &length); + if (buffer == NULL) { + return TCL_ERROR; + } numberCachePtr = &numberCacheHash; Tcl_InitHashTable(numberCachePtr, TCL_ONE_WORD_KEYS); - buffer = Tcl_GetByteArrayFromObj(objv[1], &length); format = TclGetString(objv[2]); arg = 3; offset = 0; @@ -1567,7 +1457,7 @@ BinaryScanCmd( if (count == BINARY_NOCOUNT) { count = 1; } - if (count > (length - offset)) { + if (count > length - offset) { goto done; } } @@ -1634,7 +1524,7 @@ BinaryScanCmd( if (count == BINARY_NOCOUNT) { count = 1; } - if (count > (length - offset) * 8) { + if (count > (size_t)(length - offset) * 8) { goto done; } } @@ -1644,7 +1534,7 @@ BinaryScanCmd( dest = TclGetString(valuePtr); if (cmd == 'b') { - for (i = 0; i < count; i++) { + for (i = 0; (size_t)i < count; i++) { if (i % 8) { value >>= 1; } else { @@ -1653,7 +1543,7 @@ BinaryScanCmd( *dest++ = (char) ((value & 1) ? '1' : '0'); } } else { - for (i = 0; i < count; i++) { + for (i = 0; (size_t)i < count; i++) { if (i % 8) { value <<= 1; } else { @@ -1699,7 +1589,7 @@ BinaryScanCmd( dest = TclGetString(valuePtr); if (cmd == 'h') { - for (i = 0; i < count; i++) { + for (i = 0; (size_t)i < count; i++) { if (i % 2) { value >>= 4; } else { @@ -1708,7 +1598,7 @@ BinaryScanCmd( *dest++ = hexdigit[value & 0xF]; } } else { - for (i = 0; i < count; i++) { + for (i = 0; (size_t)i < count; i++) { if (i % 2) { value <<= 4; } else { @@ -1765,7 +1655,7 @@ BinaryScanCmd( goto badIndex; } if (count == BINARY_NOCOUNT) { - if ((length - offset) < size) { + if ((length - offset) < (size_t)size) { goto done; } valuePtr = ScanNumber(buffer+offset, cmd, flags, @@ -1780,7 +1670,7 @@ BinaryScanCmd( } TclNewObj(valuePtr); src = buffer + offset; - for (i = 0; i < count; i++) { + for (i = 0; (size_t)i < count; i++) { elementPtr = ScanNumber(src, cmd, flags, &numberCachePtr); src += size; Tcl_ListObjAppendElement(NULL, valuePtr, elementPtr); @@ -1801,7 +1691,7 @@ BinaryScanCmd( if (count == BINARY_NOCOUNT) { count = 1; } - if ((count == BINARY_ALL) || (count > (length - offset))) { + if ((count == BINARY_ALL) || (count > length - offset)) { offset = length; } else { offset += count; @@ -1811,7 +1701,7 @@ BinaryScanCmd( if (count == BINARY_NOCOUNT) { count = 1; } - if ((count == BINARY_ALL) || (count > offset)) { + if ((count == BINARY_ALL) || (count > (size_t)offset)) { offset = 0; } else { offset -= count; @@ -1895,7 +1785,7 @@ static int GetFormatSpec( const char **formatPtr, /* Pointer to format string. */ char *cmdPtr, /* Pointer to location of command char. */ - int *countPtr, /* Pointer to repeat count value. */ + size_t *countPtr, /* Pointer to repeat count value. */ int *flagsPtr) /* Pointer to field flags */ { /* @@ -2061,7 +1951,7 @@ static void CopyNumber( const void *from, /* source */ void *to, /* destination */ - unsigned length, /* Number of bytes to copy */ + size_t length, /* Number of bytes to copy */ int type) /* What type of thing are we copying? */ { switch (NeedReversing(type)) { @@ -2128,7 +2018,7 @@ CopyNumber( * * FormatNumber -- * - * This routine is called by BinaryFormatCmd to format a number into a + * This routine is called by Tcl_BinaryObjCmd to format a number into a * location pointed at by cursor. * * Results: @@ -2297,7 +2187,7 @@ FormatNumber( * * ScanNumber -- * - * This routine is called by BinaryScanCmd to scan a number out of a + * This routine is called by Tcl_BinaryObjCmd to scan a number out of a * buffer. * * Results: @@ -2587,7 +2477,7 @@ DeleteScanNumberCache( static int BinaryEncodeHex( - TCL_UNUSED(ClientData), + TCL_UNUSED(void *), Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) @@ -2595,15 +2485,19 @@ BinaryEncodeHex( Tcl_Obj *resultObj = NULL; unsigned char *data = NULL; unsigned char *cursor = NULL; - int offset = 0, count = 0; + size_t offset = 0, count = 0; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "data"); return TCL_ERROR; } + data = Tcl_GetBytesFromObj(interp, objv[1], &count); + if (data == NULL) { + return TCL_ERROR; + } + TclNewObj(resultObj); - data = Tcl_GetByteArrayFromObj(objv[1], &count); cursor = Tcl_SetByteArrayLength(resultObj, count * 2); for (offset = 0; offset < count; ++offset) { *cursor++ = HexDigits[(data[offset] >> 4) & 0x0F]; @@ -2631,7 +2525,7 @@ BinaryEncodeHex( static int BinaryDecodeHex( - TCL_UNUSED(ClientData), + TCL_UNUSED(void *), Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) @@ -2639,7 +2533,8 @@ BinaryDecodeHex( Tcl_Obj *resultObj = NULL; unsigned char *data, *datastart, *dataend; unsigned char *begin, *cursor, c; - int i, index, value, size, pure = 1, count = 0, cut = 0, strict = 0; + int i, index, value, pure = 1, strict = 0; + size_t size, cut = 0, count = 0; int ucs4; enum {OPT_STRICT }; static const char *const optStrings[] = { "-strict", NULL }; @@ -2661,10 +2556,10 @@ BinaryDecodeHex( } TclNewObj(resultObj); - data = TclGetBytesFromObj(NULL, objv[objc - 1], &count); + data = Tcl_GetBytesFromObj(NULL, objv[objc - 1], &count); if (data == NULL) { pure = 0; - data = (unsigned char *) TclGetStringFromObj(objv[objc - 1], &count); + data = (unsigned char *) Tcl_GetStringFromObj(objv[objc - 1], &count); } datastart = data; dataend = data + count; @@ -2718,8 +2613,8 @@ BinaryDecodeHex( } TclDecrRefCount(resultObj); Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "invalid hexadecimal digit \"%c\" (U+%06X) at position %d", - ucs4, ucs4, (int) (data - datastart - 1))); + "invalid hexadecimal digit \"%c\" (U+%06X) at position %" + TCL_Z_MODIFIER "u", ucs4, ucs4, data - datastart - 1)); Tcl_SetErrorCode(interp, "TCL", "BINARY", "DECODE", "INVALID", NULL); return TCL_ERROR; } @@ -2755,7 +2650,7 @@ BinaryDecodeHex( static int BinaryEncode64( - TCL_UNUSED(ClientData), + TCL_UNUSED(void *), Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) @@ -2764,8 +2659,9 @@ BinaryEncode64( unsigned char *data, *limit; int maxlen = 0; const char *wrapchar = "\n"; - int wrapcharlen = 1; - int offset, i, index, size, outindex = 0, count = 0, purewrap = 1; + size_t wrapcharlen = 1; + int i, index, size, outindex = 0, purewrap = 1; + size_t offset, count = 0; enum { OPT_MAXLEN, OPT_WRAPCHAR }; static const char *const optStrings[] = { "-maxlen", "-wrapchar", NULL }; @@ -2793,11 +2689,11 @@ BinaryEncode64( } break; case OPT_WRAPCHAR: - wrapchar = (const char *)TclGetBytesFromObj(NULL, + wrapchar = (const char *)Tcl_GetBytesFromObj(NULL, objv[i + 1], &wrapcharlen); if (wrapchar == NULL) { purewrap = 0; - wrapchar = TclGetStringFromObj(objv[i + 1], &wrapcharlen); + wrapchar = Tcl_GetStringFromObj(objv[i + 1], &wrapcharlen); } break; } @@ -2806,8 +2702,11 @@ BinaryEncode64( maxlen = 0; } + data = Tcl_GetBytesFromObj(interp, objv[objc - 1], &count); + if (data == NULL) { + return TCL_ERROR; + } TclNewObj(resultObj); - data = Tcl_GetByteArrayFromObj(objv[objc - 1], &count); if (count > 0) { unsigned char *cursor = NULL; @@ -2877,19 +2776,19 @@ BinaryEncode64( static int BinaryEncodeUu( - TCL_UNUSED(ClientData), + TCL_UNUSED(void *), Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Tcl_Obj *resultObj; unsigned char *data, *start, *cursor; - int offset, count, rawLength, i, j, bits, index; + int rawLength, i, bits, index; unsigned int n; int lineLength = 61; const unsigned char SingleNewline[] = { UCHAR('\n') }; const unsigned char *wrapchar = SingleNewline; - int wrapcharlen = sizeof(SingleNewline); + size_t j, offset, count = 0, wrapcharlen = sizeof(SingleNewline); enum { OPT_MAXLEN, OPT_WRAPCHAR }; static const char *const optStrings[] = { "-maxlen", "-wrapchar", NULL }; @@ -2919,11 +2818,11 @@ BinaryEncodeUu( lineLength = ((lineLength - 1) & -4) + 1; /* 5, 9, 13 ... */ break; case OPT_WRAPCHAR: - wrapchar = (const unsigned char *) TclGetStringFromObj( + wrapchar = (const unsigned char *) Tcl_GetStringFromObj( objv[i + 1], &wrapcharlen); { const unsigned char *p = wrapchar; - int numBytes = wrapcharlen; + size_t numBytes = wrapcharlen; while (numBytes) { switch (*p) { @@ -2959,9 +2858,12 @@ BinaryEncodeUu( * enough". */ - TclNewObj(resultObj); offset = 0; - data = Tcl_GetByteArrayFromObj(objv[objc - 1], &count); + data = Tcl_GetBytesFromObj(interp, objv[objc - 1], &count); + if (data == NULL) { + return TCL_ERROR; + } + TclNewObj(resultObj); rawLength = (lineLength - 1) * 3 / 4; start = cursor = Tcl_SetByteArrayLength(resultObj, (lineLength + wrapcharlen) * @@ -3026,7 +2928,7 @@ BinaryEncodeUu( static int BinaryDecodeUu( - TCL_UNUSED(ClientData), + TCL_UNUSED(void *), Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) @@ -3034,7 +2936,8 @@ BinaryDecodeUu( Tcl_Obj *resultObj = NULL; unsigned char *data, *datastart, *dataend; unsigned char *begin, *cursor; - int i, index, size, pure = 1, count = 0, strict = 0, lineLen; + int i, index, pure = 1, strict = 0, lineLen; + size_t size, count = 0; unsigned char c; int ucs4; enum { OPT_STRICT }; @@ -3057,10 +2960,10 @@ BinaryDecodeUu( } TclNewObj(resultObj); - data = TclGetBytesFromObj(NULL, objv[objc - 1], &count); + data = Tcl_GetBytesFromObj(NULL, objv[objc - 1], &count); if (data == NULL) { pure = 0; - data = (unsigned char *) TclGetStringFromObj(objv[objc - 1], &count); + data = (unsigned char *) Tcl_GetStringFromObj(objv[objc - 1], &count); } datastart = data; dataend = data + count; @@ -3174,8 +3077,8 @@ BinaryDecodeUu( TclUtfToUCS4((const char *)(data - 1), &ucs4); } Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "invalid uuencode character \"%c\" (U+%06X) at position %d", - ucs4, ucs4, (int) (data - datastart - 1))); + "invalid uuencode character \"%c\" (U+%06X) at position %" + TCL_Z_MODIFIER "u", ucs4, ucs4, data - datastart - 1)); Tcl_SetErrorCode(interp, "TCL", "BINARY", "DECODE", "INVALID", NULL); TclDecrRefCount(resultObj); return TCL_ERROR; @@ -3199,7 +3102,7 @@ BinaryDecodeUu( static int BinaryDecode64( - TCL_UNUSED(ClientData), + TCL_UNUSED(void *), Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) @@ -3209,7 +3112,8 @@ BinaryDecode64( unsigned char *begin = NULL; unsigned char *cursor = NULL; int pure = 1, strict = 0; - int i, index, size, cut = 0, count = 0; + int i, index, cut = 0; + size_t size, count = 0; int ucs4; enum { OPT_STRICT }; static const char *const optStrings[] = { "-strict", NULL }; @@ -3231,10 +3135,10 @@ BinaryDecode64( } TclNewObj(resultObj); - data = TclGetBytesFromObj(NULL, objv[objc - 1], &count); + data = Tcl_GetBytesFromObj(NULL, objv[objc - 1], &count); if (data == NULL) { pure = 0; - data = (unsigned char *) TclGetStringFromObj(objv[objc - 1], &count); + data = (unsigned char *) Tcl_GetStringFromObj(objv[objc - 1], &count); } datastart = data; dataend = data + count; @@ -3349,8 +3253,8 @@ BinaryDecode64( } Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "invalid base64 character \"%c\" (U+%06X) at position %d", - ucs4, ucs4, (int) (data - datastart - 1))); + "invalid base64 character \"%c\" (U+%06X) at position %" + TCL_Z_MODIFIER "u", ucs4, ucs4, data - datastart - 1)); Tcl_SetErrorCode(interp, "TCL", "BINARY", "DECODE", "INVALID", NULL); TclDecrRefCount(resultObj); return TCL_ERROR; |