diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-11-15 13:31:35 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-11-15 13:31:35 (GMT) |
commit | 1412e9b9f0da015eacc10e723f1e602bf255c697 (patch) | |
tree | ca45b570040a5fd4d358ad4933e2d9318a874a96 | |
parent | c381a177849c7043f3fee5559c42e5f02a7dff14 (diff) | |
parent | 870cb82c96d74e93a642296f68319c777359a11d (diff) | |
download | tcl-1412e9b9f0da015eacc10e723f1e602bf255c697.zip tcl-1412e9b9f0da015eacc10e723f1e602bf255c697.tar.gz tcl-1412e9b9f0da015eacc10e723f1e602bf255c697.tar.bz2 |
Merge 8.7
-rw-r--r-- | doc/LinkVar.3 | 5 | ||||
-rw-r--r-- | generic/tclObj.c | 34 |
2 files changed, 12 insertions, 27 deletions
diff --git a/doc/LinkVar.3 b/doc/LinkVar.3 index 40399ac..db5a90b 100644 --- a/doc/LinkVar.3 +++ b/doc/LinkVar.3 @@ -239,9 +239,8 @@ The C variable, or each element of the C array, is of type \fBTcl_WideUInt\fR (which is an unsigned integer type at least 64-bits wide on all platforms that can support it.) Any value written into the Tcl variable must have a proper unsigned -integer form acceptable to \fBTcl_GetWideIntFromObj\fR (it will be -cast to unsigned); -.\" FIXME! Use bignums instead. +wideinteger form acceptable to \fBTcl_GetBignumFromObj\fR and in the +platform's defined range for the \fBTcl_WideUInt\fR type; attempts to write non-integer values into \fIvarName\fR will be rejected with Tcl errors. Incomplete integer representations (like the empty string, '+', '-' or the hex/octal/decimal/binary prefix) are accepted diff --git a/generic/tclObj.c b/generic/tclObj.c index d385ed0..db4d3c0 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -2678,15 +2678,12 @@ Tcl_GetLongFromObj( { mp_int big; - unsigned long scratch, value = 0; - unsigned char *bytes = (unsigned char *) &scratch; + unsigned long value = 0; size_t numBytes; TclUnpackBignum(objPtr, big); - if (mp_to_ubin(&big, bytes, sizeof(long), &numBytes) == MP_OKAY) { - while (numBytes-- > 0) { - value = (value << CHAR_BIT) | *bytes++; - } + if (mp_pack(&value, 1, + &numBytes, 0, sizeof(Tcl_WideUInt), 0, 0, &big) == MP_OKAY) { if (big.sign) { if (value <= 1 + (unsigned long)LONG_MAX) { *longPtr = (long)(-value); @@ -2918,14 +2915,10 @@ 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_to_ubin(&big, bytes, sizeof(Tcl_WideInt), &numBytes) == MP_OKAY) { - while (numBytes-- > 0) { - value = (value << CHAR_BIT) | *bytes++; - } + if (mp_pack(&value, 1, + &numBytes, 0, sizeof(Tcl_WideUInt), 0, 0, &big) == MP_OKAY) { if (big.sign) { if (value <= 1 + ~(Tcl_WideUInt)WIDE_MIN) { *wideIntPtr = (Tcl_WideInt)(-value); @@ -2998,21 +2991,18 @@ TclGetWideBitsFromObj( mp_int big; mp_err err; - Tcl_WideUInt value = 0, scratch; + Tcl_WideUInt value = 0; 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_to_ubin(&big, bytes, sizeof(Tcl_WideInt), &numBytes); + err = mp_pack(&value, 1, + &numBytes, 0, sizeof(Tcl_WideUInt), 0, 0, &big); } 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; @@ -3382,19 +3372,15 @@ 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_to_ubin(bignumValue, bytes, sizeof(Tcl_WideUInt), &numBytes) != MP_OKAY) { + if (mp_pack(&value, 1, + &numBytes, 0, sizeof(Tcl_WideUInt), 0, 0, bignumValue) != MP_OKAY) { goto tooLargeForWide; } - while (numBytes-- > 0) { - value = (value << CHAR_BIT) | *bytes++; - } if (value > ((Tcl_WideUInt)WIDE_MAX + bignumValue->sign)) { goto tooLargeForWide; } |