summaryrefslogtreecommitdiffstats
path: root/generic/tkObj.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2023-09-01 12:43:41 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2023-09-01 12:43:41 (GMT)
commit6596a897b03d3e5a8c192481e47251f124cf6a68 (patch)
tree7d642faf4e7a4c0aa94a572fe98b0f4475579175 /generic/tkObj.c
parent3d4865351a5e9ec4af6a58463a3d7b02ab9cdab7 (diff)
parent90b909515c2a6ff8b67618bca674856b7d23182f (diff)
downloadtk-6596a897b03d3e5a8c192481e47251f124cf6a68.zip
tk-6596a897b03d3e5a8c192481e47251f124cf6a68.tar.gz
tk-6596a897b03d3e5a8c192481e47251f124cf6a68.tar.bz2
Fix [6cc8002951]: numeric parameter errors depending on whether string vs double/int rep
Diffstat (limited to 'generic/tkObj.c')
-rw-r--r--generic/tkObj.c150
1 files changed, 45 insertions, 105 deletions
diff --git a/generic/tkObj.c b/generic/tkObj.c
index 0abf534..47a3201 100644
--- a/generic/tkObj.c
+++ b/generic/tkObj.c
@@ -40,20 +40,6 @@ typedef struct PixelRep {
((PixelRep *) (objPtr)->internalRep.twoPtrValue.ptr2)
/*
- * One of these structures is created per thread to store thread-specific
- * data. In this case, it is used to contain references to selected
- * Tcl_ObjTypes that we can use as screen distances without conversion. The
- * "dataKey" below is used to locate the ThreadSpecificData for the current
- * thread.
- */
-
-typedef struct {
- const Tcl_ObjType *doubleTypePtr;
- const Tcl_ObjType *intTypePtr;
-} ThreadSpecificData;
-static Tcl_ThreadDataKey dataKey;
-
-/*
* The following structure is the internal representation for mm objects.
*/
@@ -87,7 +73,6 @@ static void DupWindowInternalRep(Tcl_Obj *srcPtr,Tcl_Obj*copyPtr);
static void FreeMMInternalRep(Tcl_Obj *objPtr);
static void FreePixelInternalRep(Tcl_Obj *objPtr);
static void FreeWindowInternalRep(Tcl_Obj *objPtr);
-static ThreadSpecificData *GetTypeCache(void);
static void UpdateStringOfMM(Tcl_Obj *objPtr);
static int SetMMFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int SetPixelFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
@@ -137,42 +122,6 @@ static const Tcl_ObjType windowObjType = {
/*
*----------------------------------------------------------------------
*
- * GetTypeCache --
- *
- * Get (and build if necessary) the cache of useful Tcl object types for
- * comparisons in the conversion functions. This allows optimized checks
- * for standard cases.
- *
- *----------------------------------------------------------------------
- */
-
-static ThreadSpecificData *
-GetTypeCache(void)
-{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
- if (tsdPtr->doubleTypePtr == NULL) {
- /* Smart initialization of doubleTypePtr/intTypePtr without
- * hash-table lookup or creating complete Tcl_Obj's */
- Tcl_Obj obj;
- obj.length = 3;
- obj.bytes = (char *)"0.0";
- obj.typePtr = NULL;
- Tcl_GetDoubleFromObj(NULL, &obj, &obj.internalRep.doubleValue);
- tsdPtr->doubleTypePtr = obj.typePtr;
- obj.bytes += 2;
- obj.length = 1;
- obj.typePtr = NULL;
- Tcl_GetLongFromObj(NULL, &obj, &obj.internalRep.longValue);
- tsdPtr->intTypePtr = obj.typePtr;
- }
- return tsdPtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* GetPixelsFromObjEx --
*
* Attempt to return a pixel value from the Tcl object "objPtr". If the
@@ -207,29 +156,14 @@ GetPixelsFromObjEx(
1.0, 10.0, 25.4, 0.35278 /*25.4 / 72.0*/
};
- /*
- * Special hacks where the type of the object is known to be something
- * that is just numeric and cannot require distance conversion. This pokes
- * holes in Tcl's abstractions, but they are just for optimization, not
- * semantics.
- */
-
if (objPtr->typePtr != &pixelObjType) {
- ThreadSpecificData *typeCache = GetTypeCache();
- if (objPtr->typePtr == typeCache->doubleTypePtr) {
- (void) Tcl_GetDoubleFromObj(interp, objPtr, &d);
+ if (Tcl_GetDoubleFromObj(NULL, objPtr, &d) == TCL_OK) {
if (dblPtr != NULL) {
*dblPtr = d;
}
*intPtr = (int) (d<0 ? d-0.5 : d+0.5);
return TCL_OK;
- } else if (objPtr->typePtr == typeCache->intTypePtr) {
- (void) Tcl_GetIntFromObj(interp, objPtr, intPtr);
- if (dblPtr) {
- *dblPtr = (double) (*intPtr);
- }
- return TCL_OK;
}
}
@@ -458,36 +392,50 @@ SetPixelFromAny(
double d;
int i, units;
- string = Tcl_GetString(objPtr);
+ if (Tcl_GetIntFromObj(NULL, objPtr, &units) == TCL_OK) {
+ d = (double) units;
+ units = -1;
- d = strtod(string, &rest);
- if (rest == string) {
- goto error;
- }
- while ((*rest != '\0') && isspace(UCHAR(*rest))) {
- rest++;
- }
+ /*
+ * In the case of ints, we need to ensure that a valid string exists
+ * in order for int-but-not-string objects to be converted back to
+ * ints again from pixel obj types.
+ */
- switch (*rest) {
- case '\0':
+ (void) Tcl_GetString(objPtr);
+ } else if (Tcl_GetDoubleFromObj(NULL, objPtr, &d) == TCL_OK) {
units = -1;
- break;
- case 'm':
- units = 0;
- break;
- case 'c':
- units = 1;
- break;
- case 'i':
- units = 2;
- break;
- case 'p':
- units = 3;
- break;
- default:
- goto error;
- }
+ } else {
+ string = Tcl_GetString(objPtr);
+ d = strtod(string, &rest);
+ if (rest == string) {
+ goto error;
+ }
+ while ((*rest != '\0') && isspace(UCHAR(*rest))) {
+ rest++;
+ }
+
+ switch (*rest) {
+ case '\0':
+ units = -1;
+ break;
+ case 'm':
+ units = 0;
+ break;
+ case 'c':
+ units = 1;
+ break;
+ case 'i':
+ units = 2;
+ break;
+ case 'p':
+ units = 3;
+ break;
+ default:
+ goto error;
+ }
+ }
/*
* Free the old internalRep before setting the new one.
*/
@@ -708,19 +656,14 @@ SetMMFromAny(
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
Tcl_Obj *objPtr) /* The object to convert. */
{
- ThreadSpecificData *typeCache = GetTypeCache();
const Tcl_ObjType *typePtr;
- const char *string;
+ char *string;
char *rest;
double d;
int units;
MMRep *mmPtr;
- if (objPtr->typePtr == typeCache->doubleTypePtr) {
- Tcl_GetDoubleFromObj(interp, objPtr, &d);
- units = -1;
- } else if (objPtr->typePtr == typeCache->intTypePtr) {
- Tcl_GetIntFromObj(interp, objPtr, &units);
+ if (Tcl_GetIntFromObj(NULL, objPtr, &units) == TCL_OK) {
d = (double) units;
units = -1;
@@ -731,6 +674,8 @@ SetMMFromAny(
*/
(void) Tcl_GetString(objPtr);
+ } else if (Tcl_GetDoubleFromObj(NULL, objPtr, &d) == TCL_OK) {
+ units = -1;
} else {
/*
* It wasn't a known int or double, so parse it.
@@ -740,11 +685,6 @@ SetMMFromAny(
d = strtod(string, &rest);
if (rest == string) {
- /*
- * Must copy string before resetting the result in case a caller
- * is trying to convert the interpreter's result to mms.
- */
-
error:
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad screen distance \"%s\"", string));