From: Bruce Momjian Date: Thu, 20 Dec 2012 18:56:24 +0000 (-0500) Subject: Avoid using NAMEDATALEN in pg_upgrade X-Git-Tag: REL9_3_BETA1~576 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dc9896a2457f0d72458f1ff45935362521f0f99c;p=postgresql Avoid using NAMEDATALEN in pg_upgrade Because the client encoding might not match the server encoding, pg_upgrade can't allocate NAMEDATALEN bytes for storage of database, relation, and namespace identifiers. Instead pg_strdup() the memory and free it. Also add C comment in initdb.c about safe NAMEDATALEN usage. --- diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c index 11ceb70567..b19f2103ca 100644 --- a/contrib/pg_upgrade/info.c +++ b/contrib/pg_upgrade/info.c @@ -23,7 +23,7 @@ static void get_db_infos(ClusterInfo *cluster); static void get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo); static void free_rel_infos(RelInfoArr *rel_arr); static void print_db_infos(DbInfoArr *dbinfo); -static void print_rel_infos(RelInfoArr *arr); +static void print_rel_infos(RelInfoArr *rel_arr); /* @@ -130,8 +130,8 @@ create_rel_filename_map(const char *old_data, const char *new_data, map->new_relfilenode = new_rel->relfilenode; /* used only for logging and error reporing, old/new are identical */ - snprintf(map->nspname, sizeof(map->nspname), "%s", old_rel->nspname); - snprintf(map->relname, sizeof(map->relname), "%s", old_rel->relname); + map->nspname = old_rel->nspname; + map->relname = old_rel->relname; } @@ -223,8 +223,7 @@ get_db_infos(ClusterInfo *cluster) for (tupnum = 0; tupnum < ntups; tupnum++) { dbinfos[tupnum].db_oid = atooid(PQgetvalue(res, tupnum, i_oid)); - snprintf(dbinfos[tupnum].db_name, sizeof(dbinfos[tupnum].db_name), "%s", - PQgetvalue(res, tupnum, i_datname)); + dbinfos[tupnum].db_name = pg_strdup(PQgetvalue(res, tupnum, i_datname)); snprintf(dbinfos[tupnum].db_tblspace, sizeof(dbinfos[tupnum].db_tblspace), "%s", PQgetvalue(res, tupnum, i_spclocation)); } @@ -349,10 +348,10 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo) curr->reloid = atooid(PQgetvalue(res, relnum, i_oid)); nspname = PQgetvalue(res, relnum, i_nspname); - strlcpy(curr->nspname, nspname, sizeof(curr->nspname)); + curr->nspname = pg_strdup(nspname); relname = PQgetvalue(res, relnum, i_relname); - strlcpy(curr->relname, relname, sizeof(curr->relname)); + curr->relname = pg_strdup(relname); curr->relfilenode = atooid(PQgetvalue(res, relnum, i_relfilenode)); @@ -380,7 +379,10 @@ free_db_and_rel_infos(DbInfoArr *db_arr) int dbnum; for (dbnum = 0; dbnum < db_arr->ndbs; dbnum++) + { free_rel_infos(&db_arr->dbs[dbnum].rel_arr); + pg_free(db_arr->dbs[dbnum].db_name); + } pg_free(db_arr->dbs); db_arr->dbs = NULL; db_arr->ndbs = 0; @@ -390,6 +392,13 @@ free_db_and_rel_infos(DbInfoArr *db_arr) static void free_rel_infos(RelInfoArr *rel_arr) { + int relnum; + + for (relnum = 0; relnum < rel_arr->nrels; relnum++) + { + pg_free(rel_arr->rels[relnum].nspname); + pg_free(rel_arr->rels[relnum].relname); + } pg_free(rel_arr->rels); rel_arr->nrels = 0; } @@ -410,12 +419,12 @@ print_db_infos(DbInfoArr *db_arr) static void -print_rel_infos(RelInfoArr *arr) +print_rel_infos(RelInfoArr *rel_arr) { int relnum; - for (relnum = 0; relnum < arr->nrels; relnum++) + for (relnum = 0; relnum < rel_arr->nrels; relnum++) pg_log(PG_VERBOSE, "relname: %s.%s: reloid: %u reltblspace: %s\n", - arr->rels[relnum].nspname, arr->rels[relnum].relname, - arr->rels[relnum].reloid, arr->rels[relnum].tablespace); + rel_arr->rels[relnum].nspname, rel_arr->rels[relnum].relname, + rel_arr->rels[relnum].reloid, rel_arr->rels[relnum].tablespace); } diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h index 972e8e95e9..cae1e46c95 100644 --- a/contrib/pg_upgrade/pg_upgrade.h +++ b/contrib/pg_upgrade/pg_upgrade.h @@ -114,8 +114,9 @@ extern char *output_files[]; */ typedef struct { - char nspname[NAMEDATALEN]; /* namespace name */ - char relname[NAMEDATALEN]; /* relation name */ + /* Can't use NAMEDATALEN; not guaranteed to fit on client */ + char *nspname; /* namespace name */ + char *relname; /* relation name */ Oid reloid; /* relation oid */ Oid relfilenode; /* relation relfile node */ /* relation tablespace path, or "" for the cluster default */ @@ -143,8 +144,8 @@ typedef struct Oid old_relfilenode; Oid new_relfilenode; /* the rest are used only for logging and error reporting */ - char nspname[NAMEDATALEN]; /* namespaces */ - char relname[NAMEDATALEN]; + char *nspname; /* namespaces */ + char *relname; } FileNameMap; /* @@ -153,7 +154,7 @@ typedef struct typedef struct { Oid db_oid; /* oid of the database */ - char db_name[NAMEDATALEN]; /* database name */ + char *db_name; /* database name */ char db_tblspace[MAXPGPATH]; /* database default tablespace path */ RelInfoArr rel_arr; /* array of all user relinfos */ } DbInfo; diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 40740dcb72..3e05ac3309 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -1836,7 +1836,7 @@ setup_collation(void) #if defined(HAVE_LOCALE_T) && !defined(WIN32) int i; FILE *locale_a_handle; - char localebuf[NAMEDATALEN]; + char localebuf[NAMEDATALEN]; /* we assume ASCII so this is fine */ int count = 0; PG_CMD_DECL;