From d0996f34029620a4e4469b9b70427b6694cd83e6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 3 Jul 2017 08:27:42 +0000 Subject: 'inline static' -> 'static inline' and 'INLINE' -> 'inline', for consistancy. --- generic/tclStrToD.c | 52 ++++++++++++++++++++++++++-------------------------- generic/tclUtf.c | 4 ++-- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c index 2091928..5d601e4 100644 --- a/generic/tclStrToD.c +++ b/generic/tclStrToD.c @@ -1973,7 +1973,7 @@ RefineApproximation( *---------------------------------------------------------------------- */ -inline static void +static inline void MulPow5( mp_int *base, /* Number to multiply. */ unsigned n, /* Power of 5 to multiply by. */ @@ -2018,7 +2018,7 @@ MulPow5( *---------------------------------------------------------------------- */ -inline static int +static inline int NormalizeRightward( Tcl_WideUInt *wPtr) /* INOUT: Number to shift. */ { @@ -2109,7 +2109,7 @@ RequiredPrecision( *---------------------------------------------------------------------- */ -inline static void +static inline void DoubleToExpAndSig( double dv, /* Number to convert. */ Tcl_WideUInt *significand, /* OUTPUT: Significand of the number. */ @@ -2157,7 +2157,7 @@ DoubleToExpAndSig( *---------------------------------------------------------------------- */ -inline static void +static inline void TakeAbsoluteValue( Double *d, /* Number to replace with absolute value. */ int *sign) /* Place to put the signum. */ @@ -2188,7 +2188,7 @@ TakeAbsoluteValue( *---------------------------------------------------------------------- */ -inline static char * +static inline char * FormatInfAndNaN( Double *d, /* Exceptional number to format. */ int *decpt, /* Decimal point to set to a bogus value. */ @@ -2230,7 +2230,7 @@ FormatInfAndNaN( *---------------------------------------------------------------------- */ -inline static char * +static inline char * FormatZero( int *decpt, /* Location of the decimal point. */ char **endPtr) /* Pointer to the end of the formatted data */ @@ -2260,7 +2260,7 @@ FormatZero( *---------------------------------------------------------------------- */ -inline static int +static inline int ApproximateLog10( Tcl_WideUInt bw, /* Integer significand of the number. */ int be, /* Power of two to scale bw. */ @@ -2308,7 +2308,7 @@ ApproximateLog10( *---------------------------------------------------------------------- */ -inline static int +static inline int BetterLog10( double d, /* Original number to format. */ int k, /* Characteristic(Log base 10) of the @@ -2351,7 +2351,7 @@ BetterLog10( *---------------------------------------------------------------------- */ -inline static void +static inline void ComputeScale( int be, /* Exponent part of number: d = bw * 2**be. */ int k, /* Characteristic of log10(number). */ @@ -2414,7 +2414,7 @@ ComputeScale( *---------------------------------------------------------------------- */ -inline static void +static inline void SetPrecisionLimits( int convType, /* Type of conversion: TCL_DD_SHORTEST, * TCL_DD_STEELE0, TCL_DD_E_FMT, @@ -2475,7 +2475,7 @@ SetPrecisionLimits( *---------------------------------------------------------------------- */ -inline static char * +static inline char * BumpUp( char *s, /* Cursor pointing one past the end of the * string. */ @@ -2509,7 +2509,7 @@ BumpUp( *---------------------------------------------------------------------- */ -inline static int +static inline int AdjustRange( double *dPtr, /* INOUT: Number to adjust. */ int k) /* IN: floor(log10(d)) */ @@ -2582,7 +2582,7 @@ AdjustRange( *---------------------------------------------------------------------- */ -inline static char * +static inline char * ShorteningQuickFormat( double d, /* Number to convert. */ int k, /* floor(log10(d)) */ @@ -2657,7 +2657,7 @@ ShorteningQuickFormat( *---------------------------------------------------------------------- */ -inline static char * +static inline char * StrictQuickFormat( double d, /* Number to convert. */ int k, /* floor(log10(d)) */ @@ -2731,7 +2731,7 @@ StrictQuickFormat( *---------------------------------------------------------------------- */ -inline static char * +static inline char * QuickConversion( double e, /* Number to format. */ int k, /* floor(log10(d)), approximately. */ @@ -2836,7 +2836,7 @@ QuickConversion( *---------------------------------------------------------------------- */ -inline static void +static inline void CastOutPowersOf2( int *b2, /* Power of 2 to multiply the significand. */ int *m2, /* Power of 2 to multiply 1/2 ulp. */ @@ -2880,7 +2880,7 @@ CastOutPowersOf2( *---------------------------------------------------------------------- */ -inline static char * +static inline char * ShorteningInt64Conversion( Double *dPtr, /* Original number to convert. */ int convType, /* Type of conversion (shortest, Steele, @@ -3049,7 +3049,7 @@ ShorteningInt64Conversion( *---------------------------------------------------------------------- */ -inline static char * +static inline char * StrictInt64Conversion( Double *dPtr, /* Original number to convert. */ int convType, /* Type of conversion (shortest, Steele, @@ -3155,7 +3155,7 @@ StrictInt64Conversion( *---------------------------------------------------------------------- */ -inline static int +static inline int ShouldBankerRoundUpPowD( mp_int *b, /* Numerator of the fraction. */ int sd, /* Denominator is 2**(sd*DIGIT_BIT). */ @@ -3193,7 +3193,7 @@ ShouldBankerRoundUpPowD( *---------------------------------------------------------------------- */ -inline static int +static inline int ShouldBankerRoundUpToNextPowD( mp_int *b, /* Numerator of the fraction. */ mp_int *m, /* Numerator of the rounding tolerance. */ @@ -3256,7 +3256,7 @@ ShouldBankerRoundUpToNextPowD( *---------------------------------------------------------------------- */ -inline static char * +static inline char * ShorteningBignumConversionPowD( Double *dPtr, /* Original number to convert. */ int convType, /* Type of conversion (shortest, Steele, @@ -3449,7 +3449,7 @@ ShorteningBignumConversionPowD( *---------------------------------------------------------------------- */ -inline static char * +static inline char * StrictBignumConversionPowD( Double *dPtr, /* Original number to convert. */ int convType, /* Type of conversion (shortest, Steele, @@ -3565,7 +3565,7 @@ StrictBignumConversionPowD( *---------------------------------------------------------------------- */ -inline static int +static inline int ShouldBankerRoundUp( mp_int *twor, /* 2x the remainder from thd division that * produced the last digit. */ @@ -3600,7 +3600,7 @@ ShouldBankerRoundUp( *---------------------------------------------------------------------- */ -inline static int +static inline int ShouldBankerRoundUpToNext( mp_int *b, /* Remainder from the division that produced * the last digit. */ @@ -3654,7 +3654,7 @@ ShouldBankerRoundUpToNext( *---------------------------------------------------------------------- */ -inline static char * +static inline char * ShorteningBignumConversion( Double *dPtr, /* Original number being converted. */ int convType, /* Conversion type. */ @@ -3870,7 +3870,7 @@ ShorteningBignumConversion( *---------------------------------------------------------------------- */ -inline static char * +static inline char * StrictBignumConversion( Double *dPtr, /* Original number being converted. */ int convType, /* Conversion type. */ diff --git a/generic/tclUtf.c b/generic/tclUtf.c index b13ad75..b8b867c 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -98,7 +98,7 @@ static int UtfCount(int ch); *--------------------------------------------------------------------------- */ -INLINE static int +static inline int UtfCount( int ch) /* The Tcl_UniChar whose size is returned. */ { @@ -134,7 +134,7 @@ UtfCount( *--------------------------------------------------------------------------- */ -INLINE int +int Tcl_UniCharToUtf( int ch, /* The Tcl_UniChar to be stored in the * buffer. */ -- cgit v0.12 From 692ea37c40875fdf3db99108dcbd34a4de9d0c22 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 3 Jul 2017 09:15:23 +0000 Subject: tclPathObj: fixed TclJoinPath (backported from 8.6) - usage of released object and object leakage. closes [adb198c256df8c4192838cc3c1112fb2821314e9] --- generic/tclPathObj.c | 154 +++++++++++++++++++++++---------------------------- 1 file changed, 70 insertions(+), 84 deletions(-) diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index 88e49b5..a306853 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -821,50 +821,47 @@ GetExtension( *--------------------------------------------------------------------------- */ +Tcl_Obj * TclJoinPath(int elements, Tcl_Obj * const objv[]); + Tcl_Obj * Tcl_FSJoinPath( Tcl_Obj *listObj, /* Path elements to join, may have a zero * reference count. */ int elements) /* Number of elements to use (-1 = all) */ { - Tcl_Obj *res; - int i; - Tcl_Filesystem *fsPtr = NULL; + Tcl_Obj *copy, *res; + int objc; + Tcl_Obj **objv; - if (elements < 0) { - if (Tcl_ListObjLength(NULL, listObj, &elements) != TCL_OK) { - return NULL; - } - } else { - /* - * Just make sure it is a valid list. - */ - - int listTest; - - if (Tcl_ListObjLength(NULL, listObj, &listTest) != TCL_OK) { - return NULL; - } - - /* - * Correct this if it is too large, otherwise we will waste our time - * joining null elements to the path. - */ - - if (elements > listTest) { - elements = listTest; - } + if (Tcl_ListObjLength(NULL, listObj, &objc) != TCL_OK) { + return NULL; } - res = NULL; + elements = ((elements >= 0) && (elements <= objc)) ? elements : objc; + copy = TclListObjCopy(NULL, listObj); + Tcl_ListObjGetElements(NULL, listObj, &objc, &objv); + res = TclJoinPath(elements, objv); + Tcl_DecrRefCount(copy); + return res; +} + +Tcl_Obj * +TclJoinPath( + int elements, + Tcl_Obj * const objv[]) +{ + Tcl_Obj *res = NULL; /* Resulting path object (container of join) */ + Tcl_Obj *elt; /* Path part (result if returns part of path) */ + int i; + Tcl_Filesystem *fsPtr = NULL; for (i = 0; i < elements; i++) { - Tcl_Obj *elt, *driveName = NULL; int driveNameLength, strEltLen, length; Tcl_PathType type; char *strElt, *ptr; - - Tcl_ListObjIndex(NULL, listObj, i, &elt); + Tcl_Obj *driveName = NULL; + + elt = objv[i]; /* * This is a special case where we can be much more efficient, where @@ -873,19 +870,23 @@ Tcl_FSJoinPath( * object which can be normalized more efficiently. Currently we only * use the special case when we have exactly two elements, but we * could expand that in the future. + * + * Bugfix [a47641a0]. TclNewFSPathObj requires first argument + * to be an absolute path. Added a check for that elt is absolute. */ - if ((i == (elements-2)) && (i == 0) && (elt->typePtr == &tclFsPathType) - && !(elt->bytes != NULL && (elt->bytes[0] == '\0'))) { - Tcl_Obj *tail; + if ((i == (elements-2)) && (i == 0) + && (elt->typePtr == &tclFsPathType) + && !((elt->bytes != NULL) && (elt->bytes[0] == '\0')) + && TclGetPathType(elt, NULL, NULL, NULL) == TCL_PATH_ABSOLUTE) { + Tcl_Obj *tailObj = objv[i+1]; - Tcl_ListObjIndex(NULL, listObj, i+1, &tail); - type = TclGetPathType(tail, NULL, NULL, NULL); + type = TclGetPathType(tailObj, NULL, NULL, NULL); if (type == TCL_PATH_RELATIVE) { const char *str; int len; - str = Tcl_GetStringFromObj(tail, &len); + str = Tcl_GetStringFromObj(tailObj, &len); if (len == 0) { /* * This happens if we try to handle the root volume '/'. @@ -893,10 +894,7 @@ Tcl_FSJoinPath( * the base itself is just fine! */ - if (res != NULL) { - TclDecrRefCount(res); - } - return elt; + goto partReturn; /* return elt; */ } /* @@ -917,20 +915,20 @@ Tcl_FSJoinPath( */ if ((tclPlatform != TCL_PLATFORM_WINDOWS) - || (strchr(Tcl_GetString(elt), '\\') == NULL)) { - if (res != NULL) { - TclDecrRefCount(res); - } - + || (strchr(Tcl_GetString(elt), '\\') == NULL) + ) { if (PATHFLAGS(elt)) { - return TclNewFSPathObj(elt, str, len); + elt = TclNewFSPathObj(elt, str, len); + goto partReturn; /* return elt; */ } if (TCL_PATH_ABSOLUTE != Tcl_FSGetPathType(elt)) { - return TclNewFSPathObj(elt, str, len); + elt = TclNewFSPathObj(elt, str, len); + goto partReturn; /* return elt; */ } (void) Tcl_FSGetNormalizedPath(NULL, elt); if (elt == PATHOBJ(elt)->normPathPtr) { - return TclNewFSPathObj(elt, str, len); + elt = TclNewFSPathObj(elt, str, len); + goto partReturn; /* return elt; */ } } } @@ -940,19 +938,15 @@ Tcl_FSJoinPath( * more general code below handle things. */ } else if (tclPlatform == TCL_PLATFORM_UNIX) { - if (res != NULL) { - TclDecrRefCount(res); - } - return tail; + elt = tailObj; + goto partReturn; /* return elt; */ } else { - const char *str = TclGetString(tail); + const char *str = TclGetString(tailObj); if (tclPlatform == TCL_PLATFORM_WINDOWS) { if (strchr(str, '\\') == NULL) { - if (res != NULL) { - TclDecrRefCount(res); - } - return tail; + elt = tailObj; + goto partReturn; /* return elt; */ } } } @@ -1031,16 +1025,12 @@ Tcl_FSJoinPath( } ptr++; } - if (res != NULL) { - TclDecrRefCount(res); - } - /* - * This element is just what we want to return already - no - * further manipulation is requred. + * This element is just what we want to return already; no further + * manipulation is requred. */ - return elt; + goto partReturn; /* return elt; */ } /* @@ -1051,10 +1041,8 @@ Tcl_FSJoinPath( noQuickReturn: if (res == NULL) { res = Tcl_NewObj(); - ptr = Tcl_GetStringFromObj(res, &length); - } else { - ptr = Tcl_GetStringFromObj(res, &length); } + ptr = Tcl_GetStringFromObj(res, &length); /* * Strip off any './' before a tilde, unless this is the beginning of @@ -1083,10 +1071,11 @@ Tcl_FSJoinPath( int needsSep = 0; if (fsPtr->filesystemSeparatorProc != NULL) { - Tcl_Obj *sep = (*fsPtr->filesystemSeparatorProc)(res); + Tcl_Obj *sep = fsPtr->filesystemSeparatorProc(res); if (sep != NULL) { separator = TclGetString(sep)[0]; + TclDecrRefCount(sep); } /* Safety check in case the VFS driver caused sharing */ if (Tcl_IsShared(res)) { @@ -1126,6 +1115,12 @@ Tcl_FSJoinPath( res = Tcl_NewObj(); } return res; + +partReturn: + if (res != NULL) { + TclDecrRefCount(res); + } + return elt; } /* @@ -2516,27 +2511,18 @@ SetFsPathFromAny( } TclDecrRefCount(parts); } else { - /* - * Simple case. "rest" is relative path. Just join it. The - * "rest" object will be freed when Tcl_FSJoinToPath returns - * (unless something else claims a refCount on it). - */ - - Tcl_Obj *joined; - Tcl_Obj *rest = Tcl_NewStringObj(name+split+1, -1); + Tcl_Obj *pair[2]; - Tcl_IncrRefCount(transPtr); - joined = Tcl_FSJoinToPath(transPtr, 1, &rest); - TclDecrRefCount(transPtr); - transPtr = joined; + pair[0] = transPtr; + pair[1] = Tcl_NewStringObj(name+split+1, -1); + transPtr = TclJoinPath(2, pair); + TclDecrRefCount(pair[0]); + TclDecrRefCount(pair[1]); } } Tcl_DStringFree(&temp); } else { - /* Bug 3479689: protect 0-refcount pathPth from getting freed */ - pathPtr->refCount++; - transPtr = Tcl_FSJoinToPath(pathPtr, 0, NULL); - pathPtr->refCount--; + transPtr = TclJoinPath(1, &pathPtr); } /* -- cgit v0.12 From bcb9c345212df9ab3ea814522a43090b856bd1e9 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 6 Jul 2017 15:46:58 +0000 Subject: Alternative fix for memleaks in fs path join machinery. --- generic/tclPathObj.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index 31ed68e..f8015b2 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -13,6 +13,7 @@ #include "tclInt.h" #include "tclFileSystem.h" +#include /* * Prototypes for functions defined later in this file. @@ -849,11 +850,17 @@ TclJoinPath( int elements, Tcl_Obj * const objv[]) { - Tcl_Obj *res; + Tcl_Obj *res = NULL; int i; const Tcl_Filesystem *fsPtr = NULL; - res = NULL; + assert ( elements >= 0 ); + + if (elements == 0) { + return Tcl_NewObj(); + } + + assert ( elements > 0 ); for (i = 0; i < elements; i++) { int driveNameLength, strEltLen, length; @@ -893,9 +900,7 @@ TclJoinPath( * the base itself is just fine! */ - if (res != NULL) { - TclDecrRefCount(res); - } + assert ( res == NULL ); return elt; } @@ -918,9 +923,8 @@ TclJoinPath( if ((tclPlatform != TCL_PLATFORM_WINDOWS) || (strchr(Tcl_GetString(elt), '\\') == NULL)) { - if (res != NULL) { - TclDecrRefCount(res); - } + + assert ( res == NULL ); if (PATHFLAGS(elt)) { return TclNewFSPathObj(elt, str, len); @@ -940,18 +944,14 @@ TclJoinPath( * more general code below handle things. */ } else if (tclPlatform == TCL_PLATFORM_UNIX) { - if (res != NULL) { - TclDecrRefCount(res); - } + assert ( res == NULL ); return tailObj; } else { const char *str = TclGetString(tailObj); if (tclPlatform == TCL_PLATFORM_WINDOWS) { if (strchr(str, '\\') == NULL) { - if (res != NULL) { - TclDecrRefCount(res); - } + assert ( res == NULL ); return tailObj; } } @@ -1087,6 +1087,7 @@ TclJoinPath( if (sep != NULL) { separator = TclGetString(sep)[0]; + Tcl_DecrRefCount(sep); } /* Safety check in case the VFS driver caused sharing */ if (Tcl_IsShared(res)) { @@ -1122,9 +1123,7 @@ TclJoinPath( Tcl_SetObjLength(res, length); } } - if (res == NULL) { - res = Tcl_NewObj(); - } + assert ( res != NULL ); return res; } -- cgit v0.12 From 515f0f32c030f9972c6c518746e99ecadfb0291f Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 6 Jul 2017 16:00:46 +0000 Subject: Pull out of the loop a block of code that can only run in first iteration. --- generic/tclPathObj.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index f8015b2..8ee4869 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -862,12 +862,8 @@ TclJoinPath( assert ( elements > 0 ); - for (i = 0; i < elements; i++) { - int driveNameLength, strEltLen, length; - Tcl_PathType type; - char *strElt, *ptr; - Tcl_Obj *driveName = NULL; - Tcl_Obj *elt = objv[i]; + if (elements == 2) { + Tcl_Obj *elt = objv[0]; /* * This is a special case where we can be much more efficient, where @@ -876,18 +872,17 @@ TclJoinPath( * object which can be normalized more efficiently. Currently we only * use the special case when we have exactly two elements, but we * could expand that in the future. - * - * Bugfix [a47641a0]. TclNewFSPathObj requires first argument - * to be an absolute path. Added a check for that elt is absolute. + * + * Bugfix [a47641a0]. TclNewFSPathObj requires first argument + * to be an absolute path. Added a check for that elt is absolute. */ - if ((i == (elements-2)) && (i == 0) - && (elt->typePtr == &tclFsPathType) + if ((elt->typePtr == &tclFsPathType) && !((elt->bytes != NULL) && (elt->bytes[0] == '\0')) && TclGetPathType(elt, NULL, NULL, NULL) == TCL_PATH_ABSOLUTE) { - Tcl_Obj *tailObj = objv[i+1]; + Tcl_Obj *tailObj = objv[1]; + Tcl_PathType type = TclGetPathType(tailObj, NULL, NULL, NULL); - type = TclGetPathType(tailObj, NULL, NULL, NULL); if (type == TCL_PATH_RELATIVE) { const char *str; int len; @@ -900,7 +895,6 @@ TclJoinPath( * the base itself is just fine! */ - assert ( res == NULL ); return elt; } @@ -924,8 +918,6 @@ TclJoinPath( if ((tclPlatform != TCL_PLATFORM_WINDOWS) || (strchr(Tcl_GetString(elt), '\\') == NULL)) { - assert ( res == NULL ); - if (PATHFLAGS(elt)) { return TclNewFSPathObj(elt, str, len); } @@ -944,19 +936,28 @@ TclJoinPath( * more general code below handle things. */ } else if (tclPlatform == TCL_PLATFORM_UNIX) { - assert ( res == NULL ); return tailObj; } else { const char *str = TclGetString(tailObj); if (tclPlatform == TCL_PLATFORM_WINDOWS) { if (strchr(str, '\\') == NULL) { - assert ( res == NULL ); return tailObj; } } } } + } + + assert ( res == NULL ); + + for (i = 0; i < elements; i++) { + int driveNameLength, strEltLen, length; + Tcl_PathType type; + char *strElt, *ptr; + Tcl_Obj *driveName = NULL; + Tcl_Obj *elt = objv[i]; + strElt = Tcl_GetStringFromObj(elt, &strEltLen); driveNameLength = 0; type = TclGetPathType(elt, &fsPtr, &driveNameLength, &driveName); -- cgit v0.12