From a5cfbafa9098e5ae4018b3142702fd8138417776 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 17 Jan 2013 13:29:07 +0000 Subject: Proposed fix, by kakaroto, for Bug 2911139: http::geturl abuses vwait on async call --- library/http/http.tcl | 64 ++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 6b82894..4a517ac 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -528,11 +528,10 @@ proc http::geturl {url args} { # If a timeout is specified we set up the after event and arrange for an # asynchronous socket connection. - set sockopts [list] + set sockopts [list -async] if {$state(-timeout) > 0} { set state(after) [after $state(-timeout) \ [list http::reset $token timeout]] - lappend sockopts -async } # If we are using the proxy, we must pass in the full URL that includes @@ -588,10 +587,15 @@ proc http::geturl {url args} { set socketmap($state(socketinfo)) $sock } - # Wait for the connection to complete. + if {![info exists phost]} { + set phost "" + } + fileevent $sock writable [list http::Connect $token $proto $phost $srvurl] - if {$state(-timeout) > 0} { - fileevent $sock writable [list http::Connect $token] + # Wait for the connection to complete. + if {![info exists state(-command)]} { + # geturl does EVERYTHING asynchronously, so if the user + # calls it synchronously, we just do a wait here. http::wait $token if {![info exists state]} { @@ -607,13 +611,29 @@ proc http::geturl {url args} { set err [lindex $state(error) 0] cleanup $token return -code error $err - } elseif {$state(status) ne "connect"} { - # Likely to be connection timeout - return $token } - set state(status) "" } + return $token +} + + +proc http::Connected { token proto phost srvurl} { + variable http + variable urlTypes + + variable $token + upvar 0 $token state + + # Set back the variables needed here + set sock $state(sock) + set isQueryChannel [info exists state(-querychannel)] + set isQuery [info exists state(-query)] + set host [lindex [split $state(socketinfo) :] 0] + set port [lindex [split $state(socketinfo) :] 1] + + set defport [lindex $urlTypes($proto) 0] + # Send data in cr-lf format, but accept any line terminators fconfigure $sock -translation {auto crlf} -buffersize $state(-blocksize) @@ -746,35 +766,17 @@ proc http::geturl {url args} { fileevent $sock readable [list http::Event $sock $token] } - if {![info exists state(-command)]} { - # geturl does EVERYTHING asynchronously, so if the user calls it - # synchronously, we just do a wait here. - - wait $token - if {$state(status) eq "error"} { - # Something went wrong, so throw the exception, and the - # enclosing catch will do cleanup. - return -code error [lindex $state(error) 0] - } - } } err]} then { # The socket probably was never connected, or the connection dropped # later. - # Clean up after events and such, but DON'T call the command callback - # (if available) because we're going to throw an exception from here - # instead. - # if state(status) is error, it means someone's already called Finish # to do the above-described clean up. if {$state(status) ne "error"} { - Finish $token $err 1 + Finish $token $err } - cleanup $token - return -code error $err } - return $token } # Data access functions: @@ -858,7 +860,7 @@ proc http::cleanup {token} { # Sets the status of the connection, which unblocks # the waiting geturl call -proc http::Connect {token} { +proc http::Connect {token proto phost srvurl} { variable $token upvar 0 $token state set err "due to unexpected EOF" @@ -866,10 +868,10 @@ proc http::Connect {token} { [eof $state(sock)] || [set err [fconfigure $state(sock) -error]] ne "" } then { - Finish $token "connect failed $err" 1 + Finish $token "connect failed $err" } else { - set state(status) connect fileevent $state(sock) writable {} + ::http::Connected $token $proto $phost $srvurl } return } -- cgit v0.12 From 0389d9d276a16e5f11a8ec823cb2334e4b5d119a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 22 Jan 2013 08:16:44 +0000 Subject: Fix test-case http-4.14 --- tests/http.test | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/http.test b/tests/http.test index 3a9d4ba..b03df88 100644 --- a/tests/http.test +++ b/tests/http.test @@ -465,8 +465,7 @@ test http-4.14 {http::Event} -body { } http::wait $token http::status $token - # error code varies among platforms. -} -returnCodes 1 -match regexp -result {(connect failed|couldn't open socket)} +} -result {timeout} # Bogus host test http-4.15 {http::Event} -body { # This test may fail if you use a proxy server. That is to be -- cgit v0.12 From 21be09ba34563c7d9fd3b0d013fe643c63f00174 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 22 Jan 2013 21:56:27 +0000 Subject: Bug [3601804]: platformCPUID segmentation fault on Darwin --- unix/tclUnixCompat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/tclUnixCompat.c b/unix/tclUnixCompat.c index 71bd846..1969d1c 100644 --- a/unix/tclUnixCompat.c +++ b/unix/tclUnixCompat.c @@ -698,7 +698,7 @@ TclWinCPUID( "mov %%ebx, %%esi \n\t" /* save what cpuid just put in %ebx */ "mov %%edi, %%ebx \n\t" /* restore the old %ebx */ : "=a"(regsPtr[0]), "=S"(regsPtr[1]), "=c"(regsPtr[2]), "=d"(regsPtr[3]) - : "a"(index) : "edi"); + : "a"(index) : "edi","ebx"); status = TCL_OK; #endif return status; -- cgit v0.12 From ae2b9cd377978ef7018b95e2d16b17042e2eb76b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 22 Jan 2013 22:53:26 +0000 Subject: Now really fix test-case http-4.14 --- tests/http.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/http.test b/tests/http.test index b03df88..3ec0a6f 100644 --- a/tests/http.test +++ b/tests/http.test @@ -464,8 +464,8 @@ test http-4.14 {http::Event} -body { error "bogus return from http::geturl" } http::wait $token - http::status $token -} -result {timeout} + lindex [http::error $token] 0 +} -result {connect failed connection refused} # Bogus host test http-4.15 {http::Event} -body { # This test may fail if you use a proxy server. That is to be -- cgit v0.12 From c58c25ef079a96e684e2be9bdf78040c84c3cf9b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 23 Jan 2013 13:57:30 +0000 Subject: Protect Tcl_GetIndexFromObjStruct from invalid "offset" values, like 0 or -1. Undocumented, because I don't want to promote people start using that. --- generic/tclIndexObj.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/generic/tclIndexObj.c b/generic/tclIndexObj.c index cc50fd3..0103cdb 100644 --- a/generic/tclIndexObj.c +++ b/generic/tclIndexObj.c @@ -144,7 +144,7 @@ Tcl_GetIndexFromObj(interp, objPtr, tablePtr, msg, flags, indexPtr) * returned and an error message is left in interp's result (unless * interp is NULL). The msg argument is used in the error * message; for example, if msg has the value "option" then the - * error message will say something flag 'bad option "foo": must be + * error message will say something like 'bad option "foo": must be * ...' * * Side effects: @@ -176,6 +176,10 @@ Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, Tcl_Obj *resultPtr; IndexRep *indexRep; + /* Protect against invalid values, like -1 or 0. */ + if (offset < (int)sizeof(char *)) { + offset = (int)sizeof(char *); + } /* * See if there is a valid cached result from a previous lookup. */ -- cgit v0.12 From 94605ca2706bce3bfe127eb4168ca135fd02b609 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 24 Jan 2013 18:47:18 +0000 Subject: Silence some compiler warnings. --- generic/tclCkalloc.c | 4 ++++ generic/tclExecute.c | 3 +++ generic/tclFileName.c | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/generic/tclCkalloc.c b/generic/tclCkalloc.c index a9d98ec..6de9720 100644 --- a/generic/tclCkalloc.c +++ b/generic/tclCkalloc.c @@ -149,6 +149,10 @@ TclInitDbCkalloc() if (!ckallocInit) { ckallocInit = 1; ckallocMutexPtr = Tcl_GetAllocMutex(); +#ifndef TCL_THREADS + /* Silence compiler warning */ + (void)ckallocMutexPtr; +#endif } } diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 2a9f8bb..c09b73e 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5118,6 +5118,9 @@ VerifyExprObjType(interp, objPtr) long i; Tcl_WideInt w; GET_WIDE_OR_INT(result, objPtr, i, w); + /* Quiet cranky old compilers that complain about + * setting i, but not using it. */ + (void)i; } else { double d; result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, objPtr, &d); diff --git a/generic/tclFileName.c b/generic/tclFileName.c index 046eaef..bcaadd4 100644 --- a/generic/tclFileName.c +++ b/generic/tclFileName.c @@ -1784,13 +1784,17 @@ TclDoGlob(interp, separators, headPtr, tail, types) int baseLength, quoted, count; int result = TCL_OK; char *name, *p, *openBrace, *closeBrace, *firstSpecialChar, savedChar; + /* char lastChar = 0; + */ int length = Tcl_DStringLength(headPtr); + /* if (length > 0) { lastChar = Tcl_DStringValue(headPtr)[length-1]; } + */ /* * Consume any leading directory separators, leaving tail pointing -- cgit v0.12 From 8d7d6d8cfd4c9f0670d5c20f115e9a69364f3cef Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 24 Jan 2013 21:28:43 +0000 Subject: revert [273bbe926d]: it doesn't work on i386 --- unix/tclUnixCompat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/tclUnixCompat.c b/unix/tclUnixCompat.c index 1969d1c..71bd846 100644 --- a/unix/tclUnixCompat.c +++ b/unix/tclUnixCompat.c @@ -698,7 +698,7 @@ TclWinCPUID( "mov %%ebx, %%esi \n\t" /* save what cpuid just put in %ebx */ "mov %%edi, %%ebx \n\t" /* restore the old %ebx */ : "=a"(regsPtr[0]), "=S"(regsPtr[1]), "=c"(regsPtr[2]), "=d"(regsPtr[3]) - : "a"(index) : "edi","ebx"); + : "a"(index) : "edi"); status = TCL_OK; #endif return status; -- cgit v0.12 From 2ad8238512c29b86039ba28d5e489ffd77069793 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 24 Jan 2013 22:00:50 +0000 Subject: new version of cpuid, which doesn't use the edi register any more. Hopefully that works better on some Darwin. --- unix/tclUnixCompat.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/unix/tclUnixCompat.c b/unix/tclUnixCompat.c index 71bd846..5a3ccd4 100644 --- a/unix/tclUnixCompat.c +++ b/unix/tclUnixCompat.c @@ -693,12 +693,11 @@ TclWinCPUID( /* See: */ #if defined(HAVE_CPUID) - __asm__ __volatile__("mov %%ebx, %%edi \n\t" /* save %ebx */ + __asm__ __volatile__("mov %%ebx, %%esi \n\t" /* save %ebx */ "cpuid \n\t" - "mov %%ebx, %%esi \n\t" /* save what cpuid just put in %ebx */ - "mov %%edi, %%ebx \n\t" /* restore the old %ebx */ + "xchg %%esi, %%ebx \n\t" /* restore the old %ebx */ : "=a"(regsPtr[0]), "=S"(regsPtr[1]), "=c"(regsPtr[2]), "=d"(regsPtr[3]) - : "a"(index) : "edi"); + : "a"(index)); status = TCL_OK; #endif return status; -- cgit v0.12