Skip to content

Commit 3b1790f

Browse files
committed
Add PQescapeIdentifier() to libpq
Christopher Kings-Lynne
1 parent 59a853e commit 3b1790f

File tree

4 files changed

+106
-4
lines changed

4 files changed

+106
-4
lines changed

doc/src/sgml/libpq.sgml

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.211 2006/05/23 22:13:19 momjian Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.212 2006/06/27 00:03:41 momjian Exp $ -->
22

33
<chapter id="libpq">
44
<title><application>libpq</application> - C Library</title>
@@ -2279,6 +2279,68 @@ in favor of <function>PQescapeStringConn</>.
22792279
</para>
22802280
</sect2>
22812281

2282+
<sect2 id="libpq-exec-escape-identifier">
2283+
<title>Escaping Identifier for Inclusion in SQL Commands</title>
2284+
2285+
<indexterm zone="libpq-exec-escape-identifier"><primary>PQescapeIdentifier</></>
2286+
<indexterm zone="libpq-exec-escape-identifier"><primary>escaping strings</></>
2287+
2288+
<para>
2289+
<function>PQescapeIdentifier</function> escapes a string for use
2290+
as an identifier name within an SQL command. For example; table names,
2291+
column names, view names and user names are all identifiers.
2292+
Double quotes (") must be escaped to prevent them from being interpreted
2293+
specially by the SQL parser. <function>PQescapeIdentifier</> performs this
2294+
operation.
2295+
</para>
2296+
2297+
<tip>
2298+
<para>
2299+
It is especially important to do proper escaping when handling strings that
2300+
were received from an untrustworthy source. Otherwise there is a security
2301+
risk: you are vulnerable to <quote>SQL injection</> attacks wherein unwanted
2302+
SQL commands are fed to your database.
2303+
</para>
2304+
</tip>
2305+
2306+
<para>
2307+
Note that it is still necessary to do escaping of identifiers when
2308+
using functions that support parameterized queries such as <function>PQexecParams</> or
2309+
its sibling routines. Only literal values are automatically escaped
2310+
using these functions, not identifiers.
2311+
2312+
<synopsis>
2313+
size_t PQescapeIdentifier (char *to, const char *from, size_t length);
2314+
</synopsis>
2315+
</para>
2316+
2317+
<para>
2318+
The parameter <parameter>from</> points to the first character of the
2319+
string that is to be escaped, and the <parameter>length</> parameter
2320+
gives the number of characters in this string. A terminating zero byte
2321+
is not required, and should not be counted in <parameter>length</>. (If
2322+
a terminating zero byte is found before <parameter>length</> bytes are
2323+
processed, <function>PQescapeIdentifier</> stops at the zero; the
2324+
behavior is thus rather like <function>strncpy</>.) <parameter>to</>
2325+
shall point to a buffer that is able to hold at least one more character
2326+
than twice the value of <parameter>length</>, otherwise the behavior is
2327+
undefined. A call to <function>PQescapeIdentifier</> writes an escaped
2328+
version of the <parameter>from</> string to the <parameter>to</> buffer,
2329+
replacing special characters so that they cannot cause any harm, and
2330+
adding a terminating zero byte. The double quotes that may surround
2331+
<productname>PostgreSQL</> identifiers are not included in the result
2332+
string; they should be provided in the SQL command that the result is
2333+
inserted into.
2334+
</para>
2335+
<para>
2336+
<function>PQescapeIdentifier</> returns the number of characters written
2337+
to <parameter>to</>, not including the terminating zero byte.
2338+
</para>
2339+
<para>
2340+
Behavior is undefined if the <parameter>to</> and <parameter>from</>
2341+
strings overlap.
2342+
</para>
2343+
</sect2>
22822344

22832345
<sect2 id="libpq-exec-escape-bytea">
22842346
<title>Escaping Binary Strings for Inclusion in SQL Commands</title>

src/interfaces/libpq/exports.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $PostgreSQL: pgsql/src/interfaces/libpq/exports.txt,v 1.11 2006/05/28 22:42:05 tgl Exp $
1+
# $PostgreSQL: pgsql/src/interfaces/libpq/exports.txt,v 1.12 2006/06/27 00:03:41 momjian Exp $
22
# Functions to be exported by libpq DLLs
33
PQconnectdb 1
44
PQsetdbLogin 2
@@ -130,3 +130,5 @@ PQescapeByteaConn 127
130130
PQencryptPassword 128
131131
PQisthreadsafe 129
132132
enlargePQExpBuffer 130
133+
PQescapeIdentifier 131
134+

src/interfaces/libpq/fe-exec.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.186 2006/05/28 21:13:54 tgl Exp $
11+
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.187 2006/06/27 00:03:41 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2515,6 +2515,42 @@ PQescapeString(char *to, const char *from, size_t length)
25152515
static_std_strings);
25162516
}
25172517

2518+
/*
2519+
* Escaping arbitrary strings to get valid SQL identifier strings.
2520+
*
2521+
* Replaces " with "".
2522+
*
2523+
* length is the length of the source string. (Note: if a terminating NUL
2524+
* is encountered sooner, PQescapeIdentifier stops short of "length"; the behavior
2525+
* is thus rather like strncpy.)
2526+
*
2527+
* For safety the buffer at "to" must be at least 2*length + 1 bytes long.
2528+
* A terminating NUL character is added to the output string, whether the
2529+
* input is NUL-terminated or not.
2530+
*
2531+
* Returns the actual length of the output (not counting the terminating NUL).
2532+
*/
2533+
size_t
2534+
PQescapeIdentifier(char *to, const char *from, size_t length)
2535+
{
2536+
const char *source = from;
2537+
char *target = to;
2538+
size_t remaining = length;
2539+
2540+
while (remaining > 0 && *source != '\0')
2541+
{
2542+
if (*source == '"')
2543+
*target++ = *source;
2544+
*target++ = *source++;
2545+
remaining--;
2546+
}
2547+
2548+
/* Write the terminating NUL character. */
2549+
*target = '\0';
2550+
2551+
return target - to;
2552+
}
2553+
25182554
/*
25192555
* PQescapeBytea - converts from binary string to the
25202556
* minimal encoding necessary to include the string in an SQL

src/interfaces/libpq/libpq-fe.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.129 2006/05/23 22:13:19 momjian Exp $
10+
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.130 2006/06/27 00:03:42 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -436,6 +436,8 @@ extern unsigned char *PQescapeByteaConn(PGconn *conn,
436436
size_t *to_length);
437437
extern unsigned char *PQunescapeBytea(const unsigned char *strtext,
438438
size_t *retbuflen);
439+
extern size_t PQescapeIdentifier(char *to, const char *from, size_t length);
440+
439441
/* These forms are deprecated! */
440442
extern size_t PQescapeString(char *to, const char *from, size_t length);
441443
extern unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length,

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