Skip to content

Commit 1834987

Browse files
committed
I've attached the fixed version of the patch below. After the
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
1 parent bd9b328 commit 1834987

File tree

3 files changed

+98
-3
lines changed

3 files changed

+98
-3
lines changed

doc/src/sgml/libpq.sgml

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.68 2001/09/04 00:18:18 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.69 2001/09/07 22:02:32 momjian Exp $
33
-->
44

55
<chapter id="libpq">
@@ -827,6 +827,42 @@ as with a PGresult returned by libpq itself.
827827
</itemizedlist>
828828
</sect2>
829829

830+
<sect2 id="libpq-exec-escape-string">
831+
<title>Escaping strings for inclusion in SQL queries</title>
832+
<para>
833+
<function>PQescapeString</function>
834+
Escapes a string for use within an SQL query.
835+
<synopsis>
836+
size_t PQescapeString (char *to, const char *from, size_t length);
837+
</synopsis>
838+
If you want to include strings which have been received
839+
from a source which is not trustworthy (for example, because they were
840+
transmitted across a network), you cannot directly include them in SQL
841+
queries for security reasons. Instead, you have to quote special
842+
characters which are otherwise interpreted by the SQL parser.
843+
</para>
844+
<para>
845+
<function>PQescapeString</> performs this operation. The
846+
<parameter>from</> points to the first character of the string which
847+
is to be escaped, and the <parameter>length</> parameter counts the
848+
number of characters in this string (a terminating NUL character is
849+
neither necessary nor counted). <parameter>to</> shall point to a
850+
buffer which is able to hold at least one more character than twice
851+
the value of <parameter>length</>, otherwise the behavior is
852+
undefined. A call to <function>PQescapeString</> writes an escaped
853+
version of the <parameter>from</> string to the <parameter>to</>
854+
buffer, replacing special characters so that they cannot cause any
855+
harm, and adding a terminating NUL character. The single quotes which
856+
must surround PostgreSQL string literals are not part of the result
857+
string.
858+
</para>
859+
<para>
860+
<function>PQescapeString</> returns the number of characters written
861+
to <parameter>to</>, not including the terminating NUL character.
862+
Behavior is undefined when the <parameter>to</> and <parameter>from</>
863+
strings overlap.
864+
</para>
865+
830866
<sect2 id="libpq-exec-select-info">
831867
<title>Retrieving SELECT Result Information</title>
832868

src/interfaces/libpq/fe-exec.c

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.109 2001/09/06 02:54:56 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.110 2001/09/07 22:02:32 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -56,6 +56,62 @@ static int getAnotherTuple(PGconn *conn, int binary);
5656
static int getNotify(PGconn *conn);
5757
static int getNotice(PGconn *conn);
5858

59+
/* ---------------
60+
* Escaping arbitrary strings to get valid SQL strings/identifiers.
61+
*
62+
* Replaces "\\" with "\\\\", "\0" with "\\0", and "'" with "''".
63+
* length is the length of the buffer pointed to by
64+
* from. The buffer at to must be at least 2*length + 1 characters
65+
* long. A terminating NUL character is written.
66+
* ---------------
67+
*/
68+
69+
size_t
70+
PQescapeString (char *to, const char *from, size_t length)
71+
{
72+
const char *source = from;
73+
char *target = to;
74+
unsigned int remaining = length;
75+
76+
while (remaining > 0) {
77+
switch (*source) {
78+
case '\0':
79+
*target = '\\';
80+
target++;
81+
*target = '0';
82+
/* target and remaining are updated below. */
83+
break;
84+
85+
case '\\':
86+
*target = '\\';
87+
target++;
88+
*target = '\\';
89+
/* target and remaining are updated below. */
90+
break;
91+
92+
case '\'':
93+
*target = '\'';
94+
target++;
95+
*target = '\'';
96+
/* target and remaining are updated below. */
97+
break;
98+
99+
default:
100+
*target = *source;
101+
/* target and remaining are updated below. */
102+
}
103+
source++;
104+
target++;
105+
remaining--;
106+
}
107+
108+
/* Write the terminating NUL character. */
109+
*target = '\0';
110+
111+
return target - to;
112+
}
113+
114+
59115

60116
/* ----------------
61117
* Space management for PGresult.

src/interfaces/libpq/libpq-fe.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: libpq-fe.h,v 1.73 2001/09/06 02:54:56 momjian Exp $
10+
* $Id: libpq-fe.h,v 1.74 2001/09/07 22:02:32 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -251,6 +251,9 @@ extern "C"
251251

252252
/* === in fe-exec.c === */
253253

254+
/* Quoting strings before inclusion in queries. */
255+
extern size_t PQescapeString (char *to, const char *from, size_t length);
256+
254257
/* Simple synchronous query */
255258
extern PGresult *PQexec(PGconn *conn, const char *query);
256259
extern PGnotify *PQnotifies(PGconn *conn);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy