@@ -8765,6 +8765,13 @@ TclCompareTwoNumbers(
87658765 double d1 , d2 , tmp ;
87668766 Tcl_WideInt w1 , w2 ;
87678767
8768+ /*
8769+ * NOTE: Use Tcl_GetNumberFromObj() in the code below, not
8770+ * Tcl_TakeNumberFromObj() as the latter can modify the value of
8771+ * unshared objects which would be a problem when valuePtr==value2Ptr
8772+ * and unshared. Bug [8dd2807066].
8773+ */
8774+
87688775 (void ) GetNumberFromObj (NULL , valuePtr , & ptr1 , & type1 );
87698776 (void ) GetNumberFromObj (NULL , value2Ptr , & ptr2 , & type2 );
87708777
@@ -8812,7 +8819,7 @@ TclCompareTwoNumbers(
88128819 w2 = (Tcl_WideInt )d2 ;
88138820 goto wideCompare ;
88148821 case TCL_NUMBER_BIG :
8815- Tcl_TakeBignumFromObj (NULL , value2Ptr , & big2 );
8822+ Tcl_GetBignumFromObj (NULL , value2Ptr , & big2 );
88168823 if (mp_isneg (& big2 )) {
88178824 compare = MP_GT ;
88188825 } else {
@@ -8849,7 +8856,7 @@ TclCompareTwoNumbers(
88498856 if (isinf (d1 )) {
88508857 return (d1 > 0.0 ) ? MP_GT : MP_LT ;
88518858 }
8852- Tcl_TakeBignumFromObj (NULL , value2Ptr , & big2 );
8859+ Tcl_GetBignumFromObj (NULL , value2Ptr , & big2 );
88538860 if ((d1 < (double )WIDE_MAX ) && (d1 > (double )WIDE_MIN )) {
88548861 if (mp_isneg (& big2 )) {
88558862 compare = MP_GT ;
@@ -8871,7 +8878,7 @@ TclCompareTwoNumbers(
88718878 break ;
88728879
88738880 case TCL_NUMBER_BIG :
8874- Tcl_TakeBignumFromObj (NULL , valuePtr , & big1 );
8881+ Tcl_GetBignumFromObj (NULL , valuePtr , & big1 );
88758882 switch (type2 ) {
88768883 case TCL_NUMBER_INT :
88778884 compare = mp_cmp_d (& big1 , 0 );
@@ -8898,7 +8905,7 @@ TclCompareTwoNumbers(
88988905 Tcl_InitBignumFromDouble (NULL , d2 , & big2 );
88998906 goto bigCompare ;
89008907 case TCL_NUMBER_BIG :
8901- Tcl_TakeBignumFromObj (NULL , value2Ptr , & big2 );
8908+ Tcl_GetBignumFromObj (NULL , value2Ptr , & big2 );
89028909 bigCompare :
89038910 compare = mp_cmp (& big1 , & big2 );
89048911 mp_clear (& big1 );
0 commit comments