]> granicus.if.org Git - postgresql/commitdiff
I've attached the fixed version of the patch below. After the
authorBruce Momjian <bruce@momjian.us>
Fri, 7 Sep 2001 22:02:32 +0000 (22:02 +0000)
committerBruce Momjian <bruce@momjian.us>
Fri, 7 Sep 2001 22:02:32 +0000 (22:02 +0000)
discussion on pgsql-hackers (especially the frightening memory dump in
<12273.999562219@sss.pgh.pa.us>), we decided that it is best not to
use identifiers from an untrusted source at all.  Therefore, all
claims of the suitability of PQescapeString() for identifiers have
been removed.

Florian Weimer

doc/src/sgml/libpq.sgml
src/interfaces/libpq/fe-exec.c
src/interfaces/libpq/libpq-fe.h

index 51f30802fccbb0da898677bbf37bee1ccc33e3d2..56518805dd5ab0db35eb47f1ad9eb812f83cc1d5 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.68 2001/09/04 00:18:18 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.69 2001/09/07 22:02:32 momjian Exp $
 -->
 
  <chapter id="libpq">
@@ -827,6 +827,42 @@ as with a PGresult returned by libpq itself.
 </itemizedlist>
 </sect2>
 
+<sect2 id="libpq-exec-escape-string">
+  <title>Escaping strings for inclusion in SQL queries</title>
+<para>
+<function>PQescapeString</function>
+          Escapes a string for use within an SQL query.
+<synopsis>
+size_t PQescapeString (char *to, const char *from, size_t length);
+</synopsis>
+If you want to include strings which have been received
+from a source which is not trustworthy (for example, because they were
+transmitted across a network), you cannot directly include them in SQL
+queries for security reasons.  Instead, you have to quote special
+characters which are otherwise interpreted by the SQL parser.
+</para>
+<para>
+<function>PQescapeString</> performs this operation.  The
+<parameter>from</> points to the first character of the string which
+is to be escaped, and the <parameter>length</> parameter counts the
+number of characters in this string (a terminating NUL character is
+neither necessary nor counted).  <parameter>to</> shall point to a
+buffer which is able to hold at least one more character than twice
+the value of <parameter>length</>, otherwise the behavior is
+undefined.  A call to <function>PQescapeString</> writes an escaped
+version of the <parameter>from</> string to the <parameter>to</>
+buffer, replacing special characters so that they cannot cause any
+harm, and adding a terminating NUL character.  The single quotes which
+must surround PostgreSQL string literals are not part of the result
+string.
+</para>
+<para>
+<function>PQescapeString</> returns the number of characters written
+to <parameter>to</>, not including the terminating NUL character.
+Behavior is undefined when the <parameter>to</> and <parameter>from</>
+strings overlap.
+</para>
+
 <sect2 id="libpq-exec-select-info">
   <title>Retrieving SELECT Result Information</title>
 
index 4b67bdcf52a3567673e43dfd5b1b58d85f780567..bdff56fe0804b50c1c521879eecaafd3a8ca34bd 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.109 2001/09/06 02:54:56 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.110 2001/09/07 22:02:32 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -56,6 +56,62 @@ static int   getAnotherTuple(PGconn *conn, int binary);
 static int     getNotify(PGconn *conn);
 static int     getNotice(PGconn *conn);
 
+/* ---------------
+ * Escaping arbitrary strings to get valid SQL strings/identifiers.
+ *
+ * Replaces "\\" with "\\\\", "\0" with "\\0", and "'" with "''".
+ * length is the length of the buffer pointed to by
+ * from.  The buffer at to must be at least 2*length + 1 characters
+ * long.  A terminating NUL character is written.
+ * ---------------
+ */
+
+size_t
+PQescapeString (char *to, const char *from, size_t length)
+{
+       const char *source = from;
+       char *target = to;
+       unsigned int remaining = length;
+
+       while (remaining > 0) {
+               switch (*source) {
+               case '\0':
+                       *target = '\\';
+                       target++;
+                       *target = '0';
+                       /* target and remaining are updated below. */
+                       break;
+                       
+               case '\\':
+                       *target = '\\';
+                       target++;
+                       *target = '\\';
+                       /* target and remaining are updated below. */
+                       break;
+
+               case '\'':
+                       *target = '\'';
+                       target++;
+                       *target = '\'';
+                       /* target and remaining are updated below. */
+                       break;
+
+               default:
+                       *target = *source;
+                       /* target and remaining are updated below. */
+               }
+               source++;
+               target++;
+               remaining--;
+       }
+
+       /* Write the terminating NUL character. */
+       *target = '\0';
+       
+       return target - to;
+}
+
+
 
 /* ----------------
  * Space management for PGresult.
index 5faa576c0875b8ab5e3248ad35b903189c4fcaa1..d3b472f9ccbc4f0be55a5bcd7b55ac70d1cb1d42 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: libpq-fe.h,v 1.73 2001/09/06 02:54:56 momjian Exp $
+ * $Id: libpq-fe.h,v 1.74 2001/09/07 22:02:32 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -251,6 +251,9 @@ extern              "C"
 
 /* === in fe-exec.c === */
 
+       /* Quoting strings before inclusion in queries. */
+       extern size_t PQescapeString (char *to, const char *from, size_t length);
+
        /* Simple synchronous query */
        extern PGresult *PQexec(PGconn *conn, const char *query);
        extern PGnotify *PQnotifies(PGconn *conn);