Ticket UUID: | 1109484 | |||
Title: | Tcl_Expr* do not gracefully handle wide ints | |||
Type: | Bug | Version: | obsolete: 8.4.9 | |
Submitter: | hobbs | Created on: | 2005-01-25 23:48:10 | |
Subsystem: | 10. Objects | Assigned To: | dkf | |
Priority: | 8 | Severity: | ||
Status: | Closed | Last Modified: | 2005-01-28 20:38:58 | |
Resolution: | Fixed | Closed By: | hobbs | |
Closed on: | 2005-01-28 01:51:16 | |||
Description: |
The Tcl_Expr* functions in tclBasic.c do checks on the return value to see if it is int or double, but the value could be a wide int that fits into the requisite size. That would prevent an error condition. See this example from TclX: package require Tclx 8.4 (Tcl) 57 % crange abc 1 {end-[expr 1]} b (Tcl) 58 % crange abc 1 {end-[expr wide(1)]} expression didn't have numeric value | |||
User Comments: |
dkf added on 2005-01-28 20:38:58:
Logged In: YES user_id=79902 Added test (expr-old-37.2) in HEAD. dgp added on 2005-01-28 11:37:42: Logged In: YES user_id=80530 I see a fix is now in place. Any chance we can also get some tests for this in the test suite? hobbs added on 2005-01-28 08:51:17: File Added - 117468: 1109484.patch hobbs added on 2005-01-28 08:51:16: Logged In: YES user_id=72656 Fixed with attached patch in 8.5a3 head and 8.4 branch. hobbs added on 2005-01-27 08:29:55: Logged In: YES user_id=72656 This patch reportedly fixed an issue someone was having with TclX, so apparently the problem can creep in in real-life code. Any reason not to go with this solution? hobbs added on 2005-01-26 07:19:48: Logged In: YES user_id=72656 The following is just a teaser patch against core-8-4-branch that should be used in a few places to fix the issue: Index: generic/tclBasic.c =================================================================== RCS file: /cvsroot/tcl/tcl/generic/tclBasic.c,v retrieving revision 1.75.2.10 diff -u -r1.75.2.10 tclBasic.c --- generic/tclBasic.c 29 Sep 2004 19:36:36 -0000 1.75.2.10 +++ generic/tclBasic.c 26 Jan 2005 00:18:55 -0000 @@ -4144,6 +4144,29 @@ *ptr = resultPtr->internalRep.longValue; } else if (resultPtr->typePtr == &tclDoubleType) { *ptr = (long) resultPtr->internalRep.doubleValue; + } else if (resultPtr->typePtr == &tclWideIntType) { +#ifndef TCL_WIDE_INT_IS_LONG + /* + * If the object is already a wide integer, don't convert it. + * This code allows for any integer in the range -ULONG_MAX to + * ULONG_MAX to be converted to a long, ignoring overflow. + * The rule preserves existing semantics for conversion of + * integers on input, but avoids inadvertent demotion of + * wide integers to 32-bit ones in the internal rep. + */ + + Tcl_WideInt w = resultPtr->internalRep.wideValue; + if (w >= -(Tcl_WideInt)(ULONG_MAX) && w <= (Tcl_WideInt)(ULONG_MAX)) { + *ptr = Tcl_WideAsLong(w); + } else { + Tcl_SetResult(interp, + "integer value too large to represent as non-long integer", + TCL_STATIC); + result = TCL_ERROR; + } +#else + *ptr = resultPtr->internalRep.longValue; +#endif } else { Tcl_SetResult(interp, "expression didn't have numeric value", TCL_STATIC); |
Attachments:
- 1109484.patch [download] added by hobbs on 2005-01-28 08:51:17. [details]