diff options
author | sebres <sebres@users.sourceforge.net> | 2017-05-11 15:07:32 (GMT) |
---|---|---|
committer | sebres <sebres@users.sourceforge.net> | 2017-05-11 15:07:32 (GMT) |
commit | 95b07543288c057479a4d167887b372c00707dc0 (patch) | |
tree | d5619c1b47e91ff192841335b65d5c729e8512ef | |
parent | dceaea0327abc9d0e7620a7b2a4af177e9c8d569 (diff) | |
download | tcl-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.
-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); } |