summaryrefslogtreecommitdiffstats
path: root/generic/tclStringObj.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2024-02-05 15:26:42 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2024-02-05 15:26:42 (GMT)
commit21b70feb08dfc39254ed2217b397f61f1682a21a (patch)
tree8d154be86727800ef84bc2008bf24a4936c8b723 /generic/tclStringObj.c
parentee4107080cb9df21f2c3261f45a43f2e01f5564b (diff)
downloadtcl-21b70feb08dfc39254ed2217b397f61f1682a21a.zip
tcl-21b70feb08dfc39254ed2217b397f61f1682a21a.tar.gz
tcl-21b70feb08dfc39254ed2217b397f61f1682a21a.tar.bz2
Fix [2089279]: StringObj.3 Tcl_ObjPrintf inaccuracies.
Not only the documentation, also the behavior in the "unsigned long" case was wrong. Testcases added.
Diffstat (limited to 'generic/tclStringObj.c')
-rw-r--r--generic/tclStringObj.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index 7f9f874..bf6fd9d 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -2677,6 +2677,23 @@ Tcl_Format(
*---------------------------------------------------------------------------
*/
+static Tcl_Obj *
+NewLongObj(
+ char c,
+ long value)
+{
+ if ((value < 0) && strchr("puoxX", c)) {
+#ifdef TCL_WIDE_INT_IS_LONG
+ mp_int bignumValue;
+ mp_init_u64(&bignumValue, (unsigned long)value);
+ return Tcl_NewBignumObj(&bignumValue);
+#else
+ return Tcl_NewWideIntObj((unsigned long)value | ~(unsigned long)LONG_MAX);
+#endif
+ }
+ return Tcl_NewLongObj(value);
+}
+
static void
AppendPrintfToObjVA(
Tcl_Obj *objPtr,
@@ -2755,10 +2772,10 @@ AppendPrintfToObjVA(
case -1:
case 0:
Tcl_ListObjAppendElement(NULL, list, Tcl_NewLongObj(
- (long) va_arg(argList, int)));
+ (long)va_arg(argList, int)));
break;
case 1:
- Tcl_ListObjAppendElement(NULL, list, Tcl_NewLongObj(
+ Tcl_ListObjAppendElement(NULL, list, NewLongObj(*p,
va_arg(argList, long)));
break;
}