Commit a401226b authored by Peter Eisentraut's avatar Peter Eisentraut

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

with a few strategically placed pg_verifymbstr calls.
parent ab5694e8
<!-- $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>
......
/**********************************************************************
* 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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment