Commit c846f7ca authored by Tom Lane's avatar Tom Lane

Fix several datatype input functions that were allowing unused bytes in their

results to contain uninitialized, unpredictable values.  While this was okay
as far as the datatypes themselves were concerned, it's a problem for the
parser because occurrences of the "same" literal might not be recognized as
equal by datumIsEqual (and hence not by equal()).  It seems sufficient to fix
this in the input functions since the only critical use of equal() is in the
parser's comparisons of ORDER BY and DISTINCT expressions.
Per a trouble report from Marc Cousin.

Patch all the way back.  Interestingly, array_in did not have the bug before
8.2, which may explain why the issue went unnoticed for so long.
parent 00b1827a
/*
* in/out function for ltree and lquery
* Teodor Sigaev <teodor@stack.net>
* $PostgreSQL: pgsql/contrib/ltree/ltree_io.c,v 1.14 2007/02/28 22:44:38 tgl Exp $
* $PostgreSQL: pgsql/contrib/ltree/ltree_io.c,v 1.15 2008/04/11 22:52:05 tgl Exp $
*/
#include "ltree.h"
......@@ -118,7 +118,7 @@ ltree_in(PG_FUNCTION_ARGS)
errmsg("syntax error"),
errdetail("Unexpected end of line.")));
result = (ltree *) palloc(LTREE_HDRSIZE + totallen);
result = (ltree *) palloc0(LTREE_HDRSIZE + totallen);
SET_VARSIZE(result, LTREE_HDRSIZE + totallen);
result->numlevel = lptr - list;
curlevel = LTREE_FIRST(result);
......@@ -208,8 +208,7 @@ lquery_in(PG_FUNCTION_ARGS)
}
num++;
curqlevel = tmpql = (lquery_level *) palloc(ITEMSIZE * num);
memset((void *) tmpql, 0, ITEMSIZE * num);
curqlevel = tmpql = (lquery_level *) palloc0(ITEMSIZE * num);
ptr = buf;
while (*ptr)
{
......@@ -217,16 +216,14 @@ lquery_in(PG_FUNCTION_ARGS)
{
if (ISALNUM(*ptr))
{
GETVAR(curqlevel) = lptr = (nodeitem *) palloc(sizeof(nodeitem) * (numOR + 1));
memset((void *) GETVAR(curqlevel), 0, sizeof(nodeitem) * (numOR + 1));
GETVAR(curqlevel) = lptr = (nodeitem *) palloc0(sizeof(nodeitem) * (numOR + 1));
lptr->start = ptr;
state = LQPRS_WAITDELIM;
curqlevel->numvar = 1;
}
else if (*ptr == '!')
{
GETVAR(curqlevel) = lptr = (nodeitem *) palloc(sizeof(nodeitem) * (numOR + 1));
memset((void *) GETVAR(curqlevel), 0, sizeof(nodeitem) * (numOR + 1));
GETVAR(curqlevel) = lptr = (nodeitem *) palloc0(sizeof(nodeitem) * (numOR + 1));
lptr->start = ptr + 1;
state = LQPRS_WAITDELIM;
curqlevel->numvar = 1;
......@@ -448,7 +445,7 @@ lquery_in(PG_FUNCTION_ARGS)
curqlevel = NEXTLEV(curqlevel);
}
result = (lquery *) palloc(totallen);
result = (lquery *) palloc0(totallen);
SET_VARSIZE(result, totallen);
result->numlevel = num;
result->firstgood = 0;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.142 2008/03/25 22:42:43 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.143 2008/04/11 22:52:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -319,7 +319,7 @@ array_in(PG_FUNCTION_ARGS)
dataoffset = 0; /* marker for no null bitmap */
nbytes += ARR_OVERHEAD_NONULLS(ndim);
}
retval = (ArrayType *) palloc(nbytes);
retval = (ArrayType *) palloc0(nbytes);
SET_VARSIZE(retval, nbytes);
retval->ndim = ndim;
retval->dataoffset = dataoffset;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/geo_ops.c,v 1.99 2008/01/01 19:45:52 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/geo_ops.c,v 1.100 2008/04/11 22:52:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1425,6 +1425,8 @@ path_in(PG_FUNCTION_ARGS)
errmsg("invalid input syntax for type path: \"%s\"", str)));
path->closed = (!isopen);
/* prevent instability in unused pad bytes */
path->dummy = 0;
PG_RETURN_PATH_P(path);
}
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/tsquery.c,v 1.16 2008/03/25 22:42:44 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/tsquery.c,v 1.17 2008/04/11 22:52:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -223,7 +223,7 @@ pushOperator(TSQueryParserState state, int8 oper)
Assert(oper == OP_NOT || oper == OP_AND || oper == OP_OR);
tmp = (QueryOperator *) palloc(sizeof(QueryOperator));
tmp = (QueryOperator *) palloc0(sizeof(QueryOperator));
tmp->type = QI_OPR;
tmp->oper = oper;
/* left is filled in later with findoprnd */
......@@ -247,7 +247,7 @@ pushValue_internal(TSQueryParserState state, pg_crc32 valcrc, int distance, int
errmsg("operand is too long in tsquery: \"%s\"",
state->buffer)));
tmp = (QueryOperand *) palloc(sizeof(QueryOperand));
tmp = (QueryOperand *) palloc0(sizeof(QueryOperand));
tmp->type = QI_VAL;
tmp->weight = weight;
tmp->valcrc = (int32) valcrc;
......@@ -304,7 +304,7 @@ pushStop(TSQueryParserState state)
{
QueryOperand *tmp;
tmp = (QueryOperand *) palloc(sizeof(QueryOperand));
tmp = (QueryOperand *) palloc0(sizeof(QueryOperand));
tmp->type = QI_VALSTOP;
state->polstr = lcons(tmp, state->polstr);
......
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