Thread: BUG #5111: Segmentation fault, if to_tsvector returns empty row to ts_stat

BUG #5111: Segmentation fault, if to_tsvector returns empty row to ts_stat

From
"Fendris"
Date:
The following bug has been logged online:

Bug reference:      5111
Logged by:          Fendris
Email address:      f.fendris@gmail.com
PostgreSQL version: 8.4.1
Operating system:   x86_64 Debian 5.0.3
Description:        Segmentation fault, if to_tsvector returns empty row to
ts_stat
Details:

example SQL:

SELECT * from ts_stat('SELECT to_tsvector(''simple'','''')');

Core:

Core was generated by `postgres: postgres postgres [local] SELECT
                        '.

Program terminated with signal 11, Segmentation fault.


[New process 30914]


#0  ts_setup_firstcall (fcinfo=<value optimized out>, funcctx=0x1e96290,
stat=0x1e962e0) at tsvector_op.c:965

965     tsvector_op.c: No such file or directory.


        in tsvector_op.c




(gdb) info locals


tupdesc = <value optimized out>


oldcontext = (MemoryContext) 0x1ec8ca0


node = (StatEntry *) 0x0


(gdb) print


The history is empty.


(gdb) info args


fcinfo = <value optimized out>


funcctx = (FuncCallContext *) 0x1e96290


stat = (TSVectorStat *) 0x1e962e0


(gdb) list


960     in tsvector_op.c
"Fendris" <f.fendris@gmail.com> writes:
> SELECT * from ts_stat('SELECT to_tsvector(''simple'','''')');
> [ dumps core ]

Thanks, looks like this code just missed the possibility of an empty
tree.  Attached patch fixes it.

            regards, tom lane

*** src/backend/utils/adt/tsvector_op.c.orig    Thu Jul 16 02:33:44 2009
--- src/backend/utils/adt/tsvector_op.c    Tue Oct 13 10:19:24 2009
***************
*** 959,975 ****

      node = stat->root;
      /* find leftmost value */
!     for (;;)
!     {
!         stat->stack[stat->stackpos] = node;
!         if (node->left)
          {
!             stat->stackpos++;
!             node = node->left;
          }
!         else
!             break;
!     }

      tupdesc = CreateTemplateTupleDesc(3, false);
      TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
--- 959,979 ----

      node = stat->root;
      /* find leftmost value */
!     if (node == NULL)
!         stat->stack[stat->stackpos] = NULL;
!     else
!         for (;;)
          {
!             stat->stack[stat->stackpos] = node;
!             if (node->left)
!             {
!                 stat->stackpos++;
!                 node = node->left;
!             }
!             else
!                 break;
          }
!     Assert(stat->stackpos <= stat->maxdepth);

      tupdesc = CreateTemplateTupleDesc(3, false);
      TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
***************
*** 1015,1020 ****
--- 1019,1025 ----
              else
                  break;
          }
+         Assert(stat->stackpos <= stat->maxdepth);
      }
      else
      {