diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-11-18 21:43:40 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-11-18 21:43:40 (GMT) |
commit | 1c1ee1c59dab10aa856f9ecc8a2e9613aa69c04e (patch) | |
tree | 1bea67c3baaaa170b17938ea61b1b510e07a63e0 /generic/tclObj.c | |
parent | b3caf035b4e0afcd1686d6ac3190f6e0970e8199 (diff) | |
download | tcl-1c1ee1c59dab10aa856f9ecc8a2e9613aa69c04e.zip tcl-1c1ee1c59dab10aa856f9ecc8a2e9613aa69c04e.tar.gz tcl-1c1ee1c59dab10aa856f9ecc8a2e9613aa69c04e.tar.bz2 |
Backout [52a52a65f0], let's see if this fixes the Windows crash
Diffstat (limited to 'generic/tclObj.c')
-rw-r--r-- | generic/tclObj.c | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/generic/tclObj.c b/generic/tclObj.c index 5a52e29..cc792c7 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); @@ -3440,24 +3447,27 @@ Tcl_GetWideUIntFromObj( if (objPtr->typePtr == &tclBignumType) { /* * Must check for those bignum values that can fit in a - * Tcl_WideInt, even when auto-narrowing is enabled. + * Tcl_WideUInt, even when auto-narrowing is enabled. */ mp_int big; Tcl_WideUInt value = 0; size_t numBytes; + Tcl_WideUInt 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 (big.sign == MP_NEG) { goto wideUIntOutOfRange; } - if (value <= (Tcl_WideUInt)UWIDE_MAX) { - *wideUIntPtr = (Tcl_WideUInt)value; - return TCL_OK; + if (mp_to_ubin(&big, bytes, sizeof(Tcl_WideUInt), &numBytes) == MP_OKAY) { + while (numBytes-- > 0) { + value = (value << CHAR_BIT) | *bytes++; } + *wideUIntPtr = (Tcl_WideUInt)value; + return TCL_OK; } + if (interp != NULL) { const char *s = "integer value too large to represent"; Tcl_Obj *msg = Tcl_NewStringObj(s, -1); @@ -3518,18 +3528,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; @@ -3899,15 +3912,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; } |