Fix incorrect encoding-aware name truncation in makeArrayTypeName().
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 16 Aug 2009 18:14:34 +0000 (18:14 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 16 Aug 2009 18:14:34 +0000 (18:14 +0000)
truncate_identifier won't do anything if the passed-in strlen is already
less than NAMEDATALEN, which it always would be given the strlcpy usage.
This has been broken since the arrays-of-composite-types code went in.

Arguably truncate_identifier is suffering from excessive optimization
and should always process the string, but for the moment I'll take the
more localized patch.

Per bug #4987.

src/backend/catalog/pg_type.c

index 0788a2675363fe867e80df41f95f4f233262b8fd..76964802f43578957920974f8180f7498e88eb13 100644 (file)
@@ -686,23 +686,27 @@ RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace)
 char *
 makeArrayTypeName(const char *typeName, Oid typeNamespace)
 {
-       char       *arr;
-       int                     i;
+       char       *arr = (char *) palloc(NAMEDATALEN);
+       int                     namelen = strlen(typeName);
        Relation        pg_type_desc;
+       int                     i;
 
        /*
         * The idea is to prepend underscores as needed until we make a name that
         * doesn't collide with anything...
         */
-       arr = palloc(NAMEDATALEN);
-
        pg_type_desc = heap_open(TypeRelationId, AccessShareLock);
 
        for (i = 1; i < NAMEDATALEN - 1; i++)
        {
                arr[i - 1] = '_';
-               strlcpy(arr + i, typeName, NAMEDATALEN - i);
-               truncate_identifier(arr, strlen(arr), false);
+               if (i + namelen < NAMEDATALEN)
+                       strcpy(arr + i, typeName);
+               else
+               {
+                       memcpy(arr + i, typeName, NAMEDATALEN - i);
+                       truncate_identifier(arr, NAMEDATALEN, false);
+               }
                if (!SearchSysCacheExists(TYPENAMENSP,
                                                                  CStringGetDatum(arr),
                                                                  ObjectIdGetDatum(typeNamespace),