From 2507a22c1331a14e20f89bc665f8f8f0810d8da8 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 22 Apr 2017 14:57:17 +0000 Subject: A better way of getting source file location information when disassembling. --- generic/tclDisassemble.c | 34 ++++++++++++++++------------------ generic/tclInt.h | 5 +++-- generic/tclProc.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 1d616fb..f62c260 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -27,9 +27,8 @@ static Tcl_Obj * DisassembleByteCodeObj(Tcl_Interp *interp, Tcl_Obj *objPtr); static int FormatInstruction(ByteCode *codePtr, const unsigned char *pc, Tcl_Obj *bufferObj); -static void GetLocationInformation(Tcl_Interp *interp, - Proc *procPtr, Tcl_Obj **fileObjPtr, - int *linePtr); +static void GetLocationInformation(Proc *procPtr, + Tcl_Obj **fileObjPtr, int *linePtr); static void PrintSourceToObj(Tcl_Obj *appendObj, const char *stringPtr, int maxChars); static void UpdateStringOfInstName(Tcl_Obj *objPtr); @@ -73,8 +72,6 @@ static const Tcl_ObjType tclInstNameType = { static void GetLocationInformation( - Tcl_Interp *interp, /* Where to look up the location - * information. */ Proc *procPtr, /* What to look up the information for. */ Tcl_Obj **fileObjPtr, /* Where to write the information about what * file the code came from. Will be written @@ -88,20 +85,21 @@ GetLocationInformation( * either with the line number or with -1 if * the information is not available. */ { - Interp *iPtr = (Interp *) interp; - Tcl_HashEntry *hePtr; - CmdFrame *cfPtr; + CmdFrame *cfPtr = TclGetCmdFrameForProcedure(procPtr); *fileObjPtr = NULL; *linePtr = -1; - if (iPtr != NULL && procPtr != NULL) { - hePtr = Tcl_FindHashEntry(iPtr->linePBodyPtr, procPtr); - if (hePtr != NULL && (cfPtr = Tcl_GetHashValue(hePtr)) != NULL) { - *linePtr = cfPtr->line[0]; - if (cfPtr->type == TCL_LOCATION_SOURCE) { - *fileObjPtr = cfPtr->data.eval.path; - } - } + if (cfPtr == NULL) { + return; + } + + /* + * Get the source location data out of the CmdFrame. + */ + + *linePtr = cfPtr->line[0]; + if (cfPtr->type == TCL_LOCATION_SOURCE) { + *fileObjPtr = cfPtr->data.eval.path; } } @@ -278,7 +276,7 @@ DisassembleByteCodeObj( Tcl_AppendToObj(bufferObj, " Source ", -1); PrintSourceToObj(bufferObj, codePtr->source, TclMin(codePtr->numSrcBytes, 55)); - GetLocationInformation(interp, codePtr->procPtr, &fileObj, &line); + GetLocationInformation(codePtr->procPtr, &fileObj, &line); if (line > -1 && fileObj != NULL) { Tcl_AppendPrintfToObj(bufferObj, "\n File \"%s\" Line %d", Tcl_GetString(fileObj), line); @@ -1221,7 +1219,7 @@ DisassembleByteCodeAsDicts( * system if it is available. */ - GetLocationInformation(interp, codePtr->procPtr, &file, &line); + GetLocationInformation(codePtr->procPtr, &file, &line); /* * Build the overall result. diff --git a/generic/tclInt.h b/generic/tclInt.h index 1deda3c..fe4fefd 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2940,7 +2940,8 @@ MODULE_SCOPE Tcl_Obj * TclGetBgErrorHandler(Tcl_Interp *interp); MODULE_SCOPE int TclGetChannelFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Channel *chanPtr, int *modePtr, int flags); -MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp, +MODULE_SCOPE CmdFrame * TclGetCmdFrameForProcedure(Proc *procPtr); +MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp, Tcl_Obj *value, int *code); MODULE_SCOPE int TclGetNumberFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, ClientData *clientDataPtr, @@ -3920,7 +3921,7 @@ MODULE_SCOPE int TclCompileAssembleCmd(Tcl_Interp *interp, struct CompileEnv *envPtr); /* - * Functions defined in generic/tclVar.c and currenttly exported only for use + * Functions defined in generic/tclVar.c and currently exported only for use * by the bytecode compiler and engine. Some of these could later be placed in * the public interface. */ diff --git a/generic/tclProc.c b/generic/tclProc.c index ae9e7cd..5c68e17 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -2774,6 +2774,41 @@ MakeLambdaError( } /* + *---------------------------------------------------------------------- + * + * TclGetCmdFrameForProcedure -- + * + * How to get the CmdFrame information for a procedure. + * + * Results: + * A pointer to the CmdFrame (only guaranteed to be valid until the next + * Tcl command is processed or the interpreter's state is otherwise + * modified) or a NULL if the information is not available. + * + * Side effects: + * none. + * + *---------------------------------------------------------------------- + */ + +CmdFrame * +TclGetCmdFrameForProcedure( + Proc *procPtr) /* The procedure whose cmd-frame is to be + * looked up. */ +{ + Tcl_HashEntry *hePtr; + + if (procPtr == NULL || procPtr->iPtr == NULL) { + return NULL; + } + hePtr = Tcl_FindHashEntry(procPtr->iPtr->linePBodyPtr, procPtr); + if (hePtr == NULL) { + return NULL; + } + return (CmdFrame *) Tcl_GetHashValue(hePtr); +} + +/* * Local Variables: * mode: c * c-basic-offset: 4 -- cgit v0.12 From fa02e7f947236f2d780798ba13956209e355036e Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 25 Apr 2017 13:08:52 +0000 Subject: Deal with a couple of obscure causes of warnings on some versions of OSX. --- unix/tclUnixInit.c | 58 ++++++++++++++++++++++++++++++++++++------------------ unix/tclUnixSock.c | 35 +++++++++++++++++++++++++------- 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c index badfb36..67e0b65 100644 --- a/unix/tclUnixInit.c +++ b/unix/tclUnixInit.c @@ -744,6 +744,43 @@ Tcl_GetEncodingNameFromEnvironment( *---------------------------------------------------------------------- */ +#if defined(HAVE_COREFOUNDATION) && MAC_OS_X_VERSION_MAX_ALLOWED > 1020 +/* + * Helper because whether CFLocaleCopyCurrent and CFLocaleGetIdentifier are + * strongly or weakly bound varies by version of OSX, triggering warnings. + */ + +static inline void +InitMacLocaleInfoVar( + CFLocaleRef (*localeCopyCurrent)(void), + CFStringRef (*localeGetIdentifier)(CFLocaleRef), + Tcl_Interp *interp) +{ + CFLocaleRef localeRef; + CFStringRef locale; + char loc[256]; + + if (localeCopyCurrent == NULL || localeGetIdentifier == NULL) { + return; + } + + localeRef = localeCopyCurrent(); + if (!localeRef) { + return; + } + + locale = localeGetIdentifier(localeRef); + if (locale && CFStringGetCString(locale, loc, 256, + kCFStringEncodingUTF8)) { + if (!Tcl_CreateNamespace(interp, "::tcl::mac", NULL, NULL)) { + Tcl_ResetResult(interp); + } + Tcl_SetVar(interp, "::tcl::mac::locale", loc, TCL_GLOBAL_ONLY); + } + CFRelease(localeRef); +} +#endif /*defined(HAVE_COREFOUNDATION) && MAC_OS_X_VERSION_MAX_ALLOWED > 1020*/ + void TclpSetVariables( Tcl_Interp *interp) @@ -762,29 +799,12 @@ TclpSetVariables( #ifdef HAVE_COREFOUNDATION char tclLibPath[MAXPATHLEN + 1]; -#if MAC_OS_X_VERSION_MAX_ALLOWED > 1020 /* * Set msgcat fallback locale to current CFLocale identifier. */ - CFLocaleRef localeRef; - - if (&CFLocaleCopyCurrent != NULL && &CFLocaleGetIdentifier != NULL && - (localeRef = CFLocaleCopyCurrent())) { - CFStringRef locale = CFLocaleGetIdentifier(localeRef); - - if (locale) { - char loc[256]; - - if (CFStringGetCString(locale, loc, 256, kCFStringEncodingUTF8)) { - if (!Tcl_CreateNamespace(interp, "::tcl::mac", NULL, NULL)) { - Tcl_ResetResult(interp); - } - Tcl_SetVar(interp, "::tcl::mac::locale", loc, TCL_GLOBAL_ONLY); - } - } - CFRelease(localeRef); - } +#if MAC_OS_X_VERSION_MAX_ALLOWED > 1020 + InitMacLocaleInfoVar(CFLocaleCopyCurrent, CFLocaleGetIdentifier, interp); #endif /* MAC_OS_X_VERSION_MAX_ALLOWED > 1020 */ if (MacOSXGetLibraryPath(interp, MAXPATHLEN, tclLibPath) == TCL_OK) { diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index ca8d677..e8767e2 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -698,6 +698,33 @@ TcpClose2Proc( * *---------------------------------------------------------------------- */ + +#ifndef NEED_FAKE_RFC2553 +static inline int +IPv6AddressNeedsNumericRendering( + struct in6_addr addr) +{ + if (IN6_ARE_ADDR_EQUAL(&addr, &in6addr_any)) { + return 1; + } + + /* + * The IN6_IS_ADDR_V4MAPPED macro has a problem with aliasing warnings on + * at least some versions of OSX. + */ + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" + if (!IN6_IS_ADDR_V4MAPPED(&addr)) { +#pragma GCC diagnostic pop + return 0; + } + + return (addr.s6_addr[12] == 0 && addr.s6_addr[13] == 0 + && addr.s6_addr[14] == 0 && addr.s6_addr[15] == 0); +} +#endif /* NEED_FAKE_RFC2553 */ + static void TcpHostPortList( Tcl_Interp *interp, @@ -723,13 +750,7 @@ TcpHostPortList( } #ifndef NEED_FAKE_RFC2553 } else if (addr.sa.sa_family == AF_INET6) { - if ((IN6_ARE_ADDR_EQUAL(&addr.sa6.sin6_addr, - &in6addr_any)) - || (IN6_IS_ADDR_V4MAPPED(&addr.sa6.sin6_addr) && - addr.sa6.sin6_addr.s6_addr[12] == 0 && - addr.sa6.sin6_addr.s6_addr[13] == 0 && - addr.sa6.sin6_addr.s6_addr[14] == 0 && - addr.sa6.sin6_addr.s6_addr[15] == 0)) { + if (IPv6AddressNeedsNumericRendering(addr.sa6.sin6_addr)) { flags |= NI_NUMERICHOST; } #endif /* NEED_FAKE_RFC2553 */ -- cgit v0.12 From 1aa76f11131f03e095b8df149e4f8ba406c88cde Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 25 Apr 2017 19:32:46 +0000 Subject: [50750c735a] Fix for uninit memory handling issue in zlib transforms. --- generic/tclZlib.c | 34 ++++++++++++++++------------------ tests/zlib.test | 2 +- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 82486d2..fc20d7e 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -3113,30 +3113,28 @@ ZlibTransformOutput( errorCodePtr); } + /* + * No zero-length writes. Flushes must be explicit. + */ + + if (toWrite == 0) { + return 0; + } + cd->outStream.next_in = (Bytef *) buf; cd->outStream.avail_in = toWrite; - do { + while (cd->outStream.avail_in > 0) { e = Deflate(&cd->outStream, cd->outBuffer, cd->outAllocated, Z_NO_FLUSH, &produced); + if (e != Z_OK || produced == 0) { + break; + } - if ((e == Z_OK && produced > 0) || e == Z_BUF_ERROR) { - /* - * deflate() indicates that it is out of space by returning - * Z_BUF_ERROR *or* by simply returning Z_OK with no remaining - * space; in either case, we must write the whole buffer out and - * retry to compress what is left. - */ - - if (e == Z_BUF_ERROR) { - produced = cd->outAllocated; - e = Z_OK; - } - if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) < 0) { - *errorCodePtr = Tcl_GetErrno(); - return -1; - } + if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) < 0) { + *errorCodePtr = Tcl_GetErrno(); + return -1; } - } while (e == Z_OK && produced > 0 && cd->outStream.avail_in > 0); + } if (e == Z_OK) { return toWrite - cd->outStream.avail_in; diff --git a/tests/zlib.test b/tests/zlib.test index 9f06eb1..c2f7825 100644 --- a/tests/zlib.test +++ b/tests/zlib.test @@ -1004,7 +1004,7 @@ test zlib-12.2 {Patrick Dunnigan's issue} -constraints zlib -setup { } -cleanup { removeFile $filesrc removeFile $filedst -} -result 4152 +} -result 56 ::tcltest::cleanupTests return -- cgit v0.12