diff options
-rw-r--r-- | generic/tclExecute.c | 25 | ||||
-rw-r--r-- | tests/cmdAH.test | 3 | ||||
-rw-r--r-- | tests/obj.test | 4 | ||||
-rw-r--r-- | unix/tcl.pc.in | 8 | ||||
-rw-r--r-- | unix/tclUnixFile.c | 6 | ||||
-rw-r--r-- | win/tclWinFCmd.c | 5 | ||||
-rw-r--r-- | win/tclWinFile.c | 27 |
7 files changed, 63 insertions, 15 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index cd0371b..25f4951 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5857,6 +5857,31 @@ TEBCresume( case INST_NUM_TYPE: if (GetNumberFromObj(NULL, OBJ_AT_TOS, &ptr1, &type1) != TCL_OK) { type1 = 0; + } else if (type1 == TCL_NUMBER_LONG) { + /* value is between LONG_MIN and LONG_MAX */ + /* [string is integer] is -UINT_MAX to UINT_MAX range */ + int i; + + if (Tcl_GetIntFromObj(NULL, OBJ_AT_TOS, &i) != TCL_OK) { + type1 = TCL_NUMBER_WIDE; + } +#ifndef TCL_WIDE_INT_IS_LONG + } else if (type1 == TCL_NUMBER_WIDE) { + /* value is between WIDE_MIN and WIDE_MAX */ + /* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */ + int i; + if (Tcl_GetIntFromObj(NULL, OBJ_AT_TOS, &i) == TCL_OK) { + type1 = TCL_NUMBER_LONG; + } +#endif + } else if (type1 == TCL_NUMBER_BIG) { + /* value is an integer outside the WIDE_MIN to WIDE_MAX range */ + /* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */ + Tcl_WideInt w; + + if (Tcl_GetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) { + type1 = TCL_NUMBER_WIDE; + } } TclNewLongObj(objResultPtr, type1); TRACE(("\"%.20s\" => %d\n", O2S(OBJ_AT_TOS), type1)); diff --git a/tests/cmdAH.test b/tests/cmdAH.test index 68a9a49..8af1228 100644 --- a/tests/cmdAH.test +++ b/tests/cmdAH.test @@ -139,6 +139,9 @@ test cmdAH-2.6.2 {cd} -constraints {unix nonPortable} -setup { } -cleanup { cd $dir } -result {/} +test cmdAH-2.6.3 {Tcl_CdObjCmd, bug #3118489} -returnCodes error -body { + cd .\0 +} -result "couldn't change working directory to \".\0\": no such file or directory" test cmdAH-2.7 {Tcl_ConcatObjCmd} { concat } {} diff --git a/tests/obj.test b/tests/obj.test index 71a39b4..151abfb 100644 --- a/tests/obj.test +++ b/tests/obj.test @@ -605,7 +605,7 @@ test obj-33.2 {integer overflow on input} {longIs32bit wideBiggerThanInt} { set x 0xffff; append x ffff list [string is integer $x] [expr { wide($x) }] } {1 4294967295} -test obj-33.3 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.3 {integer overflow on input} { set x 0x10000; append x 0000 list [string is integer $x] [expr { wide($x) }] } {0 4294967296} @@ -621,7 +621,7 @@ test obj-33.6 {integer overflow on input} {longIs32bit wideBiggerThanInt} { set x -0xffff; append x ffff list [string is integer $x] [expr { wide($x) }] } {1 -4294967295} -test obj-33.7 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.7 {integer overflow on input} { set x -0x10000; append x 0000 list [string is integer $x] [expr { wide($x) }] } {0 -4294967296} diff --git a/unix/tcl.pc.in b/unix/tcl.pc.in index 6b6fe44..846cb11 100644 --- a/unix/tcl.pc.in +++ b/unix/tcl.pc.in @@ -8,8 +8,8 @@ includedir=@includedir@ Name: Tool Command Language Description: Tcl is a powerful, easy-to-learn dynamic programming language, suitable for a wide range of uses. URL: http://www.tcl.tk/ -Version: @TCL_VERSION@ -Requires: -Conflicts: -Libs: -L${libdir} @TCL_LIB_FLAG@ @TCL_LIBS@ +Version: @TCL_VERSION@@TCL_PATCH_LEVEL@ +Requires.private: zlib >= 1.2.3 +Libs: -L${libdir} @TCL_LIB_FLAG@ @TCL_STUB_LIB_FLAG@ +Libs.private: @TCL_LIBS@ Cflags: -I${includedir} diff --git a/unix/tclUnixFile.c b/unix/tclUnixFile.c index 5bfe5d9..2cb0027 100644 --- a/unix/tclUnixFile.c +++ b/unix/tclUnixFile.c @@ -1105,6 +1105,12 @@ TclNativeCreateNativeRep( str = Tcl_GetStringFromObj(validPathPtr, &len); Tcl_UtfToExternalDString(NULL, str, len, &ds); len = Tcl_DStringLength(&ds) + sizeof(char); + if (strlen(Tcl_DStringValue(&ds)) < len - sizeof(char)) { + /* See bug [3118489]: NUL in filenames */ + Tcl_DecrRefCount(validPathPtr); + Tcl_DStringFree(&ds); + return NULL; + } Tcl_DecrRefCount(validPathPtr); nativePathPtr = ckalloc(len); memcpy(nativePathPtr, Tcl_DStringValue(&ds), (size_t) len); diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c index 0803175..e91f529 100644 --- a/win/tclWinFCmd.c +++ b/win/tclWinFCmd.c @@ -1108,7 +1108,12 @@ DoRemoveJustDirectory( end: if (errorPtr != NULL) { + char *p; Tcl_WinTCharToUtf(nativePath, -1, errorPtr); + p = Tcl_DStringValue(errorPtr); + for (; *p; ++p) { + if (*p == '\\') *p = '/'; + } } return TCL_ERROR; diff --git a/win/tclWinFile.c b/win/tclWinFile.c index f69ad23..fc0ac9e 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -1816,6 +1816,9 @@ TclpObjChdir( nativePath = Tcl_FSGetNativePath(pathPtr); + if (!nativePath) { + return -1; + } result = SetCurrentDirectory(nativePath); if (result == 0) { @@ -2897,7 +2900,8 @@ TclNativeCreateNativeRep( char *nativePathPtr, *str; Tcl_DString ds; Tcl_Obj *validPathPtr; - int len; + int len, i = 2; + WCHAR *wp; if (TclFSCwdIsNative()) { /* @@ -2923,17 +2927,22 @@ TclNativeCreateNativeRep( } str = Tcl_GetStringFromObj(validPathPtr, &len); - if (str[0] == '/' && str[1] == '/' && str[2] == '?' && str[3] == '/') { - char *p; - - for (p = str; p && *p; ++p) { - if (*p == '/') { - *p = '\\'; + Tcl_WinUtfToTChar(str, len, &ds); + len = Tcl_DStringLength(&ds) + sizeof(WCHAR); + wp = (WCHAR *) Tcl_DStringValue(&ds); + for (i=sizeof(WCHAR); i<len; ++wp,i+=sizeof(WCHAR)) { + if ( (*wp < ' ') || wcschr(L"\"*<>|", *wp) ){ + if (!*wp){ + /* See bug [3118489]: NUL in filenames */ + Tcl_DecrRefCount(validPathPtr); + Tcl_DStringFree(&ds); + return NULL; } + *wp |= 0xF000; + }else if (*wp=='/') { + *wp = '\\'; } } - Tcl_WinUtfToTChar(str, len, &ds); - len = Tcl_DStringLength(&ds) + sizeof(WCHAR); Tcl_DecrRefCount(validPathPtr); nativePathPtr = ckalloc(len); memcpy(nativePathPtr, Tcl_DStringValue(&ds), (size_t) len); |