summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2008-04-11 22:53:33 +0000
committerTom Lane2008-04-11 22:53:33 +0000
commit76289946173c26db76541ddb8f87bfd64d584c23 (patch)
tree52b9d545eac0703ad87d2f3ecfba32f153fbd212
parent7beb65a4b756bcf18e9ec2146cc560352e2df6ec (diff)
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.
-rw-r--r--contrib/ltree/ltree_io.c13
-rw-r--r--src/backend/utils/adt/arrayfuncs.c2
-rw-r--r--src/backend/utils/adt/geo_ops.c2
-rw-r--r--src/backend/utils/adt/tsquery.c6
4 files changed, 11 insertions, 12 deletions
diff --git a/contrib/ltree/ltree_io.c b/contrib/ltree/ltree_io.c
index 58d1a6c72d..d534a89690 100644
--- a/contrib/ltree/ltree_io.c
+++ b/contrib/ltree/ltree_io.c
@@ -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;
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index e8b8f19e11..a46db56804 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -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;
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index aaed59c537..6828e5e559 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -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);
}
diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
index 7f5a12d737..efc0433472 100644
--- a/src/backend/utils/adt/tsquery.c
+++ b/src/backend/utils/adt/tsquery.c
@@ -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);