From a32dffe303445fed997b22794752d372bd997399 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 28 Mar 2020 19:21:56 +0000 Subject: [8edfcedfa0] [binary encode base64] build a string instead of a bytearray whenever it might be required to get the right result. --- generic/tclBinary.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 93aeee3..e4d7365 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -2484,11 +2484,11 @@ BinaryEncode64( Tcl_Obj *const objv[]) { Tcl_Obj *resultObj; - unsigned char *data, *cursor, *limit; + unsigned char *data, *limit; int maxlen = 0; const char *wrapchar = "\n"; int wrapcharlen = 1; - int offset, i, index, size, outindex = 0, count = 0; + int offset, i, index, size, outindex = 0, count = 0, purewrap = 1; enum { OPT_MAXLEN, OPT_WRAPCHAR }; static const char *const optStrings[] = { "-maxlen", "-wrapchar", NULL }; @@ -2516,7 +2516,13 @@ BinaryEncode64( } break; case OPT_WRAPCHAR: - wrapchar = Tcl_GetStringFromObj(objv[i + 1], &wrapcharlen); + purewrap = TclIsPureByteArray(objv[i + 1]); + if (purewrap) { + wrapchar = (const char *) Tcl_GetByteArrayFromObj( + objv[i + 1], &wrapcharlen); + } else { + wrapchar = Tcl_GetStringFromObj(objv[i + 1], &wrapcharlen); + } break; } } @@ -2527,6 +2533,8 @@ BinaryEncode64( resultObj = Tcl_NewObj(); data = Tcl_GetByteArrayFromObj(objv[objc - 1], &count); if (count > 0) { + unsigned char *cursor = NULL; + size = (((count * 4) / 3) + 3) & ~3; /* ensure 4 byte chunks */ if (maxlen > 0 && size > maxlen) { int adjusted = size + (wrapcharlen * (size / maxlen)); @@ -2535,8 +2543,17 @@ BinaryEncode64( adjusted -= wrapcharlen; } size = adjusted; + + if (purewrap == 0) { + /* Wrapchar is (possibly) non-byte, so build result as + * general string, not bytearray */ + Tcl_SetObjLength(resultObj, size); + cursor = (unsigned char *) TclGetString(resultObj); + } + } + if (cursor == NULL) { + cursor = Tcl_SetByteArrayLength(resultObj, size); } - cursor = Tcl_SetByteArrayLength(resultObj, size); limit = cursor + size; for (offset = 0; offset < count; offset += 3) { unsigned char d[3] = {0, 0, 0}; -- cgit v0.12