From 0bcca87681ea390671d67a96f771697c9f5ff3be Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 18 Nov 2022 20:26:52 +0000 Subject: Backout [52a52a65f0], let's see if this fixes the Windows crash --- generic/tclLink.c | 19 +++++++++++++++++-- generic/tclObj.c | 34 ++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/generic/tclLink.c b/generic/tclLink.c index 397c9bc..1973067 100644 --- a/generic/tclLink.c +++ b/generic/tclLink.c @@ -537,10 +537,15 @@ GetUWide( } else if (type == TCL_NUMBER_BIG) { mp_int *numPtr = (mp_int *)clientData; Tcl_WideUInt value = 0; + union { + Tcl_WideUInt value; + unsigned char bytes[sizeof(Tcl_WideUInt)]; + } scratch; size_t numBytes; + unsigned char *bytes = scratch.bytes; - if (numPtr->sign || (MP_OKAY != mp_pack(&value, 1, - &numBytes, 0, sizeof(Tcl_WideUInt), 0, 0, numPtr))) { + if (numPtr->sign || (MP_OKAY != mp_to_ubin(numPtr, + bytes, sizeof(Tcl_WideUInt), &numBytes))) { /* * If the sign bit is set (a negative value) or if the value * can't possibly fit in the bits of an unsigned wide, there's @@ -548,6 +553,16 @@ GetUWide( */ return 1; } +#ifndef WORDS_BIGENDIAN + while (numBytes-- > 0) { + value = (value << CHAR_BIT) | *bytes++; + } +#else /* WORDS_BIGENDIAN */ + /* + * Big-endian can read the value directly. + */ + value = scratch.value; +#endif /* WORDS_BIGENDIAN */ *uwidePtr = value; return 0; } diff --git a/generic/tclObj.c b/generic/tclObj.c index bad3f85..ce8e610 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -3124,12 +3124,15 @@ Tcl_GetLongFromObj( { mp_int big; - unsigned long value = 0; + unsigned long scratch, value = 0; + unsigned char *bytes = (unsigned char *) &scratch; size_t numBytes; TclUnpackBignum(objPtr, big); - if (mp_pack(&value, 1, - &numBytes, 0, sizeof(Tcl_WideUInt), 0, 0, &big) == MP_OKAY) { + if (mp_to_ubin(&big, bytes, sizeof(long), &numBytes) == MP_OKAY) { + while (numBytes-- > 0) { + value = (value << CHAR_BIT) | *bytes++; + } if (big.sign) { if (value <= 1 + (unsigned long)LONG_MAX) { *longPtr = (long)(-value); @@ -3361,10 +3364,14 @@ Tcl_GetWideIntFromObj( mp_int big; Tcl_WideUInt value = 0; size_t numBytes; + Tcl_WideInt scratch; + unsigned char *bytes = (unsigned char *) &scratch; TclUnpackBignum(objPtr, big); - if (mp_pack(&value, 1, - &numBytes, 0, sizeof(Tcl_WideUInt), 0, 0, &big) == MP_OKAY) { + if (mp_to_ubin(&big, bytes, sizeof(Tcl_WideInt), &numBytes) == MP_OKAY) { + while (numBytes-- > 0) { + value = (value << CHAR_BIT) | *bytes++; + } if (big.sign) { if (value <= 1 + ~(Tcl_WideUInt)WIDE_MIN) { *wideIntPtr = (Tcl_WideInt)(-value); @@ -3437,18 +3444,21 @@ TclGetWideBitsFromObj( mp_int big; mp_err err; - Tcl_WideUInt value = 0; + Tcl_WideUInt value = 0, scratch; size_t numBytes; + unsigned char *bytes = (unsigned char *) &scratch; Tcl_GetBignumFromObj(NULL, objPtr, &big); err = mp_mod_2d(&big, (int) (CHAR_BIT * sizeof(Tcl_WideInt)), &big); if (err == MP_OKAY) { - err = mp_pack(&value, 1, - &numBytes, 0, sizeof(Tcl_WideUInt), 0, 0, &big); + err = mp_to_ubin(&big, bytes, sizeof(Tcl_WideInt), &numBytes); } if (err != MP_OKAY) { return TCL_ERROR; } + while (numBytes-- > 0) { + value = (value << CHAR_BIT) | *bytes++; + } *wideIntPtr = !big.sign ? (Tcl_WideInt)value : -(Tcl_WideInt)value; mp_clear(&big); return TCL_OK; @@ -3818,15 +3828,19 @@ Tcl_SetBignumObj( { Tcl_WideUInt value = 0; size_t numBytes; + Tcl_WideUInt scratch; + unsigned char *bytes = (unsigned char *) &scratch; mp_int *bignumValue = (mp_int *) big; if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_SetBignumObj"); } - if (mp_pack(&value, 1, - &numBytes, 0, sizeof(Tcl_WideUInt), 0, 0, bignumValue) != MP_OKAY) { + if (mp_to_ubin(bignumValue, bytes, sizeof(Tcl_WideUInt), &numBytes) != MP_OKAY) { goto tooLargeForWide; } + while (numBytes-- > 0) { + value = (value << CHAR_BIT) | *bytes++; + } if (value > ((Tcl_WideUInt)WIDE_MAX + bignumValue->sign)) { goto tooLargeForWide; } -- cgit v0.12