Skip to content

Commit

Permalink
merge 8.7
Browse files Browse the repository at this point in the history
  • Loading branch information
dgp committed Nov 13, 2023
2 parents b50cf76 + d086345 commit 7bb4d60
Show file tree
Hide file tree
Showing 18 changed files with 182 additions and 115 deletions.
39 changes: 39 additions & 0 deletions doc/exec.n
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,45 @@ processor (\fBcmd.exe /c\fR), because this causes truncation of command-line
(also the argument chain) on the first newline character.
But it works properly with an executable (using CommandLineToArgv, etc).
.PP
\fBArgument quoting\fR
.RS
The arguments of the \fBexec\fR command are mapped to the arguments of the called
program. Additional quote characters (\fB"\fR) are automatically added around
arguments if expected. Special characters are escaped by inserting backslash
characters.
.PP
The MS-Windows environment does execute programs mentioned in the arguments and
called batch files (conspec) replace environment variables, which may have side
effects (vulnerabilities) or break any already existing quoting (for example,
if the environment variable contains a special character like a \fB"\fR).
Examples are:
.CS
% exec my-echo.cmd {test&whoami}
test
mylogin
% exec my-echo.cmd "ENV X:%X%"
ENV X: CONTENT OF X
.CE
The following formatting is automatically performed on any
argument item:
.IP \(bu 3
Avoid subprogram execution:
Any special character argument containing a special character (\fB&\fR, \fB|\fR,
\fB^\fR, \fB<\fR, \fB>\fR, \fB!\fR, \fB(\fR, \fB)\fR, \fB(\fR, \fB%\fR)
is automatically enclosed in quotes (\fB"\fR). Any data quote is escaped by
insertion of backslash characters.
.IP \(bu 3
Avoid environment variable replacement:
Any appearence of environment variable reference (\fB%\fR) is individually quoted
by \fB"\fR.
.PP
TCL 8.6.10 refined this quoting by adding quoting for data quotes and individual
quoting of "\fB%\fR".
This may break present scripts which rely on the replacement functionality of
environment variables.
A solution with command parameters is envisaged for a future release of TCL.
.RE
.PP
The Tk console text widget does not provide real standard IO capabilities.
Under Tk, when redirecting from standard input, all applications will see an
immediate end-of-file; information redirected to standard output or standard
Expand Down
5 changes: 2 additions & 3 deletions generic/tcl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2180,10 +2180,9 @@ typedef struct Tcl_EncodingType {
* changes, ensure ENCODING_PROFILE_* macros in tclInt.h are modified if
* necessary.
*/
#define TCL_ENCODING_PROFILE_STRICT TCL_ENCODING_STOPONERROR
#define TCL_ENCODING_PROFILE_TCL8 0x01000000
#define TCL_ENCODING_PROFILE_STRICT 0x02000000
#define TCL_ENCODING_PROFILE_REPLACE 0x03000000
#define TCL_ENCODING_PROFILE_DEFAULT TCL_ENCODING_PROFILE_TCL8
#define TCL_ENCODING_PROFILE_REPLACE 0x02000000

/*
* The following definitions are the error codes returned by the conversion
Expand Down
21 changes: 8 additions & 13 deletions generic/tclBasic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1082,14 +1082,9 @@ Tcl_CreateInterp(void)
iPtr->deferredCallbacks = NULL;

/*
* Create the core commands. Do it here, rather than calling
* Tcl_CreateCommand, because it's faster (there's no need to check for a
* preexisting command by the same name). If a command has a Tcl_CmdProc
* but no Tcl_ObjCmdProc, set the Tcl_ObjCmdProc to
* TclInvokeStringCommand. This is an object-based wrapper function that
* extracts strings, calls the string function, and creates an object for
* the result. Similarly, if a command has a Tcl_ObjCmdProc but no
* Tcl_CmdProc, set the Tcl_CmdProc to TclInvokeObjectCommand.
* Create the core commands. Do it here, rather than calling Tcl_CreateObjCommand,
* because it's faster (there's no need to check for a preexisting command
* by the same name). Set the Tcl_CmdProc to TclInvokeObjectCommand.
*/

for (cmdInfoPtr = builtInCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
Expand Down Expand Up @@ -3140,7 +3135,7 @@ TclRenameCommand(
/*
* Make sure that the destination command does not already exist. The
* rename operation is like creating a command, so we should automatically
* create the containing namespaces just like Tcl_CreateCommand would.
* create the containing namespaces just like Tcl_CreateObjCommand would.
*/

TclGetNamespaceForQualName(interp, newName, NULL,
Expand Down Expand Up @@ -3445,7 +3440,7 @@ Tcl_GetCommandInfoFromToken(
*
* Tcl_GetCommandName --
*
* Given a token returned by Tcl_CreateCommand, this function returns the
* Given a token returned by Tcl_CreateObjCommand, this function returns the
* current name of the command (which may have changed due to renaming).
*
* Results:
Expand All @@ -3461,7 +3456,7 @@ const char *
Tcl_GetCommandName(
TCL_UNUSED(Tcl_Interp *),
Tcl_Command command) /* Token for command returned by a previous
* call to Tcl_CreateCommand. The command must
* call to Tcl_CreateObjCommand. The command must
* not have been deleted. */
{
Command *cmdPtr = (Command *) command;
Expand All @@ -3484,7 +3479,7 @@ Tcl_GetCommandName(
*
* Tcl_GetCommandFullName --
*
* Given a token returned by, e.g., Tcl_CreateCommand or Tcl_FindCommand,
* Given a token returned by, e.g., Tcl_CreateObjCommand or Tcl_FindCommand,
* this function appends to an object the command's full name, qualified
* by a sequence of parent namespace names. The command's fully-qualified
* name may have changed due to renaming.
Expand All @@ -3503,7 +3498,7 @@ void
Tcl_GetCommandFullName(
Tcl_Interp *interp, /* Interpreter containing the command. */
Tcl_Command command, /* Token for command returned by a previous
* call to Tcl_CreateCommand. The command must
* call to Tcl_CreateObjCommand. The command must
* not have been deleted. */
Tcl_Obj *objPtr) /* Points to the object onto which the
* command's full name is appended. */
Expand Down
7 changes: 4 additions & 3 deletions generic/tclCmdAH.c
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ EncodingConvertfromObjCmd(
/*
* Convert the string into a byte array in 'ds'.
*/
#if !defined(TCL_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9)
#if !defined(TCL_NO_DEPRECATED)
if (ENCODING_PROFILE_GET(flags) == TCL_ENCODING_PROFILE_TCL8) {
/* Permits high bits to be non-0 in byte array (Tcl 8 style) */
bytesPtr = (char *) Tcl_GetByteArrayFromObj(data, &length);
Expand Down Expand Up @@ -2212,7 +2212,7 @@ PathSplitCmd(
Tcl_WrongNumArgs(interp, 1, objv, "name");
return TCL_ERROR;
}
res = Tcl_FSSplitPath(objv[1], NULL);
res = Tcl_FSSplitPath(objv[1], (Tcl_Size *)NULL);
if (res == NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"could not read \"%s\": no such file or directory",
Expand Down Expand Up @@ -3109,7 +3109,8 @@ ForeachAssignments(
Tcl_Interp *interp,
struct ForeachState *statePtr)
{
int i, v, k;
int i;
Tcl_Size v, k;
Tcl_Obj *valuePtr, *varValuePtr;

for (i=0 ; i<statePtr->numLists ; i++) {
Expand Down
6 changes: 0 additions & 6 deletions generic/tclDate.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
#define yylex TclDatelex
#define yyerror TclDateerror
#define yydebug TclDatedebug
#define yynerrs TclDatenerrs


/* Copy the first part of user declarations. */
Expand Down Expand Up @@ -1294,9 +1293,6 @@ static YYLTYPE yyloc_default
;
YYLTYPE yylloc = yyloc_default;

/* Number of syntax errors so far. */
int yynerrs;

int yystate;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
Expand Down Expand Up @@ -1360,7 +1356,6 @@ YYLTYPE yylloc = yyloc_default;

yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
yylsp[0] = yylloc;
goto yysetstate;
Expand Down Expand Up @@ -2098,7 +2093,6 @@ YYLTYPE yylloc = yyloc_default;
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
++yynerrs;
#if ! YYERROR_VERBOSE
yyerror (&yylloc, info, YY_("syntax error"));
#else
Expand Down
14 changes: 10 additions & 4 deletions generic/tclDecls.h
Original file line number Diff line number Diff line change
Expand Up @@ -4331,23 +4331,29 @@ extern const TclStubs *tclStubsPtr;
#undef Tcl_GetIndexFromObjStruct
#undef Tcl_GetBooleanFromObj
#undef Tcl_GetBoolean
#ifdef __GNUC__
/* If this gives: "error: size of array ‘_boolVar’ is negative", it means that sizeof(*boolPtr)>sizeof(int), which is not allowed */
# define TCLBOOLWARNING(boolPtr) ({__attribute__((unused)) char _bool_Var[sizeof(*(boolPtr)) > sizeof(int) ? -1 : 1];}),
#else
# define TCLBOOLWARNING(boolPtr)
#endif
#if defined(USE_TCL_STUBS)
#define Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, indexPtr) \
(tclStubsPtr->tcl_GetIndexFromObjStruct((interp), (objPtr), (tablePtr), (offset), (msg), (flags)|(int)(sizeof(*(indexPtr))<<1), (indexPtr)))
#define Tcl_GetBooleanFromObj(interp, objPtr, boolPtr) \
(sizeof(*(boolPtr)) == sizeof(int) ? tclStubsPtr->tcl_GetBooleanFromObj(interp, objPtr, (int *)(boolPtr)) : \
(sizeof(*(boolPtr)) >= sizeof(int) ? (TCLBOOLWARNING(boolPtr)tclStubsPtr->tcl_GetBooleanFromObj(interp, objPtr, (int *)(boolPtr))) : \
Tcl_GetBoolFromObj(interp, objPtr, (TCL_NULL_OK-2)&(int)sizeof((*(boolPtr))), (char *)(boolPtr)))
#define Tcl_GetBoolean(interp, src, boolPtr) \
(sizeof(*(boolPtr)) == sizeof(int) ? tclStubsPtr->tcl_GetBoolean(interp, src, (int *)(boolPtr)) : \
(sizeof(*(boolPtr)) >= sizeof(int) ? (TCLBOOLWARNING(boolPtr)tclStubsPtr->tcl_GetBoolean(interp, src, (int *)(boolPtr))) : \
Tcl_GetBool(interp, src, (TCL_NULL_OK-2)&(int)sizeof((*(boolPtr))), (char *)(boolPtr)))
#else
#define Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, indexPtr) \
((Tcl_GetIndexFromObjStruct)((interp), (objPtr), (tablePtr), (offset), (msg), (flags)|(int)(sizeof(*(indexPtr))<<1), (indexPtr)))
#define Tcl_GetBooleanFromObj(interp, objPtr, boolPtr) \
(sizeof(*(boolPtr)) == sizeof(int) ? Tcl_GetBooleanFromObj(interp, objPtr, (int *)(boolPtr)) : \
(sizeof(*(boolPtr)) >= sizeof(int) ? (TCLBOOLWARNING(boolPtr)Tcl_GetBooleanFromObj(interp, objPtr, (int *)(boolPtr))) : \
Tcl_GetBoolFromObj(interp, objPtr, (TCL_NULL_OK-2)&(int)sizeof((*(boolPtr))), (char *)(boolPtr)))
#define Tcl_GetBoolean(interp, src, boolPtr) \
(sizeof(*(boolPtr)) == sizeof(int) ? Tcl_GetBoolean(interp, src, (int *)(boolPtr)) : \
(sizeof(*(boolPtr)) >= sizeof(int) ? (TCLBOOLWARNING(boolPtr)Tcl_GetBoolean(interp, src, (int *)(boolPtr))) : \
Tcl_GetBool(interp, src, (TCL_NULL_OK-2)&(int)sizeof((*(boolPtr))), (char *)(boolPtr)))
#endif

Expand Down
Loading

0 comments on commit 7bb4d60

Please sign in to comment.