apnadkarni / iocp

Implements Tcl channels based on Windows I/O completion ports.

Home Page:https://iocp.magicsplat.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Missing check for NULL interp when setting error results

apnadkarni opened this issue · comments

apn: just btw, found a small bug (or inconsistency either) - vtblPtr->getoption can be called with interp = NULL, e. g. https://github.com/apnadkarni/iocp/blob/master/win/tclWinIocp.c#L1472, but some of getoption callback uses interp handle to set error without to check it is NULL

Although the fix is pretty simple in general:

diff --git a/win/tclWinIocpWinsock.c b/win/tclWinIocpWinsock.c
index 26d344d..67709ab 100644
--- a/win/tclWinIocpWinsock.c
+++ b/win/tclWinIocpWinsock.c
@@ -709,12 +711,29 @@ WinsockClientGetOption(
         sprintf_s(integerSpace, sizeof(integerSpace), "%u", dw);
         Tcl_DStringAppend(dsPtr, integerSpace, -1);
         return TCL_OK;
     default:
+      if (interp) {
         Tcl_SetObjResult(
             interp,
             Tcl_ObjPrintf("Internal error: invalid socket option index %d",
                           opt));
+      }
         return TCL_ERROR;
     }
 }

diff --git a/win/tclWinIocpTcp.c b/win/tclWinIocpTcp.c
index fb9fddf..5e91402 100644
--- a/win/tclWinIocpTcp.c
+++ b/win/tclWinIocpTcp.c
@@ -1302,7 +1302,9 @@ IocpTclCode TcpListenerGetOption(
         Tcl_DStringAppend(dsPtr, integerSpace, -1);
         return TCL_OK;
     default:
+      if (interp) {
         Tcl_SetObjResult(interp, Tcl_ObjPrintf("Internal error: invalid socket option index %d", opt));
+      }
         return TCL_ERROR;
     }
 }

but... I see some another troubles here... Certain code pieces show that the interpreter is really needed in getoption handler. For instance:

if (interp != NULL && Tcl_GetVar(interp, SUPPRESS_RDNS_VAR, 0) != NULL) {
noRDNS = NI_NUMERICHOST;
}

It can cause that value of option can deviate by chan configure $s -some-option (interp != NULL) compared to chan configure $s (interp == NULL).
So I think better would be always supply interp handle to vtblPtr->getoption and extend it with something like flags set to TCL_LEAVE_ERR_MSG. This will avoid error reporting overhead by getting of all options and at same point remain the consistent handling depending on interp (variables etc).

The check for interp == NULL is fixed but I don't quite understand the last comment with respect to getoption being passed interp. Are you saying there is a bug there or are you suggesting an optimization? (TBH, I don't care too much about optimizing the error reporting cases)

If I estimate correctly:

  1. supplying interp as NULL is often used to suppress interim error message generation and overwriting of interpreter result.
  2. there are places where interp is expected (see example above where noRDNS will be read from interpreters variable)
  3. therefore it is possible that the config values would deviate sometimes, e. g. as I wrote above:

It can cause that value of option can deviate by chan configure $s -some-option (interp != NULL) compared to chan configure $s (interp == NULL).