summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2017-05-11 15:07:32 (GMT)
committersebres <sebres@users.sourceforge.net>2017-05-11 15:07:32 (GMT)
commit95b07543288c057479a4d167887b372c00707dc0 (patch)
treed5619c1b47e91ff192841335b65d5c729e8512ef /generic
parentdceaea0327abc9d0e7620a7b2a4af177e9c8d569 (diff)
downloadtcl-95b07543288c057479a4d167887b372c00707dc0.zip
tcl-95b07543288c057479a4d167887b372c00707dc0.tar.gz
tcl-95b07543288c057479a4d167887b372c00707dc0.tar.bz2
prevents loss of key object if the format object (where key stored) becomes changed (loses its internal representation during evals);
should avoid possible theoretical segfault there.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclClockFmt.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c
index d875bd4..18b82fa 100644
--- a/generic/tclClockFmt.c
+++ b/generic/tclClockFmt.c
@@ -634,7 +634,7 @@ ClockFmtObj_UpdateString(objPtr)
*
* This is normally stored in second pointer of internal representation.
* If format object is not localizable, it is equal the given format
- * pointer and the first pointer of internal representation may be NULL.
+ * pointer (special case to fast fallback by not-localizable formats).
*
* Results:
* Returns tcl object with key or format object if not localizable.
@@ -825,16 +825,20 @@ ClockLocalizeFormat(
return opts->formatObj;
}
+ /* prevents loss of key object if the format object (where key stored)
+ * becomes changed (loses its internal representation during evals) */
+ Tcl_IncrRefCount(keyObj);
+
if (opts->mcDictObj == NULL) {
ClockMCDict(opts);
if (opts->mcDictObj == NULL)
- return NULL;
+ goto done;
}
/* try to find in cache within locale mc-catalog */
if (Tcl_DictObjGet(NULL, opts->mcDictObj,
keyObj, &valObj) != TCL_OK) {
- return NULL;
+ goto done;
}
/* call LocalizeFormat locale format fmtkey */
@@ -844,10 +848,9 @@ ClockLocalizeFormat(
callargs[1] = opts->localeObj;
callargs[2] = opts->formatObj;
callargs[3] = keyObj;
- Tcl_IncrRefCount(keyObj);
if (Tcl_EvalObjv(opts->interp, 4, callargs, 0) != TCL_OK
) {
- goto clean;
+ goto done;
}
valObj = Tcl_GetObjResult(opts->interp);
@@ -857,9 +860,11 @@ ClockLocalizeFormat(
keyObj, valObj) != TCL_OK
) {
valObj = NULL;
- goto clean;
+ goto done;
}
+ Tcl_ResetResult(opts->interp);
+
/* check special case - format object is not localizable */
if (valObj == opts->formatObj) {
/* mark it as unlocalizable, by setting self as key (without refcount incr) */
@@ -868,14 +873,11 @@ ClockLocalizeFormat(
ObjLocFmtKey(opts->formatObj) = opts->formatObj;
}
}
-clean:
-
- Tcl_UnsetObjRef(keyObj);
- if (valObj) {
- Tcl_ResetResult(opts->interp);
- }
}
+done:
+
+ Tcl_UnsetObjRef(keyObj);
return (opts->formatObj = valObj);
}