Re: fix for BUG #3720: wrong results at using ltree

Alexander Korotkov <a.korotkov@postgrespro.ru>

From: Alexander Korotkov <a.korotkov@postgrespro.ru>
To: Nikita Glukhov <n.gluhov@postgrespro.ru>
Cc: Oleg Bartunov <obartunov@postgrespro.ru>, Thomas Munro <thomas.munro@gmail.com>, Pgsql Hackers <pgsql-hackers@postgresql.org>, Tom Lane <tgl@sss.pgh.pa.us>, Filip Rembiałkowski <filip.rembialkowski@gmail.com>, Teodor Sigaev <teodor@sigaev.ru>
Date: 2019-07-17T18:33:46Z
Lists: pgsql-hackers
Hi Nikita,

On Tue, Jul 16, 2019 at 6:52 PM Nikita Glukhov <n.gluhov@postgrespro.ru> wrote:
> I looked at "ltree syntax improvement" patch and found two more very
> old bugs in ltree/lquery (fixes are attached):

Thank you for the fixes.  I've couple notes on them.

0001-Fix-max-size-checking-for-ltree-and-lquery.patch

+#define LTREE_MAX_LEVELS Min(PG_UINT16_MAX, MaxAllocSize / sizeof(nodeitem))
+#define LQUERY_MAX_LEVELS Min(PG_UINT16_MAX, MaxAllocSize / ITEMSIZE)

Looks over caution.  PG_UINT16_MAX is not even close to MaxAllocSize /
sizeof(nodeitem) or MaxAllocSize / ITEMSIZE.

0002-Fix-successive-lquery-ops.patch

diff --git a/contrib/ltree/lquery_op.c b/contrib/ltree/lquery_op.c
index 62172d5..d4f4941 100644
--- a/contrib/ltree/lquery_op.c
+++ b/contrib/ltree/lquery_op.c
@@ -255,8 +255,8 @@ checkCond(lquery_level *curq, int query_numlevel,
ltree_level *curt, int tree_nu
  }
  else
  {
- low_pos = cur_tpos + curq->low;
- high_pos = cur_tpos + curq->high;
+ low_pos = Min(low_pos + curq->low, PG_UINT16_MAX);
+ high_pos = Min(high_pos + curq->high, PG_UINT16_MAX);
  if (ptr && ptr->q)
  {
  ptr->nq++;
@@ -282,8 +282,8 @@ checkCond(lquery_level *curq, int query_numlevel,
ltree_level *curt, int tree_nu
  }
  else
  {
- low_pos = cur_tpos + curq->low;
- high_pos = cur_tpos + curq->high;
+ low_pos = Min(low_pos + curq->low, PG_UINT16_MAX);
+ high_pos = Min(high_pos + curq->high, PG_UINT16_MAX);
  }

  curq = LQL_NEXT(curq);

I'm not sure what do these checks do.  Code around is uncommented and
puzzled.  But could we guarantee the same invariant on the stage of
ltree/lquery parsing?

------
Alexander Korotkov
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company



Commits

  1. Back-patch addition of stack overflow and interrupt checks for lquery.

  2. Fix lquery's NOT handling, and add ability to quantify non-'*' items.

  3. Improve error messages in ltree_in and lquery_in.

  4. Fix lquery's behavior for consecutive '*' items.

  5. Protect against overflow of ltree.numlevel and lquery.numlevel.