Prevent the injection of invalidly encoded strings by PL/Python into PostgreSQL

with a few strategically placed pg_verifymbstr calls.
This commit is contained in:
Peter Eisentraut 2010-03-18 19:43:03 +00:00
parent ab5694e80d
commit a401226bd8
2 changed files with 17 additions and 2 deletions

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/plpython.sgml,v 1.45 2010/03/13 20:55:05 petere Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/plpython.sgml,v 1.46 2010/03/18 19:43:03 petere Exp $ -->
<chapter id="plpython">
<title>PL/Python - Python Procedural Language</title>
@ -340,6 +340,17 @@ $$ LANGUAGE plpythonu;
builtin <literal>str</literal>, and the result is passed to the
input function of the PostgreSQL data type.
</para>
<para>
Strings in Python 2 are required to be in the PostgreSQL server
encoding when they are passed to PostgreSQL. Strings that are
not valid in the current server encoding will raise an error,
but not all encoding mismatches can be detected, so garbage
data can still result when this is not done correctly. Unicode
strings are converted to the correct encoding automatically, so
it can be safer and more convenient to use those. In Python 3,
all strings are Unicode strings.
</para>
</listitem>
<listitem>

View File

@ -1,7 +1,7 @@
/**********************************************************************
* plpython.c - python as a procedural language for PostgreSQL
*
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.140 2010/03/18 13:23:56 petere Exp $
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.141 2010/03/18 19:43:03 petere Exp $
*
*********************************************************************
*/
@ -2174,6 +2174,7 @@ PLyObject_ToDatum(PLyTypeInfo *info,
errmsg("could not convert Python object into cstring: Python string representation appears to contain null bytes")));
else if (slen > plen)
elog(ERROR, "could not convert Python object into cstring: Python string longer than reported length");
pg_verifymbstr(plrv_sc, slen, false);
rv = InputFunctionCall(&arg->typfunc, plrv_sc, arg->typioparam, -1);
}
PG_CATCH();
@ -2871,6 +2872,7 @@ PLy_spi_prepare(PyObject *self, PyObject *args)
}
}
pg_verifymbstr(query, strlen(query), false);
plan->plan = SPI_prepare(query, plan->nargs, plan->types);
if (plan->plan == NULL)
elog(ERROR, "SPI_prepare failed: %s",
@ -3078,6 +3080,7 @@ PLy_spi_execute_query(char *query, long limit)
oldcontext = CurrentMemoryContext;
PG_TRY();
{
pg_verifymbstr(query, strlen(query), false);
rv = SPI_execute(query, PLy_curr_procedure->fn_readonly, limit);
}
PG_CATCH();
@ -3353,6 +3356,7 @@ PLy_output(volatile int level, PyObject *self, PyObject *args)
oldcontext = CurrentMemoryContext;
PG_TRY();
{
pg_verifymbstr(sv, strlen(sv), false);
elog(level, "%s", sv);
}
PG_CATCH();