1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-15 19:15:29 +03:00

Apply Tcl_Init() to the "hold" interpreter created by pltcl.

You might think this is unnecessary since that interpreter is never used
to run code --- but it turns out that's wrong.  As of Tcl 8.5, the "clock"
command (alone among builtin Tcl commands) is partially implemented by
loaded-on-demand Tcl code, which means that it fails if there's not
unknown-command support, and also that it's impossible to run it directly
in a safe interpreter.  The way they get around the latter is that
Tcl_CreateSlave() automatically sets up an alias command that forwards any
execution of "clock" in a safe slave interpreter to its parent interpreter.
Thus, when attempting to execute "clock" in trusted pltcl, the command
actually executes in the "hold" interpreter, where it will fail if
unknown-command support hasn't been introduced by sourcing the standard
init.tcl script, which is done by Tcl_Init().  (This is a pretty dubious
design decision on the Tcl boys' part, if you ask me ... but they didn't.)

Back-patch all the way.  It's not clear that anyone would try to use ancient
versions of pltcl with a recent Tcl, but it's not clear they wouldn't, either.
Also add a regression test using "clock", in branches that have regression
test support for pltcl.

Per recent trouble report from Kyle Bateman.
This commit is contained in:
Tom Lane 2010-01-25 01:58:57 +00:00
parent 10dedbf709
commit cd79a50880

View File

@ -31,7 +31,7 @@
* ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.79.2.1 2004/01/24 23:06:41 tgl Exp $
* $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.79.2.2 2010/01/25 01:58:57 tgl Exp $
*
**********************************************************************/
@ -219,9 +219,12 @@ pltcl_init(void)
************************************************************/
if ((pltcl_hold_interp = Tcl_CreateInterp()) == NULL)
elog(ERROR, "could not create \"hold\" interpreter");
if (Tcl_Init(pltcl_hold_interp) == TCL_ERROR)
elog(ERROR, "could not initialize \"hold\" interpreter");
/************************************************************
* Create the two interpreters
* Create the two slave interpreters. Note: Tcl automatically does
* Tcl_Init on the normal slave, and it's not wanted for the safe slave.
************************************************************/
if ((pltcl_norm_interp =
Tcl_CreateSlave(pltcl_hold_interp, "norm", 0)) == NULL)