diff options
-rw-r--r-- | generic/tclClockFmt.c | 26 |
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); } |