diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 51f30802fc..56518805dd 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -1,5 +1,5 @@ @@ -827,6 +827,42 @@ as with a PGresult returned by libpq itself. + + Escaping strings for inclusion in SQL queries + +PQescapeString + Escapes a string for use within an SQL query. + +size_t PQescapeString (char *to, const char *from, size_t length); + +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. + + +PQescapeString performs this operation. The +from points to the first character of the string which +is to be escaped, and the length parameter counts the +number of characters in this string (a terminating NUL character is +neither necessary nor counted). to shall point to a +buffer which is able to hold at least one more character than twice +the value of length, otherwise the behavior is +undefined. A call to PQescapeString writes an escaped +version of the from string to the 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. + + +PQescapeString returns the number of characters written +to to, not including the terminating NUL character. +Behavior is undefined when the to and from +strings overlap. + + Retrieving SELECT Result Information diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c index 4b67bdcf52..bdff56fe08 100644 --- a/src/interfaces/libpq/fe-exec.c +++ b/src/interfaces/libpq/fe-exec.c @@ -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. diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h index 5faa576c08..d3b472f9cc 100644 --- a/src/interfaces/libpq/libpq-fe.h +++ b/src/interfaces/libpq/libpq-fe.h @@ -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);