Prevent evaluation of backticks while discarding unwanted arguments
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 19 Dec 2004 19:39:47 +0000 (19:39 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 19 Dec 2004 19:39:47 +0000 (19:39 +0000)
after an unknown or failed psql backslash command, and also while
discarding "extra" arguments of a putatively valid backslash command.
In the case of an unknown/failed command, make sure we discard the
whole rest of the line, rather than trying to resume at the next
backslash.  Per discussion with Thomer Gil.

src/bin/psql/command.c
src/bin/psql/psqlscan.h
src/bin/psql/psqlscan.l

index c6ad507ca83567dc42b15e03109eb39d7026d2c1..6388f20dd7058648fc59a8032c64ff0e264fa944 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2004, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.137 2004/11/30 20:00:34 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.138 2004/12/19 19:39:47 tgl Exp $
  */
 #include "postgres_fe.h"
 #include "command.h"
@@ -127,13 +127,23 @@ HandleSlashCmds(PsqlScanState scan_state,
        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)
    {
-       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);
+           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 a4cb945a239e538cdaa7c7f440e924d8c03340e2..7b506a5a11ceac2e33834e96a81e2822332d65c4 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2004, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/psqlscan.h,v 1.3 2004/08/29 05:06:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/psqlscan.h,v 1.4 2004/12/19 19:39:47 tgl Exp $
  */
 #ifndef PSQLSCAN_H
 #define PSQLSCAN_H
@@ -32,7 +32,8 @@ enum slash_option_type
    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_WHOLE_LINE,              /* just snarf the rest of the line */
+   OT_VERBATIM                 /* literal (no backticks or variables) */
 };
 
 
index 6311ffab1783ab81e03254a0a65dbaae89e4b73d..de738958d146b1afb8b490e6466cbb0a1c645810 100644 (file)
@@ -31,7 +31,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/bin/psql/psqlscan.l,v 1.7 2004/08/29 04:13:02 momjian Exp $
+ *   $PostgreSQL: pgsql/src/bin/psql/psqlscan.l,v 1.8 2004/12/19 19:39:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -723,24 +723,38 @@ other         .
                }
 
 "`"                {
-                   *option_quote = '`';
-                   BEGIN(xslashbackquote);
+                   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 */
-                   const char *value;
+                   if (option_type == OT_VERBATIM)
+                       ECHO;
+                   else
+                   {
+                       const char *value;
 
-                   value = GetVariable(pset.vars, yytext + 1);
+                       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);
+                       /*
+                        * 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 = ':';