Check-in [e42b1e808c]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:merge trunk
Timelines: family | ancestors | descendants | both | dgp-refactor
Files: files | file ages | folders
SHA3-256: e42b1e808c0490b3c6f204cb0e91017530a818ac3a27206d4b4e0de315810c09
User & Date: dgp 2025-03-06 15:16:21.123
Context
2025-03-14
15:41
merge trunk check-in: 1c2f2f24cf user: dgp tags: dgp-refactor
2025-03-06
15:16
merge trunk check-in: e42b1e808c user: dgp tags: dgp-refactor
15:15
merge 9.0 check-in: 938b305b98 user: dgp tags: trunk, main
2025-03-05
16:12
merge trunk check-in: 00abfd892a user: dgp tags: dgp-refactor
Changes
Unified Diff Ignore Whitespace Patch
Changes to generic/tclIO.c.
6059
6060
6061
6062
6063
6064
6065
6066

6067
6068
6069
6070
6071
6072
6073
		    && !GotFlag(statePtr, CHANNEL_STICKY_EOF)
		    && (!GotFlag(statePtr, CHANNEL_NONBLOCKING))) {
		goto finish;
	    }
	}

	if (copiedNow < 0) {
	    if (GotFlag(statePtr, CHANNEL_EOF)) {

		break;
	    }
	    if ((GotFlag(statePtr, CHANNEL_NONBLOCKING) || allowShortReads)
		    && GotFlag(statePtr, CHANNEL_BLOCKED)) {
		break;
	    }
	    result = GetInput(chanPtr);







|
>







6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
		    && !GotFlag(statePtr, CHANNEL_STICKY_EOF)
		    && (!GotFlag(statePtr, CHANNEL_NONBLOCKING))) {
		goto finish;
	    }
	}

	if (copiedNow < 0) {
	    if (GotFlag(statePtr, CHANNEL_EOF) || 
	        GotFlag(statePtr, CHANNEL_ENCODING_ERROR)) {
		break;
	    }
	    if ((GotFlag(statePtr, CHANNEL_NONBLOCKING) || allowShortReads)
		    && GotFlag(statePtr, CHANNEL_BLOCKED)) {
		break;
	    }
	    result = GetInput(chanPtr);
Changes to generic/tclResult.c.
1170
1171
1172
1173
1174
1175
1176











1177
1178
1179
1180
1181
1182
1183
	if (tiPtr->returnOpts) {
	    Tcl_DecrRefCount(tiPtr->returnOpts);
	    tiPtr->returnOpts = NULL;
	}
    } else {
	Tcl_SetReturnOptions(targetInterp,
		Tcl_GetReturnOptions(sourceInterp, code));











	tiPtr->flags &= ~(ERR_ALREADY_LOGGED);
    }
    Tcl_SetObjResult(targetInterp, Tcl_GetObjResult(sourceInterp));
    Tcl_ResetResult(sourceInterp);
}

/*







>
>
>
>
>
>
>
>
>
>
>







1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
	if (tiPtr->returnOpts) {
	    Tcl_DecrRefCount(tiPtr->returnOpts);
	    tiPtr->returnOpts = NULL;
	}
    } else {
	Tcl_SetReturnOptions(targetInterp,
		Tcl_GetReturnOptions(sourceInterp, code));
	/*
	 * Add line number if needed: not in line 1 and info contains no number
	 * yet at end of the stack (e. g. proc etc), to avoid double reporting
	 */
	if (siPtr->errorLine > 1 && tiPtr->errorInfo &&
	    tiPtr->errorInfo->length &&
	    tiPtr->errorInfo->bytes[tiPtr->errorInfo->length-1] != ')'
	) {
	    Tcl_AppendObjToErrorInfo(targetInterp, Tcl_ObjPrintf(
		    "\n    (\"interp eval\" body line %d)", siPtr->errorLine));
	}
	tiPtr->flags &= ~(ERR_ALREADY_LOGGED);
    }
    Tcl_SetObjResult(targetInterp, Tcl_GetObjResult(sourceInterp));
    Tcl_ResetResult(sourceInterp);
}

/*
Changes to tests/interp.test.
2217
2218
2219
2220
2221
2222
2223
















2224
2225
2226
2227
2228
2229
2230
    interp alias $interp test {} MyTestAlias $interp
    interp eval $interp {catch test;set ::errorInfo}
} -cleanup {
    interp delete $interp
} -result {msg
    while executing
"test"}

















# Interps & Namespaces
test interp-27.1 {interp aliases & namespaces} -setup {
    set i [interp create]
} -body {
    set aliasTrace {}
    proc tstAlias {args} {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
    interp alias $interp test {} MyTestAlias $interp
    interp eval $interp {catch test;set ::errorInfo}
} -cleanup {
    interp delete $interp
} -result {msg
    while executing
"test"}
test interp-26.9 {error transmission: body line number in info similar to eval-cmd, bug [ba68d1e9484a3a92]} -setup {
    set interp [interp create]
} -body {
    # eval body with multiline code (error in line 3):
    catch {
	$interp eval "#1st line\n#2nd line\nexpr {1/0}"
    } msg res
    dict get $res -errorinfo
} -cleanup {
    interp delete $interp
} -result {divide by zero
    invoked from within
"expr {1/0}"
    ("interp eval" body line 3)
    invoked from within
"$interp eval "#1st line\n#2nd line\nexpr {1/0}""}

# Interps & Namespaces
test interp-27.1 {interp aliases & namespaces} -setup {
    set i [interp create]
} -body {
    set aliasTrace {}
    proc tstAlias {args} {
Changes to tests/io.test.
9946
9947
9948
9949
9950
9951
9952















































































9953
9954
9955
9956
9957
9958
9959
    removeFile $scriptFile
} -body {
    set fd [open |[list [info nameofexecutable] $scriptFile r+]]
    fconfigure $fd -encoding utf-8 -profile replace
    read $fd
} -result a\uFFFDb

















































































# cleanup
foreach file [list fooBar longfile script2 output test1 pipe my_script \
	test2 test3 cat stdout kyrillic.txt utf8-fcopy.txt utf8-rp.txt] {
    removeFile $file
}
cleanupTests







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957
9958
9959
9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975
9976
9977
9978
9979
9980
9981
9982
9983
9984
9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034
10035
10036
10037
10038
    removeFile $scriptFile
} -body {
    set fd [open |[list [info nameofexecutable] $scriptFile r+]]
    fconfigure $fd -encoding utf-8 -profile replace
    read $fd
} -result a\uFFFDb

proc read_blocked {args} {
    global e
    set timer [after 10000 {set ::e timeout}]
    set e ""
    set l 1; if {[llength $args] > 1} {set l [lindex $args 1]}
    try {
	while {[string length $e] < $l} {
	    append e [read {*}$args]
	    after 10; update
	}
	set e
    } finally {
	after cancel $timer
	unset -nocomplain e
    }
}
test io-bug-73bb42fb-1 {
    Non-blocking+buffer size+encoding error panic - TCL bug 73bb42fb.
    Verify error at offset 0.
} -setup {
    writeFile $path(test1) binary \xD6[string repeat _ 20]
} -body {
    set fd [open $path(test1)]
    fconfigure $fd -encoding utf-8 -profile strict -blocking 0 -buffersize 10 -translation lf -eofchar {}
    list [catch {read_blocked $fd 1} e d] $e [dict getd $d -code ""] [dict getd $d -errorcode ""] [tell $fd]
} -cleanup {
    close $fd
} -match glob -result {1 {error reading *} 1 {POSIX EILSEQ {invalid or incomplete multibyte or wide character}} 0}

test io-bug-73bb43fb-2 {
    Non-blocking+buffer size+encoding error panic - TCL bug 73bb42fb.
    Verify valid data returned before error generated.
} -setup {
    writeFile $path(test1) binary X\xD6[string repeat _ 20]
} -body {
    set fd [open $path(test1)]
    fconfigure $fd -encoding utf-8 -profile strict -blocking 0 -buffersize 10 -translation lf -eofchar {}
    set result {}
    lappend result [read_blocked $fd]
    lappend result [tell $fd]
    lappend result [catch {read_blocked $fd} e d] $e [dict getd $d -code ""] [dict getd $d -errorcode ""] [tell $fd]
} -cleanup {
    close $fd
} -match glob -result {X 1 1 {error reading *} 1 {POSIX EILSEQ {invalid or incomplete multibyte or wide character}} 1}

test io-bug-73bb43fb-3 {
    Non-blocking+buffer size+encoding error panic - TCL bug 73bb42fb.
    Modified Sergey's repro script from ticket. Check no crash / error.
} -setup {
    set f ""
} -body {
    set f [open [list | [info nameofexecutable] << {fconfigure stdout -translation binary; puts \xD6[string repeat _ 20]}]]
    fconfigure $f -encoding utf-8 -profile strict -blocking 0 -buffersize 10 -translation lf -eofchar {}
    list [catch { read_blocked $f } e d] $e [dict getd $d -code ""] [dict getd $d -errorcode ""]
} -cleanup {
    if {$f ne ""} {close $f}
} -match glob -result {1 {error reading *} 1 {POSIX EILSEQ {invalid or incomplete multibyte or wide character}}}

test io-bug-73bb43fb-4 {
    Non-blocking+buffer size+encoding error panic - TCL bug 73bb42fb.
    (PoC) Delay between bytes of single utf-8 char doesn't cause encoding error with profile strict.
} -setup {
    set f ""
} -body {
    set f [open [list | [info nameofexecutable] << {
      fconfigure stdout -translation binary
      puts -nonewline "START-"; flush stdout
      foreach {ch} [split [encoding convertto utf-8 \u30B3] ""] {; # 3 bytes E3 82 B3
        puts -nonewline $ch; flush stdout; if {$ch ne "\xB3"} {after 100}
      }
      puts -nonewline "-DONE"; flush stdout
    }]]
    fconfigure $f -encoding utf-8 -profile strict -blocking 0 -buffersize 10 -translation lf -eofchar {}
    list [catch { read_blocked $f 12 } e d] $e [dict getd $d -code ""] [dict getd $d -errorcode ""]
} -cleanup {
    if {$f ne ""} {close $f}
} -result "0 START-\u30B3-DONE 0 {}"

rename read_blocked {}

# cleanup
foreach file [list fooBar longfile script2 output test1 pipe my_script \
	test2 test3 cat stdout kyrillic.txt utf8-fcopy.txt utf8-rp.txt] {
    removeFile $file
}
cleanupTests
Changes to tests/safe.test.
1376
1377
1378
1379
1380
1381
1382

1383
1384
1385
1386
1387
1388
1389
} -body {
    catch {interp eval $i {load {} Safepfx1}} m o
    dict get $o -errorinfo
} -cleanup {
    unset -nocomplain m o
    safe::interpDelete $i
} -result {load of library for prefix Safepfx1 failed: cannot use library in a safe interpreter: no Safepfx1_SafeInit procedure

    invoked from within
"load {} Safepfx1"
    invoked from within
"interp eval $i {load {} Safepfx1}"}
test safe-10.2 {testing statics loading / -nostatics} -constraints tcl::test -body {
    set i [safe::interpCreate -nostatics]
    interp eval $i {load {} Safepfx1}







>







1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
} -body {
    catch {interp eval $i {load {} Safepfx1}} m o
    dict get $o -errorinfo
} -cleanup {
    unset -nocomplain m o
    safe::interpDelete $i
} -result {load of library for prefix Safepfx1 failed: cannot use library in a safe interpreter: no Safepfx1_SafeInit procedure
    ("interp eval" body line 59)
    invoked from within
"load {} Safepfx1"
    invoked from within
"interp eval $i {load {} Safepfx1}"}
test safe-10.2 {testing statics loading / -nostatics} -constraints tcl::test -body {
    set i [safe::interpCreate -nostatics]
    interp eval $i {load {} Safepfx1}
1407
1408
1409
1410
1411
1412
1413

1414
1415
1416
1417
1418
1419
1420
    set i [safe::interpCreate -nestedloadok]
    catch {interp eval $i {interp create x; load {} Safepfx1 x}} m o
    dict get $o -errorinfo
} -cleanup {
    unset -nocomplain m o
    safe::interpDelete $i
} -result {load of library for prefix Safepfx1 failed: cannot use library in a safe interpreter: no Safepfx1_SafeInit procedure

    invoked from within
"load {} Safepfx1 x"
    invoked from within
"interp eval $i {interp create x; load {} Safepfx1 x}"}

### 11. Safe encoding.








>







1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
    set i [safe::interpCreate -nestedloadok]
    catch {interp eval $i {interp create x; load {} Safepfx1 x}} m o
    dict get $o -errorinfo
} -cleanup {
    unset -nocomplain m o
    safe::interpDelete $i
} -result {load of library for prefix Safepfx1 failed: cannot use library in a safe interpreter: no Safepfx1_SafeInit procedure
    ("interp eval" body line 59)
    invoked from within
"load {} Safepfx1 x"
    invoked from within
"interp eval $i {interp create x; load {} Safepfx1 x}"}

### 11. Safe encoding.

Changes to win/Makefile.in.
1038
1039
1040
1041
1042
1043
1044



1045
1046
1047
1048
1049
1050
1051

cleanhelp:
	$(RM) *.hlp *.cnt *.GID

clean: cleanhelp clean-packages
	$(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out
	$(RM) $(TCLSH) $(CAT32) $(TEST_EXE_FILE) $(TEST_DLL_FILE) tcltest.cmd tcltest.sh



	$(RM) *.pch *.ilk *.pdb *.zip
	$(RM) minizip${HOST_EXEEXT} *.${HOST_OBJEXT}
	$(RMDIR) *.vfs

distclean: distclean-packages clean
	$(RM) Makefile config.status config.cache config.log tclConfig.sh \
		config.status.lineno tclsh.exe.manifest tclUuid.h







>
>
>







1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054

cleanhelp:
	$(RM) *.hlp *.cnt *.GID

clean: cleanhelp clean-packages
	$(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out
	$(RM) $(TCLSH) $(CAT32) $(TEST_EXE_FILE) $(TEST_DLL_FILE) tcltest.cmd tcltest.sh
	# remaining binaries (inclusive manifests) by version/branch switch, but retain tclsh.exe.manifest (that created on configure phase)
	find . -maxdepth 1 -type f -regex '\./tcl\(sh[^.]+\|test\|[^.]+.dll\)\.[^.]*\(\.manifest\)?' \
		-a -not -name 'tclsh.exe.manifest' -exec rm {} \;
	$(RM) *.pch *.ilk *.pdb *.zip
	$(RM) minizip${HOST_EXEEXT} *.${HOST_OBJEXT}
	$(RMDIR) *.vfs

distclean: distclean-packages clean
	$(RM) Makefile config.status config.cache config.log tclConfig.sh \
		config.status.lineno tclsh.exe.manifest tclUuid.h