summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2015-08-04 17:34:47 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2015-08-04 17:34:47 (GMT)
commite76616d7db8acb6e1cbc5f65b3a9e8893da9cd74 (patch)
tree56662022ae301feefc47a8b02b7bb9553d26bef5
parentbddd4412bf35b9855223424cf9f5e7a23b3dec2c (diff)
parent613d77612c729153bf0100a0fb30b594b23b4706 (diff)
downloadtcl-e76616d7db8acb6e1cbc5f65b3a9e8893da9cd74.zip
tcl-e76616d7db8acb6e1cbc5f65b3a9e8893da9cd74.tar.gz
tcl-e76616d7db8acb6e1cbc5f65b3a9e8893da9cd74.tar.bz2
merge trunk
-rw-r--r--generic/tclBasic.c12
-rw-r--r--generic/tclCompCmds.c8
-rw-r--r--generic/tclCompile.c23
-rw-r--r--generic/tclExecute.c42
-rw-r--r--generic/tclFileName.c4
-rw-r--r--generic/tclNamesp.c12
-rw-r--r--generic/tclOOBasic.c6
-rw-r--r--generic/tclOODefineCmds.c6
-rw-r--r--generic/tclOOMethod.c5
-rw-r--r--generic/tclPanic.c9
-rw-r--r--generic/tclProc.c7
-rw-r--r--generic/tclTest.c6
-rw-r--r--tests/for.test166
-rw-r--r--unix/tclUnixInit.c2
-rw-r--r--win/tclWinFile.c14
15 files changed, 237 insertions, 85 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 886a9ea..4dca671 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -455,7 +455,6 @@ Tcl_CreateInterp(void)
#endif /* TCL_COMPILE_STATS */
char mathFuncName[32];
CallFrame *framePtr;
- int result;
TclInitSubsystems();
@@ -622,11 +621,8 @@ Tcl_CreateInterp(void)
/* This is needed to satisfy GCC 3.3's strict aliasing rules */
framePtr = ckalloc(sizeof(CallFrame));
- result = Tcl_PushCallFrame(interp, (Tcl_CallFrame *) framePtr,
+ (void) Tcl_PushCallFrame(interp, (Tcl_CallFrame *) framePtr,
(Tcl_Namespace *) iPtr->globalNsPtr, /*isProcCallFrame*/ 0);
- if (result != TCL_OK) {
- Tcl_Panic("Tcl_CreateInterp: failed to push the root stack frame");
- }
framePtr->objc = 0;
iPtr->framePtr = framePtr;
@@ -5974,11 +5970,7 @@ TclObjInvokeNamespace(
* command.
*/
- result = TclPushStackFrame(interp, &framePtr, nsPtr, /*isProcFrame*/0);
- if (result != TCL_OK) {
- return TCL_ERROR;
- }
-
+ (void) TclPushStackFrame(interp, &framePtr, nsPtr, /*isProcFrame*/0);
result = TclObjInvoke(interp, objc, objv, flags);
TclPopStackFrame(interp);
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index 6a22a30..041694f 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.c
@@ -2704,13 +2704,9 @@ CompileEachloopCmd(
done:
if (code == TCL_ERROR) {
- if (infoPtr) {
- FreeForeachInfo(infoPtr);
- }
- }
- if (varListObj) {
- Tcl_DecrRefCount(varListObj);
+ FreeForeachInfo(infoPtr);
}
+ Tcl_DecrRefCount(varListObj);
return code;
}
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index 88891df..9beaef1 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.c
@@ -4083,16 +4083,6 @@ TclEmitInvoke(
* calls from inside a [for] increment clause).
*/
- rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_BREAK, &auxBreakPtr);
- if (rangePtr == NULL || rangePtr->type != LOOP_EXCEPTION_RANGE) {
- auxBreakPtr = NULL;
- } else if (auxBreakPtr->stackDepth == envPtr->currStackDepth-wordCount
- && auxBreakPtr->expandTarget == envPtr->expandCount-expandCount) {
- auxBreakPtr = NULL;
- } else {
- breakRange = auxBreakPtr - envPtr->exceptAuxArrayPtr;
- }
-
rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_CONTINUE,
&auxContinuePtr);
if (rangePtr == NULL || rangePtr->type != LOOP_EXCEPTION_RANGE) {
@@ -4101,7 +4091,18 @@ TclEmitInvoke(
&& auxContinuePtr->expandTarget == envPtr->expandCount-expandCount) {
auxContinuePtr = NULL;
} else {
- continueRange = auxBreakPtr - envPtr->exceptAuxArrayPtr;
+ continueRange = auxContinuePtr - envPtr->exceptAuxArrayPtr;
+ }
+
+ rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_BREAK, &auxBreakPtr);
+ if (rangePtr == NULL || rangePtr->type != LOOP_EXCEPTION_RANGE) {
+ auxBreakPtr = NULL;
+ } else if (auxContinuePtr == NULL
+ && auxBreakPtr->stackDepth == envPtr->currStackDepth-wordCount
+ && auxBreakPtr->expandTarget == envPtr->expandCount-expandCount) {
+ auxBreakPtr = NULL;
+ } else {
+ breakRange = auxBreakPtr - envPtr->exceptAuxArrayPtr;
}
if (auxBreakPtr != NULL || auxContinuePtr != NULL) {
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 23fef6c..d285816 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -701,7 +701,7 @@ static Tcl_Obj * ExecuteExtendedUnaryMathOp(int opcode,
Tcl_Obj *valuePtr);
static void FreeExprCodeInternalRep(Tcl_Obj *objPtr);
static ExceptionRange * GetExceptRangeForPc(const unsigned char *pc,
- int catchOnly, ByteCode *codePtr);
+ int searchMode, ByteCode *codePtr);
static const char * GetSrcInfoForPc(const unsigned char *pc,
ByteCode *codePtr, int *lengthPtr,
const unsigned char **pcBeg, int *cmdIdxPtr);
@@ -2863,7 +2863,6 @@ TEBCresume(
* stack-allocated parameter, update the stack pointers.
*/
- esPtr = iPtr->execEnvPtr->execStackPtr;
TD = (TEBCdata *) (((Tcl_Obj **)TD) + moved);
catchTop += moved;
@@ -7814,7 +7813,7 @@ TEBCresume(
}
#endif
if ((result == TCL_CONTINUE) || (result == TCL_BREAK)) {
- rangePtr = GetExceptRangeForPc(pc, /*catchOnly*/ 0, codePtr);
+ rangePtr = GetExceptRangeForPc(pc, result, codePtr);
if (rangePtr == NULL) {
TRACE_APPEND(("no encl. loop or catch, returning %s\n",
StringForResultCode(result)));
@@ -7975,7 +7974,7 @@ TEBCresume(
#endif
goto abnormalReturn;
}
- rangePtr = GetExceptRangeForPc(pc, /*catchOnly*/ 1, codePtr);
+ rangePtr = GetExceptRangeForPc(pc, TCL_ERROR, codePtr);
if (rangePtr == NULL) {
/*
* This is only possible when compiling a [catch] that sends its
@@ -8109,6 +8108,7 @@ TEBCresume(
#undef auxObjList
#undef catchTop
#undef TCONST
+#undef esPtr
static int
FinalizeOONext(
@@ -9962,13 +9962,14 @@ GetSrcInfoForPc(
* ExceptionRange.
*
* Results:
- * In the normal case, catchOnly is 0 (false) and this procedure returns
- * a pointer to the most closely enclosing ExceptionRange structure
- * regardless of whether it is a loop or catch exception range. This is
- * appropriate when processing a TCL_BREAK or TCL_CONTINUE, which will be
- * "handled" either by a loop exception range or a closer catch range. If
- * catchOnly is nonzero, this procedure ignores loop exception ranges and
- * returns a pointer to the closest catch range. If no matching
+ * If the searchMode is TCL_ERROR, this procedure ignores loop exception
+ * ranges and returns a pointer to the closest catch range. If the
+ * searchMode is TCL_BREAK, this procedure returns a pointer to the most
+ * closely enclosing ExceptionRange regardless of whether it is a loop or
+ * catch exception range. If the searchMode is TCL_CONTINUE, this
+ * procedure returns a pointer to the most closely enclosing
+ * ExceptionRange (of any type) skipping only loop exception ranges if
+ * they don't have a sensible continueOffset defined. If no matching
* ExceptionRange is found that encloses pc, a NULL is returned.
*
* Side effects:
@@ -9979,14 +9980,16 @@ GetSrcInfoForPc(
static ExceptionRange *
GetExceptRangeForPc(
- const unsigned char *pc, /* The program counter value for which to
+ const unsigned char *pc, /* The program counter value for which to
* search for a closest enclosing exception
* range. This points to a bytecode
* instruction in codePtr's code. */
- int catchOnly, /* If 0, consider either loop or catch
- * ExceptionRanges in search. If nonzero
+ int searchMode, /* If TCL_BREAK, consider either loop or catch
+ * ExceptionRanges in search. If TCL_ERROR
* consider only catch ranges (and ignore any
- * closer loop ranges). */
+ * closer loop ranges). If TCL_CONTINUE, look
+ * for loop ranges that define a continue
+ * point or a catch range. */
ByteCode *codePtr) /* Points to the ByteCode in which to search
* for the enclosing ExceptionRange. */
{
@@ -10012,8 +10015,13 @@ GetExceptRangeForPc(
start = rangePtr->codeOffset;
if ((start <= pcOffset) &&
(pcOffset < (start + rangePtr->numCodeBytes))) {
- if ((!catchOnly)
- || (rangePtr->type == CATCH_EXCEPTION_RANGE)) {
+ if (rangePtr->type == CATCH_EXCEPTION_RANGE) {
+ return rangePtr;
+ }
+ if (searchMode == TCL_BREAK) {
+ return rangePtr;
+ }
+ if (searchMode == TCL_CONTINUE && rangePtr->continueOffset != -1){
return rangePtr;
}
}
diff --git a/generic/tclFileName.c b/generic/tclFileName.c
index 8ecd9be..919b8d0 100644
--- a/generic/tclFileName.c
+++ b/generic/tclFileName.c
@@ -830,10 +830,10 @@ Tcl_FSJoinToPath(
return TclJoinPath(2, pair);
} else {
int elemc = objc + 1;
- Tcl_Obj *ret, **elemv = ckalloc(elemc*sizeof(Tcl_Obj **));
+ Tcl_Obj *ret, **elemv = ckalloc(elemc*sizeof(Tcl_Obj *));
elemv[0] = pathPtr;
- memcpy(elemv+1, objv, objc*sizeof(Tcl_Obj **));
+ memcpy(elemv+1, objv, objc*sizeof(Tcl_Obj *));
ret = TclJoinPath(elemc, elemv);
ckfree(elemv);
return ret;
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c
index b09a211..37d2227 100644
--- a/generic/tclNamesp.c
+++ b/generic/tclNamesp.c
@@ -3309,11 +3309,8 @@ NRNamespaceEvalCmd(
/* This is needed to satisfy GCC 3.3's strict aliasing rules */
framePtrPtr = &framePtr;
- result = TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
+ (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
namespacePtr, /*isProcCallFrame*/ 0);
- if (result != TCL_OK) {
- return TCL_ERROR;
- }
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
framePtr->objc = objc;
@@ -3730,7 +3727,7 @@ NRNamespaceInscopeCmd(
Tcl_Namespace *namespacePtr;
CallFrame *framePtr, **framePtrPtr;
register Interp *iPtr = (Interp *) interp;
- int i, result;
+ int i;
Tcl_Obj *cmdObjPtr;
if (objc < 3) {
@@ -3752,11 +3749,8 @@ NRNamespaceInscopeCmd(
framePtrPtr = &framePtr; /* This is needed to satisfy GCC's
* strict aliasing rules. */
- result = TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
+ (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
namespacePtr, /*isProcCallFrame*/ 0);
- if (result != TCL_OK) {
- return result;
- }
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
framePtr->objc = objc;
diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c
index 3000bdd..c6a1161 100644
--- a/generic/tclOOBasic.c
+++ b/generic/tclOOBasic.c
@@ -402,7 +402,6 @@ TclOO_Object_Eval(
register const int skip = Tcl_ObjectContextSkippedArgs(context);
CallFrame *framePtr, **framePtrPtr = &framePtr;
Tcl_Obj *scriptPtr;
- int result;
CmdFrame *invoker;
if (objc-1 < skip) {
@@ -415,11 +414,8 @@ TclOO_Object_Eval(
* command(s).
*/
- result = TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
+ (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
Tcl_GetObjectNamespace(object), 0);
- if (result != TCL_OK) {
- return TCL_ERROR;
- }
framePtr->objc = objc;
framePtr->objv = objv; /* Reference counts do not need to be
* incremented here. */
diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c
index 5a6c0ad..c3184be 100644
--- a/generic/tclOODefineCmds.c
+++ b/generic/tclOODefineCmds.c
@@ -646,7 +646,6 @@ InitDefineContext(
Tcl_Obj *const objv[])
{
CallFrame *framePtr, **framePtrPtr = &framePtr;
- int result;
if (namespacePtr == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
@@ -658,11 +657,8 @@ InitDefineContext(
/* framePtrPtr is needed to satisfy GCC 3.3's strict aliasing rules */
- result = TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
+ (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
namespacePtr, FRAME_IS_OO_DEFINE);
- if (result != TCL_OK) {
- return TCL_ERROR;
- }
framePtr->clientData = oPtr;
framePtr->objc = objc;
framePtr->objv = objv; /* Reference counts do not need to be
diff --git a/generic/tclOOMethod.c b/generic/tclOOMethod.c
index e18eeec..34fa108 100644
--- a/generic/tclOOMethod.c
+++ b/generic/tclOOMethod.c
@@ -875,11 +875,8 @@ PushMethodCallFrame(
* This operation may fail.
*/
- result = TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
+ (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
(Tcl_Namespace *) nsPtr, FRAME_IS_PROC|FRAME_IS_METHOD);
- if (result != TCL_OK) {
- goto failureReturn;
- }
fdPtr->framePtr->clientData = contextPtr;
fdPtr->framePtr->objc = objc;
diff --git a/generic/tclPanic.c b/generic/tclPanic.c
index 2a453b9..851695f 100644
--- a/generic/tclPanic.c
+++ b/generic/tclPanic.c
@@ -141,7 +141,14 @@ Tcl_PanicVA(
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
+/* ARGSUSED */
+
+/*
+ * The following comment is here so that Coverity's static analizer knows that
+ * a Tcl_Panic() call can never return and avoids lots of false positives.
+ */
+
+/* coverity[+kill] */
void
Tcl_Panic(
const char *format,
diff --git a/generic/tclProc.c b/generic/tclProc.c
index 7bf63c2..02bda51 100644
--- a/generic/tclProc.c
+++ b/generic/tclProc.c
@@ -1642,12 +1642,9 @@ TclPushProcCallFrame(
*/
framePtrPtr = &framePtr;
- result = TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
+ (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
(Tcl_Namespace *) nsPtr,
(isLambda? (FRAME_IS_PROC|FRAME_IS_LAMBDA) : FRAME_IS_PROC));
- if (result != TCL_OK) {
- return result;
- }
framePtr->objc = objc;
framePtr->objv = objv;
@@ -2055,7 +2052,7 @@ TclProcCompileProc(
procPtr->numCompiledLocals = procPtr->numArgs;
}
- TclPushStackFrame(interp, &framePtr, (Tcl_Namespace *) nsPtr,
+ (void) TclPushStackFrame(interp, &framePtr, (Tcl_Namespace *) nsPtr,
/* isProcCallFrame */ 0);
/*
diff --git a/generic/tclTest.c b/generic/tclTest.c
index 98beae8..e1c2119 100644
--- a/generic/tclTest.c
+++ b/generic/tclTest.c
@@ -4495,7 +4495,6 @@ TestgetvarfullnameCmd(
Tcl_Namespace *namespacePtr;
Tcl_CallFrame *framePtr;
Tcl_Var variable;
- int result;
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "name scope");
@@ -4523,11 +4522,8 @@ TestgetvarfullnameCmd(
if (namespacePtr == NULL) {
return TCL_ERROR;
}
- result = TclPushStackFrame(interp, &framePtr, namespacePtr,
+ (void) TclPushStackFrame(interp, &framePtr, namespacePtr,
/*isProcCallFrame*/ 0);
- if (result != TCL_OK) {
- return result;
- }
}
variable = Tcl_FindNamespaceVar(interp, name, NULL,
diff --git a/tests/for.test b/tests/for.test
index 8abd270..1a65274 100644
--- a/tests/for.test
+++ b/tests/for.test
@@ -1184,6 +1184,172 @@ test for-7.24 {Bug 3614226: ensure that continue from expanded command only clea
expr {$end - $tmp}
}} {return -level 0 -code continue}
} 0
+
+test for-8.0 {Coverity CID 1251203: break vs continue in for-step clause} {
+ apply {{} {
+ for {set k 0} {$k < 3} {incr k} {
+ set j 0
+ list a [\
+ for {set i 0} {$i < 5} {incr i; list a [eval {}]} {
+ incr j
+ }]
+ incr i
+ }
+ list $i $j $k
+ }}
+} {6 5 3}
+test for-8.1 {Coverity CID 1251203: break vs continue in for-step clause} {
+ apply {{} {
+ for {set k 0} {$k < 3} {incr k} {
+ set j 0
+ list a [\
+ for {set i 0} {$i < 5} {incr i;list a [eval break]} {
+ incr j
+ }]
+ incr i
+ }
+ list $i $j $k
+ }}
+} {2 1 3}
+test for-8.2 {Coverity CID 1251203: break vs continue in for-step clause} {
+ apply {{} {
+ for {set k 0} {$k < 3} {incr k} {
+ set j 0
+ list a [\
+ for {set i 0} {$i < 5} {incr i;list a [eval continue]} {
+ incr j
+ }]
+ incr i
+ }
+ list $i $j $k
+ }}
+} {1 1 3}
+test for-8.3 {break in for-step clause} {
+ apply {{} {
+ for {set k 0} {$k < 3} {incr k} {
+ set j 0
+ list a [\
+ for {set i 0} {$i < 5} {incr i; break} {
+ incr j
+ }]
+ incr i
+ }
+ list $i $j $k
+ }}
+} {2 1 3}
+test for-8.4 {continue in for-step clause} {
+ apply {{} {
+ for {set k 0} {$k < 3} {incr k} {
+ set j 0
+ list a [\
+ for {set i 0} {$i < 5} {incr i; continue} {
+ incr j
+ }]
+ incr i
+ }
+ list $i $j $k
+ }}
+} {1 1 3}
+test for-8.5 {break in for-step clause} {
+ apply {{} {
+ for {set k 0} {$k < 3} {incr k} {
+ set j 0
+ list a [\
+ for {set i 0} {$i < 5} {incr i; list a [break]} {
+ incr j
+ }]
+ incr i
+ }
+ list $i $j $k
+ }}
+} {2 1 3}
+test for-8.6 {continue in for-step clause} {
+ apply {{} {
+ for {set k 0} {$k < 3} {incr k} {
+ set j 0
+ list a [\
+ for {set i 0} {$i < 5} {incr i; list a [continue]} {
+ incr j
+ }]
+ incr i
+ }
+ list $i $j $k
+ }}
+} {1 1 3}
+test for-8.7 {break in for-step clause} {
+ apply {{} {
+ for {set k 0} {$k < 3} {incr k} {
+ set j 0
+ list a [\
+ for {set i 0} {$i < 5} {incr i;eval break} {
+ incr j
+ }]
+ incr i
+ }
+ list $i $j $k
+ }}
+} {2 1 3}
+test for-8.8 {continue in for-step clause} {
+ apply {{} {
+ for {set k 0} {$k < 3} {incr k} {
+ set j 0
+ list a [\
+ for {set i 0} {$i < 5} {incr i;eval continue} {
+ incr j
+ }]
+ incr i
+ }
+ list $i $j $k
+ }}
+} {1 1 3}
+test for-8.9 {break in for-step clause} {
+ apply {{} {
+ for {set k 0} {$k < 3} {incr k} {
+ set j 0
+ for {set i 0} {$i < 5} {incr i;eval break} {
+ incr j
+ }
+ incr i
+ }
+ list $i $j $k
+ }}
+} {2 1 3}
+test for-8.10 {continue in for-step clause} {
+ apply {{} {
+ for {set k 0} {$k < 3} {incr k} {
+ set j 0
+ for {set i 0} {$i < 5} {incr i;eval continue} {
+ incr j
+ }
+ incr i
+ }
+ list $i $j $k
+ }}
+} {1 1 3}
+test for-8.11 {break in for-step clause} {
+ apply {{} {
+ for {set k 0} {$k < 3} {incr k} {
+ set j 0
+ for {set i 0} {$i < 5} {incr i;break} {
+ incr j
+ }
+ incr i
+ }
+ list $i $j $k
+ }}
+} {2 1 3}
+test for-8.12 {continue in for-step clause} {
+ apply {{} {
+ for {set k 0} {$k < 3} {incr k} {
+ set j 0
+ for {set i 0} {$i < 5} {incr i;continue} {
+ incr j
+ }
+ incr i
+ }
+ list $i $j $k
+ }}
+} {1 1 3}
# cleanup
::tcltest::cleanupTests
diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c
index 6ff22cc..bb6de90 100644
--- a/unix/tclUnixInit.c
+++ b/unix/tclUnixInit.c
@@ -602,7 +602,7 @@ SearchKnownEncodings(
int left = 0;
int right = sizeof(localeTable)/sizeof(LocaleTable);
- while (left <= right) {
+ while (left < right) {
int test = (left + right)/2;
int code = strcmp(localeTable[test].lang, encoding);
diff --git a/win/tclWinFile.c b/win/tclWinFile.c
index a5b14b4..6b9d373 100644
--- a/win/tclWinFile.c
+++ b/win/tclWinFile.c
@@ -2897,7 +2897,7 @@ ClientData
TclNativeCreateNativeRep(
Tcl_Obj *pathPtr)
{
- WCHAR *nativePathPtr;
+ WCHAR *nativePathPtr = NULL;
const char *str;
Tcl_Obj *validPathPtr;
size_t len;
@@ -2914,6 +2914,7 @@ TclNativeCreateNativeRep(
if (validPathPtr == NULL) {
return NULL;
}
+ /* refCount of validPathPtr was already incremented in Tcl_FSGetTranslatedPath */
} else {
/*
* Make sure the normalized path is set.
@@ -2923,6 +2924,7 @@ TclNativeCreateNativeRep(
if (validPathPtr == NULL) {
return NULL;
}
+ /* validPathPtr returned from Tcl_FSGetNormalizedPath is owned by Tcl, so incr refCount here */
Tcl_IncrRefCount(validPathPtr);
}
@@ -2931,7 +2933,7 @@ TclNativeCreateNativeRep(
if (strlen(str)!=(unsigned int)len) {
/* String contains NUL-bytes. This is invalid. */
- return 0;
+ goto done;
}
/* For a reserved device, strip a possible postfix ':' */
len = WinIsReserved(str);
@@ -2940,13 +2942,13 @@ TclNativeCreateNativeRep(
* 0xC0 0x80 (== overlong NUL). See bug [3118489]: NUL in filenames */
len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, 0, 0);
if (len==0) {
- return 0;
+ goto done;
}
}
/* Overallocate 6 chars, making some room for extended paths */
wp = nativePathPtr = ckalloc( (len+6) * sizeof(WCHAR) );
if (nativePathPtr==0) {
- return 0;
+ goto done;
}
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, nativePathPtr, len+1);
/*
@@ -2997,6 +2999,10 @@ TclNativeCreateNativeRep(
}
++wp;
}
+
+ done:
+
+ TclDecrRefCount(validPathPtr);
return nativePathPtr;
}