summaryrefslogtreecommitdiffstats
path: root/generic/tclBinary.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclBinary.c')
-rw-r--r--generic/tclBinary.c658
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;