Make object address handling more robust
authorAlvaro Herrera
Wed, 20 Feb 2019 12:12:02 +0000 (09:12 -0300)
committerAlvaro Herrera
Wed, 20 Feb 2019 14:22:13 +0000 (11:22 -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 88e69f70fc19e6c7be52b1e0c85b1f03537b9fb2..f8e859d7a251245e4a2042c9a506539d8eb67071 100644 (file)
@@ -3815,7 +3815,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 */
@@ -5134,10 +5137,12 @@ strlist_to_textarray(List *list)
 {
    ArrayType  *arr;
    Datum      *datums;
+   bool       *nulls;
    int         j = 0;
    ListCell   *cell;
    MemoryContext memcxt;
    MemoryContext oldcxt;
+   int         lb[1];
 
    memcxt = AllocSetContextCreate(CurrentMemoryContext,
                                   "strlist to array",
@@ -5145,17 +5150,25 @@ strlist_to_textarray(List *list)
    oldcxt = MemoryContextSwitchTo(memcxt);
 
    datums = palloc(sizeof(text *) * 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);
 
    return arr;