From 73442469a2fb07eecd2777eb726527b68e8da8c5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 11 Jan 2019 14:35:40 +0000 Subject: =?UTF-8?q?Fix=20crash=20reported=20by=20reported=20by=20Fran?= =?UTF-8?q?=C3=A7ois=20Vogel=20related=20to:=20[cc1e91552c0ca1817292d951f8?= =?UTF-8?q?c694b28c2b2251|cc1e91552c]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- generic/tclExecute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index cd78adf..94912ce 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5238,7 +5238,7 @@ TEBCresume( /* Every range of an empty list is an empty list */ if (objc == 0) { /* avoid return of not canonical list (e. g. spaces in string repr.) */ - if (ListObjIsCanonical(valuePtr)) { + if (TclListObjIsCanonical(valuePtr)) { TRACE_APPEND(("\n")); NEXT_INST_F(9, 0, 0); } -- cgit v0.12 From ae556e220331b4da078e1a36ed7d80c43c867bb5 Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 11 Jan 2019 16:29:24 +0000 Subject: provided test-cases covering crash fixed by [58c46e74b931d3a1], as well as new test-facility "testpurebytesobj" allowing creation pure bytes object without internal representations (NULL). --- generic/tclTest.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/lrange.test | 26 ++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/generic/tclTest.c b/generic/tclTest.c index 45cca5a..0e34af7 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -220,6 +220,9 @@ static void SpecialFree(char *blockPtr); static int StaticInitProc(Tcl_Interp *interp); static int TestasyncCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); +static int TestpurebytesobjObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); static int TestbytestringObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -570,6 +573,7 @@ Tcltest_Init( Tcl_CreateObjCommand(interp, "gettimes", GetTimesObjCmd, NULL, NULL); Tcl_CreateCommand(interp, "noop", NoopCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "noop", NoopObjCmd, NULL, NULL); + Tcl_CreateObjCommand(interp, "testpurebytesobj", TestpurebytesobjObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testbytestring", TestbytestringObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testwrongnumargs", TestWrongNumArgsObjCmd, NULL, NULL); @@ -4959,6 +4963,56 @@ NoopObjCmd( /* *---------------------------------------------------------------------- * + * TestpurebytesobjObjCmd -- + * + * This object-based procedure constructs a pure bytes object + * without type and with internal representation containing NULL's. + * + * If no argument supplied it returns empty object with tclEmptyStringRep, + * otherwise it returns this as pure bytes object with bytes value equal + * string. + * + * Results: + * Returns the TCL_OK result code. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +TestpurebytesobjObjCmd( + ClientData unused, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* The argument objects. */ +{ + Tcl_Obj *objPtr; + + if (objc > 2) { + Tcl_WrongNumArgs(interp, 1, objv, "?string?"); + return TCL_ERROR; + } + objPtr = Tcl_NewObj(); + /* + objPtr->internalRep.twoPtrValue.ptr1 = NULL; + objPtr->internalRep.twoPtrValue.ptr2 = NULL; + */ + memset(&objPtr->internalRep, 0, sizeof(objPtr->internalRep)); + if (objc == 2) { + const char *s = Tcl_GetStringFromObj(objv[1], &objPtr->length); + objPtr->bytes = ckalloc(objPtr->length + 1); + memcpy(objPtr->bytes, s, objPtr->length); + objPtr->bytes[objPtr->length] = 0; + } + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * * TestbytestringObjCmd -- * * This object-based procedure constructs a string which can diff --git a/tests/lrange.test b/tests/lrange.test index 4ba645d..5bb4ee9 100644 --- a/tests/lrange.test +++ b/tests/lrange.test @@ -15,6 +15,12 @@ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } + +::tcltest::loadTestedCommands +catch [list package require -exact Tcltest [info patchlevel]] + +testConstraint testpurebytesobj [llength [info commands testpurebytesobj]] + test lrange-1.1 {range of list elements} { lrange {a b c d} 1 2 @@ -117,6 +123,26 @@ test lrange-3.7b {not compiled on empty not canonical list (with static and dyna list [$cmd { } 0 1] [$cmd [format %c 32] 0 1] [$cmd [set a { }] 0 1] \ [$cmd { } 0-1 end+1] [$cmd [format %c 32] 0-1 end+1] [$cmd $a 0-1 end+1] } [lrepeat 6 {}] +# following 4 tests could cause a segfault on empty non-lists with tclEmptyStringRep +# (as before the fix [58c46e74b931d3a1]): +test lrange-3.7a.2 {compiled on empty not list object, 2nd regression test, bug [cc1e91552c]} { + list [lrange {} 0 1] [lrange [lindex a -1] 0 1] [lrange [set a {}] 0 1] \ + [lrange {} 0-1 end+1] [lrange [lindex a -1] 0-1 end+1] [lrange $a 0-1 end+1] +} [lrepeat 6 {}] +test lrange-3.7b.2 {not compiled on empty not list object, 2nd regression test, bug [cc1e91552c]} { + set cmd lrange + list [$cmd {} 0 1] [$cmd [lindex a -1] 0 1] [$cmd [set a {}] 0 1] \ + [$cmd {} 0-1 end+1] [$cmd [lindex a -1] 0-1 end+1] [$cmd $a 0-1 end+1] +} [lrepeat 6 {}] +test lrange-3.7c.2 {compiled on empty pure bytes object, 2nd regression test, bug [cc1e91552c]} { + list [lrange [testpurebytesobj] 0 1] [lrange [testpurebytesobj { }] 0 1] [lrange [set a [testpurebytesobj {}]] 0 1] \ + [lrange [testpurebytesobj] 0-1 end+1] [lrange [testpurebytesobj { }] 0-1 end+1] [lrange $a 0-1 end+1] +} [lrepeat 6 {}] +test lrange-3.7d.2 {not compiled on empty pure bytes object, 2nd regression test, bug [cc1e91552c]} { + set cmd lrange + list [$cmd [testpurebytesobj] 0 1] [$cmd [testpurebytesobj { }] 0 1] [$cmd [set a [testpurebytesobj {}]] 0 1] \ + [$cmd [testpurebytesobj] 0-1 end+1] [$cmd [testpurebytesobj { }] 0-1 end+1] [$cmd $a 0-1 end+1] +} [lrepeat 6 {}] # cleanup -- cgit v0.12 From 631a3b78cb6c86df02039a5cd711ac322b932477 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 13 Jan 2019 15:37:42 +0000 Subject: Slightly simpler test for empty string, still covering all cases. Also prepare testpurebytesobj for strings >2G --- generic/tclExecute.c | 2 +- generic/tclTest.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 94912ce..51dd382 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5238,7 +5238,7 @@ TEBCresume( /* Every range of an empty list is an empty list */ if (objc == 0) { /* avoid return of not canonical list (e. g. spaces in string repr.) */ - if (TclListObjIsCanonical(valuePtr)) { + if (!valuePtr->bytes || !valuePtr->bytes[0]) { TRACE_APPEND(("\n")); NEXT_INST_F(9, 0, 0); } diff --git a/generic/tclTest.c b/generic/tclTest.c index 0e34af7..b39ef0a 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -2085,7 +2085,7 @@ TestevalexObjCmd( flags = 0; if (objc == 3) { - const char *global = Tcl_GetStringFromObj(objv[2], &length); + const char *global = Tcl_GetString(objv[2]); if (strcmp(global, "global") != 0) { Tcl_AppendResult(interp, "bad value \"", global, "\": must be global", NULL); @@ -5001,7 +5001,8 @@ TestpurebytesobjObjCmd( */ memset(&objPtr->internalRep, 0, sizeof(objPtr->internalRep)); if (objc == 2) { - const char *s = Tcl_GetStringFromObj(objv[1], &objPtr->length); + const char *s = Tcl_GetString(objv[1]); + objPtr->length = objv[1]->length; objPtr->bytes = ckalloc(objPtr->length + 1); memcpy(objPtr->bytes, s, objPtr->length); objPtr->bytes[objPtr->length] = 0; -- cgit v0.12 From 0e3cc87362584b9a0cc3bb6890dd588e50fd979f Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 14 Jan 2019 08:55:49 +0000 Subject: minor optimization: check length instead of content - don't touch other memory (so potentially fewer cpu-cache washout's) --- generic/tclExecute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 51dd382..fafd511 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5238,7 +5238,7 @@ TEBCresume( /* Every range of an empty list is an empty list */ if (objc == 0) { /* avoid return of not canonical list (e. g. spaces in string repr.) */ - if (!valuePtr->bytes || !valuePtr->bytes[0]) { + if (!valuePtr->bytes || !valuePtr->length) { TRACE_APPEND(("\n")); NEXT_INST_F(9, 0, 0); } -- cgit v0.12 From 6933dc699128b0c5f9f0f2174efcc760a1c35eda Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 14 Jan 2019 10:00:46 +0000 Subject: win: allows testchmod to reset DELETE DACL-mask (repaired several tests winFCmd-6.*, winFCmd-9.3, that should catch EACCESS) --- win/tclWinTest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win/tclWinTest.c b/win/tclWinTest.c index b2fe6c0..aa2c15a 100644 --- a/win/tclWinTest.c +++ b/win/tclWinTest.c @@ -399,11 +399,11 @@ TestplatformChmod( { static const SECURITY_INFORMATION infoBits = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; - /* don't deny DELETE mask (reset writable only, allow test-cases cleanup) */ + /* don't reset change permissions mask (WRITE_DAC, allow test-cases restore it to cleanup) */ static const DWORD readOnlyMask = FILE_DELETE_CHILD | FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY | FILE_WRITE_EA | FILE_APPEND_DATA | FILE_WRITE_DATA - /* | DELETE */; + | DELETE; /* * References to security functions (only available on NT and later). -- cgit v0.12 From ae312970b6c7a2d7eed2af248389ba5b7497602f Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 14 Jan 2019 17:04:24 +0000 Subject: mingw/win-autoconf build: provide tcltest-executable (for consistency reasons); normalizes loading packages calls in test-suite, added build of helpers tcltest (tcltest.cmd) to start tcl-test suite (with all dependencies/facilities) from shell --- win/Makefile.in | 53 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/win/Makefile.in b/win/Makefile.in index 9d955cd..52c7ede 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -116,6 +116,7 @@ GENERIC_DIR_NATIVE = $(shell $(CYGPATH) '$(GENERIC_DIR)') TOMMATH_DIR_NATIVE = $(shell $(CYGPATH) '$(TOMMATH_DIR)') WIN_DIR_NATIVE = $(shell $(CYGPATH) '$(WIN_DIR)') ROOT_DIR_NATIVE = $(shell $(CYGPATH) '$(ROOT_DIR)') +ROOT_DIR_WIN_NATIVE = $(shell cd '$(ROOT_DIR)' ; pwd -W || pwd -P) ZLIB_DIR_NATIVE = $(shell $(CYGPATH) '$(ZLIB_DIR)') #GENERIC_DIR_NATIVE = $(GENERIC_DIR) #TOMMATH_DIR_NATIVE = $(TOMMATH_DIR) @@ -145,7 +146,12 @@ DDE_LIB_FILE = @LIBPREFIX@tcldde$(DDEVER)${LIBSUFFIX} REG_DLL_FILE = tclreg$(REGVER)${DLLSUFFIX} REG_LIB_FILE = @LIBPREFIX@tclreg$(REGVER)${LIBSUFFIX} TEST_DLL_FILE = tcltest$(VER)${DLLSUFFIX} +TEST_EXE_FILE = tcltest${EXESUFFIX} TEST_LIB_FILE = @LIBPREFIX@tcltest$(VER)${LIBSUFFIX} +TEST_LOAD_PRMS = package ifneeded dde 1.4.1 [list load [file normalize ${DDE_DLL_FILE}] dde];\ + package ifneeded registry 1.3.3 [list load [file normalize ${REG_DLL_FILE}] registry] +TEST_LOAD_FACILITIES = package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest];\ + $(TEST_LOAD_PRMS) ZLIB_DLL_FILE = zlib1.dll SHARED_LIBRARIES = $(TCL_DLL_FILE) @ZLIB_DLL_FILE@ @@ -417,7 +423,34 @@ TCL_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n] all: binaries libraries doc packages -tcltest: $(TCLSH) $(TEST_DLL_FILE) +# Test-suite helper (can be used to test Tcl from build directory with all expected modules). +# To start from windows shell use: +# > tcltest.cmd -verbose bps -file fileName.test +# or from mingw/msys shell: +# $ ./tcltest -verbose bps -file fileName.test + +tcltest.cmd: + @echo 'Create tcltest.cmd helpers'; + @(\ + echo '@echo off'; \ + echo 'rem set LANG=en_US'; \ + echo 'set BDP=%~dp0'; \ + echo 'set OWD=%CD%'; \ + echo 'cd /d %TEMP%'; \ + echo 'rem "%BDP%\$(TCLSH)" "$(ROOT_DIR_WIN_NATIVE)/tests/all.tcl" $(TESTFLAGS) -load "$(TEST_LOAD_FACILITIES)" %*'; \ + echo '"%BDP%\$(TEST_EXE_FILE)" "$(ROOT_DIR_WIN_NATIVE)/tests/all.tcl" $(TESTFLAGS) -load "$(TEST_LOAD_PRMS)" %*'; \ + echo 'cd /d %OWD%'; \ + ) > tcltest.cmd; + @(\ + echo '#!/bin/sh'; \ + echo '#LANG=en_US'; \ + echo 'BDP=$$(dirname $$(readlink -f %0))'; \ + echo 'cd /tmp'; \ + echo '#"$$BDP/$(TCLSH)" "$(ROOT_DIR_WIN_NATIVE)/tests/all.tcl" $(TESTFLAGS) -load "$(TEST_LOAD_FACILITIES)" "$$@"'; \ + echo '"$$BDP/$(TEST_EXE_FILE)" "$(ROOT_DIR_WIN_NATIVE)/tests/all.tcl" $(TESTFLAGS) -load "$(TEST_LOAD_PRMS)" "$$@"'; \ + ) > tcltest; + +tcltest: $(TCLSH) $(TEST_EXE_FILE) $(TEST_DLL_FILE) tcltest.cmd binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ winextensions $(TCLSH) @@ -466,6 +499,11 @@ ${TEST_DLL_FILE}: ${TCL_STUB_LIB_FILE} ${TCLTEST_OBJS} @$(RM) ${TEST_DLL_FILE} ${TEST_LIB_FILE} @MAKE_DLL@ ${TCLTEST_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS) +${TEST_EXE_FILE}: ${TCL_STUB_LIB_FILE} ${TCLTEST_OBJS} tclTestMain.${OBJEXT} + @$(RM) ${TEST_EXE_FILE} + $(CC) $(CFLAGS) $(TCLTEST_OBJS) tclTestMain.$(OBJEXT) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ + tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) + # use pre-built zlib1.dll ${ZLIB_DLL_FILE}: ${TCL_STUB_LIB_FILE} @if test "@ZLIB_LIBS@set" != "${ZLIB_DIR_NATIVE}/win32/zdll.libset" ; then \ @@ -483,6 +521,9 @@ ${ZLIB_DLL_FILE}: ${TCL_STUB_LIB_FILE} # Special case object targets +tclTestMain.${OBJEXT}: tclAppInit.c + $(CC) -c $(CC_SWITCHES) -DTCL_TEST -DBUILD_tcl $(EXTFLAGS) $(CC_OBJNAME) $(WIN_DIR)/tclAppInit.c + tclWinInit.${OBJEXT}: tclWinInit.c $(CC) -c $(CC_SWITCHES) -DBUILD_tcl $(EXTFLAGS) @DEPARG@ $(CC_OBJNAME) @@ -711,16 +752,12 @@ test: test-tcl test-packages test-tcl: binaries $(TCLSH) $(CAT32) $(TEST_DLL_FILE) TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \ ./$(TCLSH) "$(ROOT_DIR_NATIVE)/tests/all.tcl" $(TESTFLAGS) \ - -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \ - package ifneeded dde 1.4.1 [list load [file normalize ${DDE_DLL_FILE}] dde]; \ - package ifneeded registry 1.3.3 [list load [file normalize ${REG_DLL_FILE}] registry]" | ./$(CAT32) + -load "$(TEST_LOAD_FACILITIES)" | ./$(CAT32) # Useful target to launch a built tclsh with the proper path,... runtest: binaries $(TCLSH) $(TEST_DLL_FILE) @TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \ - ./$(TCLSH) $(TESTFLAGS) -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \ - package ifneeded dde 1.4.1 [list load [file normalize ${DDE_DLL_FILE}] dde]; \ - package ifneeded registry 1.3.3 [list load [file normalize ${REG_DLL_FILE}] registry]" $(SCRIPT) + ./$(TCLSH) $(TESTFLAGS) -load "$(TEST_LOAD_FACILITIES)" $(SCRIPT) # This target can be used to run tclsh from the build directory via # `make shell SCRIPT=foo.tcl` @@ -744,7 +781,7 @@ cleanhelp: clean: cleanhelp clean-packages $(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out - $(RM) $(TCLSH) $(CAT32) + $(RM) $(TCLSH) $(CAT32) $(TEST_EXE_FILE) $(TEST_DLL_FILE) tcltest.cmd tcltest $(RM) *.pch *.ilk *.pdb distclean: distclean-packages clean -- cgit v0.12 From 4aca9276dfef3ce6d54718351c0a3f80896228ff Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 14 Jan 2019 19:51:02 +0000 Subject: normalize package provide for tcltests 0.1 (declaration moved from pkgIndex.tcl to package source) --- tests/pkgIndex.tcl | 5 +---- tests/tcltests.tcl | 2 ++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/pkgIndex.tcl b/tests/pkgIndex.tcl index 854b943..9d89277 100644 --- a/tests/pkgIndex.tcl +++ b/tests/pkgIndex.tcl @@ -1,6 +1,3 @@ #! /usr/bin/env tclsh -package ifneeded tcltests 0.1 " - source [list $dir/tcltests.tcl] - package provide tcltests 0.1 -" +package ifneeded tcltests 0.1 [list source $dir/tcltests.tcl] diff --git a/tests/tcltests.tcl b/tests/tcltests.tcl index 74d1b40..cfd3ea3 100644 --- a/tests/tcltests.tcl +++ b/tests/tcltests.tcl @@ -9,3 +9,5 @@ testConstraint fileevent [llength [info commands fileevent]] testConstraint thread [ expr {0 == [catch {package require Thread 2.7-}]}] testConstraint notValgrind [expr {![testConstraint valgrind]}] + +package provide tcltests 0.1 -- cgit v0.12 From c1065a28f93d92a848ffb2f35d79df4bc14532f2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 22 Jan 2019 16:52:56 +0000 Subject: Remove some mac OSX pre-10.4 stuff, which is outdated: current build doesn't support this anymore --- macosx/GNUmakefile | 19 ++++--------------- macosx/README | 7 ------- unix/configure | 7 ------- unix/tcl.m4 | 4 ---- win/Makefile.in | 2 +- 5 files changed, 5 insertions(+), 34 deletions(-) diff --git a/macosx/GNUmakefile b/macosx/GNUmakefile index a1b7040..56e5500 100644 --- a/macosx/GNUmakefile +++ b/macosx/GNUmakefile @@ -141,9 +141,9 @@ ifeq (${INSTALL_BUILD},) # symolic link hackery to trick # 'make install INSTALL_ROOT=${OBJ_DIR}' # into building Tcl.framework and tclsh in ${SYMROOT} - @cd "${OBJ_DIR}" && mkdir -p $(dir $(subst ${space},\ ,./${LIBDIR})) $(dir $(subst ${space},\ ,./${BINDIR})) "${SYMROOT}" && \ - rm -f "./${LIBDIR}" "./${BINDIR}" && ln -fs "${SYMROOT}" "./${LIBDIR}" && \ - ln -fs "${SYMROOT}" "./${BINDIR}" && ln -fs "${OBJ_DIR}/tcltest" "${SYMROOT}" + @cd "${OBJ_DIR}" && mkdir -p $(dir $(subst ${space},\ ,.${LIBDIR})) $(dir $(subst ${space},\ ,.${BINDIR})) "${SYMROOT}" && \ + rm -f ".${LIBDIR}" ".${BINDIR}" && ln -fs "${SYMROOT}" ".${LIBDIR}" && \ + ln -fs "${SYMROOT}" ".${BINDIR}" && ln -fs "${OBJ_DIR}/tcltest" "${SYMROOT}" endif install-${PROJECT}: build-${PROJECT} @@ -151,7 +151,7 @@ ifeq (${EMBEDDED_BUILD}_${INSTALL_ROOT},1_) @echo "Cannot install-embedded with empty INSTALL_ROOT !" && false endif ifeq (${EMBEDDED_BUILD},1) - @rm -rf "${INSTALL_ROOT}/${LIBDIR}/Tcl.framework" + @rm -rf "${INSTALL_ROOT}${LIBDIR}/Tcl.framework" endif ${DO_MAKE} ifeq (${INSTALL_BUILD},1) @@ -160,17 +160,6 @@ ifeq (${EMBEDDED_BUILD},1) @rm -f "${INSTALL_ROOT}${BINDIR}/${TCLSH}" && \ rmdir -p "${INSTALL_ROOT}${BINDIR}" 2>&- || true else -# redo prebinding (when not building for Mac OS X 10.4 or later only) - @if [ "`echo "$${MACOSX_DEPLOYMENT_TARGET}" | \ - awk -F '10\\.' '{print int($$2)}'`" -lt 4 -a "`echo "$${CFLAGS}" | \ - awk -F '-mmacosx-version-min=10\\.' '{print int($$2)}'`" -lt 4 ]; \ - then cd ${INSTALL_ROOT}/; \ - if [ ! -d usr/lib ]; then mkdir -p usr && ln -fs /usr/lib usr/ && RM_USRLIB=1; fi; \ - if [ ! -d System ]; then ln -fs /System . && RM_SYSTEM=1; fi; \ - redo_prebinding -r . "./${LIBDIR}/${PRODUCT_NAME}.framework/Versions/${VERSION}/${PRODUCT_NAME}"; \ - redo_prebinding -r . "./${BINDIR}/${TCLSH}"; \ - if [ -n "$${RM_USRLIB:-}" ]; then rm -f usr/lib; rmdir -p usr 2>&-; fi; \ - if [ -n "$${RM_SYSTEM:-}" ]; then rm -f System; fi; fi # install tclsh symbolic link @ln -fs ${TCLSH} "${INSTALL_ROOT}${BINDIR}/tclsh" endif diff --git a/macosx/README b/macosx/README index bcffde3..c25066e 100644 --- a/macosx/README +++ b/macosx/README @@ -128,13 +128,6 @@ on Core and ppc, i386 or x86_64 on Core2/Xeon). Universal builds of Tcl TEA extensions are also possible with CFLAGS set as above, they will be [load]able by universal as well as thin binaries of Tcl. -- To enable weak-linking, set the MACOSX_DEPLOYMENT_TARGET environment variable -to the minimal OS version the binaries should be able to run on, e.g: - export MACOSX_DEPLOYMENT_TARGET=10.4 -This requires at least gcc 3.1; with gcc 4 or later, set/add to CFLAGS instead: - export CFLAGS="-mmacosx-version-min=10.4" -Support for weak-linking was added with 8.4.14/8.5a5. - Detailed Instructions for building with macosx/GNUmakefile ---------------------------------------------------------- diff --git a/unix/configure b/unix/configure index 34669af..159a21b 100755 --- a/unix/configure +++ b/unix/configure @@ -7776,13 +7776,6 @@ fi SHLIB_SUFFIX=".dylib" DL_OBJS="tclLoadDyld.o" DL_LIBS="" - # Don't use -prebind when building for Mac OS X 10.4 or later only: - if test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \ - "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then - - LDFLAGS="$LDFLAGS -prebind" -fi - LDFLAGS="$LDFLAGS -headerpad_max_install_names" echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5 echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6 diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 1953798..f091a6b 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1602,10 +1602,6 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ SHLIB_SUFFIX=".dylib" DL_OBJS="tclLoadDyld.o" DL_LIBS="" - # Don't use -prebind when building for Mac OS X 10.4 or later only: - AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \ - "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [ - LDFLAGS="$LDFLAGS -prebind"]) LDFLAGS="$LDFLAGS -headerpad_max_install_names" AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [ diff --git a/win/Makefile.in b/win/Makefile.in index 52c7ede..8e82548 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -151,7 +151,7 @@ TEST_LIB_FILE = @LIBPREFIX@tcltest$(VER)${LIBSUFFIX} TEST_LOAD_PRMS = package ifneeded dde 1.4.1 [list load [file normalize ${DDE_DLL_FILE}] dde];\ package ifneeded registry 1.3.3 [list load [file normalize ${REG_DLL_FILE}] registry] TEST_LOAD_FACILITIES = package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest];\ - $(TEST_LOAD_PRMS) + $(TEST_LOAD_PRMS) ZLIB_DLL_FILE = zlib1.dll SHARED_LIBRARIES = $(TCL_DLL_FILE) @ZLIB_DLL_FILE@ -- cgit v0.12 From 523ea309ce99ee289cf8bea083fbc10f7d0f5320 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 25 Jan 2019 13:43:59 +0000 Subject: Do not assume that literals have a non-NULL bytes field; user code could purge it. --- generic/tclLiteral.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/generic/tclLiteral.c b/generic/tclLiteral.c index fb7c28a..b6c45ac 100644 --- a/generic/tclLiteral.c +++ b/generic/tclLiteral.c @@ -198,25 +198,36 @@ TclCreateLiteral( for (globalPtr=globalTablePtr->buckets[globalHash] ; globalPtr!=NULL; globalPtr = globalPtr->nextPtr) { objPtr = globalPtr->objPtr; - if ((globalPtr->nsPtr == nsPtr) - && (objPtr->length == length) && ((length == 0) - || ((objPtr->bytes[0] == bytes[0]) - && (memcmp(objPtr->bytes, bytes, (unsigned) length) == 0)))) { + if (globalPtr->nsPtr == nsPtr) { /* - * A literal was found: return it + * Literals should always have UTF-8 representations... but this + * is not guaranteed so we need to be careful anyway. + * + * https://stackoverflow.com/q/54337750/301832 */ - if (newPtr) { - *newPtr = 0; - } - if (globalPtrPtr) { - *globalPtrPtr = globalPtr; - } - if (flags & LITERAL_ON_HEAP) { - ckfree(bytes); + int objLength; + char *objBytes = TclGetStringFromObj(objPtr, &objLength); + + if ((objLength == length) && ((length == 0) + || ((objBytes[0] == bytes[0]) + && (memcmp(objBytes, bytes, (unsigned) length) == 0)))) { + /* + * A literal was found: return it + */ + + if (newPtr) { + *newPtr = 0; + } + if (globalPtrPtr) { + *globalPtrPtr = globalPtr; + } + if (flags & LITERAL_ON_HEAP) { + ckfree(bytes); + } + globalPtr->refCount++; + return objPtr; } - globalPtr->refCount++; - return objPtr; } } if (!newPtr) { -- cgit v0.12