Proposed patch for psql backtick safety

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-patches(at)postgreSQL(dot)org
Subject: Proposed patch for psql backtick safety
Date: 2004-12-18 19:31:15
Message-ID: 4256.1103398275@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches

Attached is a proposed patch for 8.0 to address the concerns raised
in this thread:
http://archives.postgresql.org/pgsql-bugs/2004-12/msg00189.php

The patch extends the psql lexer to have an additional argument mode
OT_VERBATIM, which is like OT_NORMAL except that backtick and variable
substitutions don't happen. (Variable substitution is not dangerous
AFAICS, but I thought that this definition might have other uses later.)

Then, it makes two changes in post-backslash-command cleanup:

1. Following a successful command, any "extra" arguments are eaten in
OT_VERBATIM instead of OT_NORMAL mode. For example, since \t takes
no arguments:

regression=# \t `echo bozo`
Showing only tuples.
\t: extra argument "`echo" ignored
\t: extra argument "bozo`" ignored
regression=#

whereas formerly the backtick command would be evaluated:

regression=# \t `echo bozo`
Showing only tuples.
\t: extra argument "bozo" ignored
regression=#

2. Following an unrecognized or unsuccessful command, the rest of the
line is eaten (in OT_WHOLE_LINE mode, which doesn't do backticks or
variables either). For example,

regression=# \N `touch bozo`
Invalid command \N. Try \? for help.
regression=# \q
$ ls bozo
bozo not found
$

whereas formerly the backtick command would be evaluated.

Comments, objections?

regards, tom lane

Index: command.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/command.c,v
retrieving revision 1.137
diff -c -r1.137 command.c
*** command.c 30 Nov 2004 20:00:34 -0000 1.137
--- command.c 18 Dec 2004 19:18:38 -0000
***************
*** 127,139 ****
status = CMD_ERROR;
}

! /* eat the rest of the options, if any */
! while ((arg = psql_scan_slash_option(scan_state,
! OT_NORMAL, NULL, false)))
{
! if (status != CMD_ERROR)
psql_error("\\%s: extra argument \"%s\" ignored\n", cmd, arg);
! free(arg);
}

/* if there is a trailing \\, swallow it */
--- 127,149 ----
status = CMD_ERROR;
}

! if (status != CMD_ERROR)
{
! /* eat any remaining arguments after a valid command */
! /* note we suppress evaluation of backticks here */
! while ((arg = psql_scan_slash_option(scan_state,
! OT_VERBATIM, NULL, false)))
! {
psql_error("\\%s: extra argument \"%s\" ignored\n", cmd, arg);
! free(arg);
! }
! }
! else
! {
! /* silently throw away rest of line after an erroneous command */
! while ((arg = psql_scan_slash_option(scan_state,
! OT_WHOLE_LINE, NULL, false)))
! free(arg);
}

/* if there is a trailing \\, swallow it */
Index: psqlscan.h
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/psqlscan.h,v
retrieving revision 1.3
diff -c -r1.3 psqlscan.h
*** psqlscan.h 29 Aug 2004 05:06:54 -0000 1.3
--- psqlscan.h 18 Dec 2004 19:18:38 -0000
***************
*** 32,38 ****
OT_SQLID, /* treat as SQL identifier */
OT_SQLIDHACK, /* SQL identifier, but don't downcase */
OT_FILEPIPE, /* it's a filename or pipe */
! OT_WHOLE_LINE /* just snarf the rest of the line */
};


--- 32,39 ----
OT_SQLID, /* treat as SQL identifier */
OT_SQLIDHACK, /* SQL identifier, but don't downcase */
OT_FILEPIPE, /* it's a filename or pipe */
! OT_WHOLE_LINE, /* just snarf the rest of the line */
! OT_VERBATIM /* literal (no backticks or variables) */
};


Index: psqlscan.l
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/psqlscan.l,v
retrieving revision 1.7
diff -c -r1.7 psqlscan.l
*** psqlscan.l 29 Aug 2004 04:13:02 -0000 1.7
--- psqlscan.l 18 Dec 2004 19:18:38 -0000
***************
*** 723,746 ****
}

"`" {
! *option_quote = '`';
! BEGIN(xslashbackquote);
}

:[A-Za-z0-9_]* {
/* Possible psql variable substitution */
! const char *value;

! value = GetVariable(pset.vars, yytext + 1);

! /*
! * The variable value is just emitted without any
! * further examination. This is consistent with the
! * pre-8.0 code behavior, if not with the way that
! * variables are handled outside backslash commands.
! */
! if (value)
! appendPQExpBufferStr(output_buf, value);

*option_quote = ':';

--- 723,760 ----
}

"`" {
! if (option_type == OT_VERBATIM)
! {
! /* in verbatim mode, backquote is not special */
! ECHO;
! BEGIN(xslashdefaultarg);
! }
! else
! {
! *option_quote = '`';
! BEGIN(xslashbackquote);
! }
}

:[A-Za-z0-9_]* {
/* Possible psql variable substitution */
! if (option_type == OT_VERBATIM)
! ECHO;
! else
! {
! const char *value;

! value = GetVariable(pset.vars, yytext + 1);

! /*
! * The variable value is just emitted without any
! * further examination. This is consistent with the
! * pre-8.0 code behavior, if not with the way that
! * variables are handled outside backslash commands.
! */
! if (value)
! appendPQExpBufferStr(output_buf, value);
! }

*option_quote = ':';

Browse pgsql-patches by date

  From Date Subject
Next Message Bruce Momjian 2004-12-19 02:16:30 Re: [PATCHES] Patch to add version numbers to
Previous Message Tom Lane 2004-12-18 04:57:54 Re: From latin9 to sql_ascii??