diff options
| author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2018-10-06 17:12:46 (GMT) |
|---|---|---|
| committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2018-10-06 17:12:46 (GMT) |
| commit | ac711bcf45a5b5bd09e3102e5ea08f726237212f (patch) | |
| tree | aa1f8b68dd50c5e303d53ca13d43ef7639b4ea95 | |
| parent | b5f75d3392ae32955aaef38e3d3af58119179a73 (diff) | |
| download | tcl-ac711bcf45a5b5bd09e3102e5ea08f726237212f.zip tcl-ac711bcf45a5b5bd09e3102e5ea08f726237212f.tar.gz tcl-ac711bcf45a5b5bd09e3102e5ea08f726237212f.tar.bz2 | |
protect Tcl_WinUtfToTChar/Tcl_WinTCharToUtf against NULL input values: return empty string in that case.
Add TIP #494-compatible definitions of TCL_IO_FAILURE/TCL_AUTO_LENGTH, and use it in some appropriate places.
| -rw-r--r-- | generic/tcl.h | 9 | ||||
| -rw-r--r-- | generic/tclIOCmd.c | 2 | ||||
| -rw-r--r-- | generic/tclIOUtil.c | 8 | ||||
| -rw-r--r-- | generic/tclZipfs.c | 6 | ||||
| -rw-r--r-- | generic/tclZlib.c | 6 | ||||
| -rw-r--r-- | win/tclWin32Dll.c | 8 |
6 files changed, 26 insertions, 13 deletions
diff --git a/generic/tcl.h b/generic/tcl.h index 2ced16b..0971066 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -224,7 +224,7 @@ extern "C" { * to be included in a shared library, then it should have the DLLEXPORT * storage class. If is being declared for use by a module that is going to * link against the shared library, then it should have the DLLIMPORT storage - * class. If the symbol is beind declared for a static build or for use from a + * class. If the symbol is being declared for a static build or for use from a * stub library, then the storage class should be empty. * * The convention is that a macro called BUILD_xxxx, where xxxx is the name of @@ -2334,6 +2334,13 @@ typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp, #define TCL_TCPSERVER_REUSEPORT (1<<1) /* + * Constants for special int-typed values, see TIP #494 + */ + +#define TCL_IO_FAILURE (-1) +#define TCL_AUTO_LENGTH (-1) + +/* *---------------------------------------------------------------------------- * Single public declaration for NRE. */ diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index d38240a..1dd8666 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -991,7 +991,7 @@ Tcl_ExecObjCmd( resultPtr = Tcl_NewObj(); if (Tcl_GetChannelHandle(chan, TCL_READABLE, NULL) == TCL_OK) { - if (Tcl_ReadChars(chan, resultPtr, -1, 0) < 0) { + if (Tcl_ReadChars(chan, resultPtr, -1, 0) == TCL_IO_FAILURE) { /* * TIP #219. * Capture error messages put by the driver into the bypass area diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 11cc22d..63d16be 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -1807,7 +1807,7 @@ Tcl_FSEvalFileEx( * be handled especially. */ - if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) { + if (Tcl_ReadChars(chan, objPtr, 1, 0) == TCL_IO_FAILURE) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", @@ -1822,7 +1822,7 @@ Tcl_FSEvalFileEx( */ if (Tcl_ReadChars(chan, objPtr, -1, - memcmp(string, "\xef\xbb\xbf", 3)) < 0) { + memcmp(string, "\xef\xbb\xbf", 3)) == TCL_IO_FAILURE) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", @@ -1942,7 +1942,7 @@ TclNREvalFile( * be handled especially. */ - if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) { + if (Tcl_ReadChars(chan, objPtr, 1, 0) == TCL_IO_FAILURE) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", @@ -1958,7 +1958,7 @@ TclNREvalFile( */ if (Tcl_ReadChars(chan, objPtr, -1, - memcmp(string, "\xef\xbb\xbf", 3)) < 0) { + memcmp(string, "\xef\xbb\xbf", 3)) == TCL_IO_FAILURE) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index b609779..5342fb1 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -4726,9 +4726,6 @@ TclZipfs_AppHook( #endif /* _WIN32 */ ***argvPtr) /* Pointer to argv */ { -#ifdef _WIN32 - Tcl_DString ds; -#endif /* _WIN32 */ char *archive; Tcl_FindExecutable((*argvPtr)[0]); @@ -4773,6 +4770,9 @@ TclZipfs_AppHook( } #ifdef SUPPORT_BUILTIN_ZIP_INSTALL } else if (*argcPtr > 1) { +#ifdef _WIN32 + Tcl_DString ds; +#endif /* _WIN32 */ /* * If the first argument is "install", run the supplied installer * script. diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 644ac8b..9bad36d 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -2931,7 +2931,7 @@ ZlibTransformClose( result = TCL_ERROR; break; } - if (written && Tcl_WriteRaw(cd->parent, cd->outBuffer, written) < 0) { + if (written && Tcl_WriteRaw(cd->parent, cd->outBuffer, written) == TCL_IO_FAILURE) { /* TODO: is this the right way to do errors on close? * Note: when close is called from FinalizeIOSubsystem then * interp may be NULL */ @@ -3130,7 +3130,7 @@ ZlibTransformOutput( break; } - if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) < 0) { + if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) == TCL_IO_FAILURE) { *errorCodePtr = Tcl_GetErrno(); return -1; } @@ -3186,7 +3186,7 @@ ZlibTransformFlush( * Write the bytes we've received to the next layer. */ - if (len > 0 && Tcl_WriteRaw(cd->parent, cd->outBuffer, len) < 0) { + if (len > 0 && Tcl_WriteRaw(cd->parent, cd->outBuffer, len) == TCL_IO_FAILURE) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "problem flushing channel: %s", Tcl_PosixError(interp))); diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index 1a33514..04d27dd 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -472,6 +472,9 @@ Tcl_WinUtfToTChar( * converted string is stored. */ { Tcl_DStringInit(dsPtr); + if (!string) { + return (TCHAR *)Tcl_DStringValue(dsPtr); + } return Tcl_UtfToUniCharDString(string, len, dsPtr); } @@ -483,12 +486,15 @@ Tcl_WinTCharToUtf( Tcl_DString *dsPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { + Tcl_DStringInit(dsPtr); + if (!string) { + return Tcl_DStringValue(dsPtr); + } if (len > 0) { len /= 2; } else if (len < 0) { len = wcslen(string); } - Tcl_DStringInit(dsPtr); return Tcl_UniCharToUtfDString(string, len, dsPtr); } |
