Fix several datatype input functions that were allowing unused bytes in their
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 11 Apr 2008 22:53:33 +0000 (22:53 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 11 Apr 2008 22:53:33 +0000 (22:53 +0000)
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.

contrib/ltree/ltree_io.c
src/backend/utils/adt/arrayfuncs.c
src/backend/utils/adt/geo_ops.c
src/backend/utils/adt/tsquery.c

index 58d1a6c72d34a2a1e22f45f9f3f3f021718fd636..d534a89690c69ca26a8dd25e1ad685c5b36798db 100644 (file)
@@ -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;
index e8b8f19e1185bb0721fb7c1ed934cbdd23fb2065..a46db56804373510cb51df6743246834b3c250cb 100644 (file)
@@ -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;
index aaed59c537c2f602d75857777421c14296dc45be..6828e5e5598890896278f9c100d27e04d02194c1 100644 (file)
@@ -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);
 }
index 7f5a12d73719831f53f57a6122fcf9e59a000ed6..efc04334727df236a195dff2a222a0965bde8782 100644 (file)
@@ -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);