From abe559d7d88c3ba9d0e56cd2aeb7fd3307f1aa0c Mon Sep 17 00:00:00 2001 From: Richard Kreckel Date: Fri, 22 Oct 2004 21:06:36 +0000 Subject: [PATCH] * src/integer/conv/cl_I_to_digits (I_to_digits): Fix an elusive stack overwriting problem. That was the real cause for Debian bug#246319. * src/integer/output/cl_I_print.cc (print_integer): Revert workaround for the bug fixed above. --- ChangeLog | 7 +++++++ src/integer/conv/cl_I_to_digits.cc | 9 ++++++--- src/integer/output/cl_I_print.cc | 5 ----- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index b681024..c646934 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-10-22 Richard B. Kreckel + + * src/integer/conv/cl_I_to_digits (I_to_digits): Fix an elusive stack + overwriting problem. That was the real cause for Debian bug#246319. + * src/integer/output/cl_I_print.cc (print_integer): Revert workaround + for the bug fixed above. + 2004-10-20 Richard B. Kreckel * include/cln/types.h: Use 64 bit digits on x86_64 CPU. diff --git a/src/integer/conv/cl_I_to_digits.cc b/src/integer/conv/cl_I_to_digits.cc index 043832b..7089106 100644 --- a/src/integer/conv/cl_I_to_digits.cc +++ b/src/integer/conv/cl_I_to_digits.cc @@ -306,7 +306,9 @@ void I_to_digits (const cl_I& X, uintD base, cl_digits* erg) var uintD carry = 0; var int carrybits = 0; loop - { if (carrybits >= b) + { if (fixnump(X) && erg->LSBptr-erg_ptr>=cl_value_len) + break; + if (carrybits >= b) { var uintD d = carry & (base-1); next_digit(d); carry = carry >> b; carrybits -= b; @@ -340,6 +342,8 @@ void I_to_digits (const cl_I& X, uintD base, cl_digits* erg) var uintD rest = divu_loop_msp(b_hoch_k,MSDptr,len); // Zerlegen des Restes in seine k Ziffern: var uintC count = k_1; + if (fixnump(X) && count>cl_value_len-1) + count = cl_value_len-1; if ((intDsize>=11) || (count>0)) // (Bei intDsize>=11 ist wegen b<=36 zwangsläufig // k = ceiling(intDsize*log(2)/log(b))-1 >= 2, also count = k_1 > 0.) @@ -350,8 +354,7 @@ void I_to_digits (const cl_I& X, uintD base, cl_digits* erg) divuD(0,rest,base,rest=,d=); #endif next_digit(d); - } - until (--count == 0); + } until (--count == 0); next_digit(rest); // letzte der k Ziffern ablegen // Quotienten normalisieren (max. 1 Digit streichen): if (mspref(MSDptr,0)==0) { msshrink(MSDptr); len--; if (len==0) break; } diff --git a/src/integer/output/cl_I_print.cc b/src/integer/output/cl_I_print.cc index 541709b..65688b4 100644 --- a/src/integer/output/cl_I_print.cc +++ b/src/integer/output/cl_I_print.cc @@ -28,11 +28,6 @@ void print_integer (std::ostream& stream, unsigned int base, const cl_I& z) var uintL need = cl_digits_need(abs_z,base); var uintB* ziffern = cl_alloc_array(uintB,need); // Platz für die Ziffern var cl_digits erg; erg.LSBptr = &ziffern[need]; -#if (defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ < 4)) - // workaround GCC-3 compiler bug fixed in GCC-3.4.0 (cf. Debian bug#246319) - static char dummy[40]; - snprintf(dummy,40,"%d%x%x",need,&erg,erg.LSBptr); -#endif I_to_digits(abs_z,(uintD)base,&erg); // Umwandlung in Ziffern // Ziffern ausgeben: {