Make object address handling more robust
authorAlvaro Herrera <[email protected]>
Wed, 20 Feb 2019 12:12:02 +0000 (09:12 -0300)
committerAlvaro Herrera <[email protected]>
Wed, 20 Feb 2019 14:26:08 +0000 (11:26 -0300)
pg_identify_object_as_address crashes when passed certain tuples from
inconsistent system catalogs.  Make it more defensive.

Author: Álvaro Herrera
Reviewed-by: Michaël Paquier
Discussion: https://postgr.es/m/20190218202743[email protected]

src/backend/catalog/objectaddress.c

index ab3ec7e356a1f9722a190c5f1d229c03d3f7f157..8b51ec7f3940ec12ea63fd734c49ed2fba7da186 100644 (file)
@@ -3939,7 +3939,10 @@ pg_identify_object_as_address(PG_FUNCTION_ARGS)
    pfree(identity);
 
    /* object_names */
-   values[1] = PointerGetDatum(strlist_to_textarray(names));
+   if (names != NIL)
+       values[1] = PointerGetDatum(strlist_to_textarray(names));
+   else
+       values[1] = PointerGetDatum(construct_empty_array(TEXTOID));
    nulls[1] = false;
 
    /* object_args */
@@ -5268,10 +5271,12 @@ strlist_to_textarray(List *list)
 {
    ArrayType  *arr;
    Datum      *datums;
+   bool       *nulls;
    int         j = 0;
    ListCell   *cell;
    MemoryContext memcxt;
    MemoryContext oldcxt;
+   int         lb[1];
 
    /* Work in a temp context; easier than individually pfree'ing the Datums */
    memcxt = AllocSetContextCreate(CurrentMemoryContext,
@@ -5280,18 +5285,26 @@ strlist_to_textarray(List *list)
    oldcxt = MemoryContextSwitchTo(memcxt);
 
    datums = (Datum *) palloc(sizeof(Datum) * list_length(list));
+   nulls = palloc(sizeof(bool) * list_length(list));
 
    foreach(cell, list)
    {
        char       *name = lfirst(cell);
 
-       datums[j++] = CStringGetTextDatum(name);
+       if (name)
+       {
+           nulls[j] = false;
+           datums[j++] = CStringGetTextDatum(name);
+       }
+       else
+           nulls[j] = true;
    }
 
    MemoryContextSwitchTo(oldcxt);
 
-   arr = construct_array(datums, list_length(list),
-                         TEXTOID, -1, false, 'i');
+   lb[0] = 1;
+   arr = construct_md_array(datums, nulls, 1, &j,
+                            lb, TEXTOID, -1, false, 'i');
 
    MemoryContextDelete(memcxt);