Skip to content

Commit dc9896a

Browse files
committed
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.
1 parent af275a1 commit dc9896a

File tree

3 files changed

+27
-17
lines changed

3 files changed

+27
-17
lines changed

contrib/pg_upgrade/info.c

+20-11
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ static void get_db_infos(ClusterInfo *cluster);
2323
static void get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo);
2424
static void free_rel_infos(RelInfoArr *rel_arr);
2525
static void print_db_infos(DbInfoArr *dbinfo);
26-
static void print_rel_infos(RelInfoArr *arr);
26+
static void print_rel_infos(RelInfoArr *rel_arr);
2727

2828

2929
/*
@@ -130,8 +130,8 @@ create_rel_filename_map(const char *old_data, const char *new_data,
130130
map->new_relfilenode = new_rel->relfilenode;
131131

132132
/* used only for logging and error reporing, old/new are identical */
133-
snprintf(map->nspname, sizeof(map->nspname), "%s", old_rel->nspname);
134-
snprintf(map->relname, sizeof(map->relname), "%s", old_rel->relname);
133+
map->nspname = old_rel->nspname;
134+
map->relname = old_rel->relname;
135135
}
136136

137137

@@ -223,8 +223,7 @@ get_db_infos(ClusterInfo *cluster)
223223
for (tupnum = 0; tupnum < ntups; tupnum++)
224224
{
225225
dbinfos[tupnum].db_oid = atooid(PQgetvalue(res, tupnum, i_oid));
226-
snprintf(dbinfos[tupnum].db_name, sizeof(dbinfos[tupnum].db_name), "%s",
227-
PQgetvalue(res, tupnum, i_datname));
226+
dbinfos[tupnum].db_name = pg_strdup(PQgetvalue(res, tupnum, i_datname));
228227
snprintf(dbinfos[tupnum].db_tblspace, sizeof(dbinfos[tupnum].db_tblspace), "%s",
229228
PQgetvalue(res, tupnum, i_spclocation));
230229
}
@@ -349,10 +348,10 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
349348
curr->reloid = atooid(PQgetvalue(res, relnum, i_oid));
350349

351350
nspname = PQgetvalue(res, relnum, i_nspname);
352-
strlcpy(curr->nspname, nspname, sizeof(curr->nspname));
351+
curr->nspname = pg_strdup(nspname);
353352

354353
relname = PQgetvalue(res, relnum, i_relname);
355-
strlcpy(curr->relname, relname, sizeof(curr->relname));
354+
curr->relname = pg_strdup(relname);
356355

357356
curr->relfilenode = atooid(PQgetvalue(res, relnum, i_relfilenode));
358357

@@ -380,7 +379,10 @@ free_db_and_rel_infos(DbInfoArr *db_arr)
380379
int dbnum;
381380

382381
for (dbnum = 0; dbnum < db_arr->ndbs; dbnum++)
382+
{
383383
free_rel_infos(&db_arr->dbs[dbnum].rel_arr);
384+
pg_free(db_arr->dbs[dbnum].db_name);
385+
}
384386
pg_free(db_arr->dbs);
385387
db_arr->dbs = NULL;
386388
db_arr->ndbs = 0;
@@ -390,6 +392,13 @@ free_db_and_rel_infos(DbInfoArr *db_arr)
390392
static void
391393
free_rel_infos(RelInfoArr *rel_arr)
392394
{
395+
int relnum;
396+
397+
for (relnum = 0; relnum < rel_arr->nrels; relnum++)
398+
{
399+
pg_free(rel_arr->rels[relnum].nspname);
400+
pg_free(rel_arr->rels[relnum].relname);
401+
}
393402
pg_free(rel_arr->rels);
394403
rel_arr->nrels = 0;
395404
}
@@ -410,12 +419,12 @@ print_db_infos(DbInfoArr *db_arr)
410419

411420

412421
static void
413-
print_rel_infos(RelInfoArr *arr)
422+
print_rel_infos(RelInfoArr *rel_arr)
414423
{
415424
int relnum;
416425

417-
for (relnum = 0; relnum < arr->nrels; relnum++)
426+
for (relnum = 0; relnum < rel_arr->nrels; relnum++)
418427
pg_log(PG_VERBOSE, "relname: %s.%s: reloid: %u reltblspace: %s\n",
419-
arr->rels[relnum].nspname, arr->rels[relnum].relname,
420-
arr->rels[relnum].reloid, arr->rels[relnum].tablespace);
428+
rel_arr->rels[relnum].nspname, rel_arr->rels[relnum].relname,
429+
rel_arr->rels[relnum].reloid, rel_arr->rels[relnum].tablespace);
421430
}

contrib/pg_upgrade/pg_upgrade.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ extern char *output_files[];
114114
*/
115115
typedef struct
116116
{
117-
char nspname[NAMEDATALEN]; /* namespace name */
118-
char relname[NAMEDATALEN]; /* relation name */
117+
/* Can't use NAMEDATALEN; not guaranteed to fit on client */
118+
char *nspname; /* namespace name */
119+
char *relname; /* relation name */
119120
Oid reloid; /* relation oid */
120121
Oid relfilenode; /* relation relfile node */
121122
/* relation tablespace path, or "" for the cluster default */
@@ -143,8 +144,8 @@ typedef struct
143144
Oid old_relfilenode;
144145
Oid new_relfilenode;
145146
/* the rest are used only for logging and error reporting */
146-
char nspname[NAMEDATALEN]; /* namespaces */
147-
char relname[NAMEDATALEN];
147+
char *nspname; /* namespaces */
148+
char *relname;
148149
} FileNameMap;
149150

150151
/*
@@ -153,7 +154,7 @@ typedef struct
153154
typedef struct
154155
{
155156
Oid db_oid; /* oid of the database */
156-
char db_name[NAMEDATALEN]; /* database name */
157+
char *db_name; /* database name */
157158
char db_tblspace[MAXPGPATH]; /* database default tablespace path */
158159
RelInfoArr rel_arr; /* array of all user relinfos */
159160
} DbInfo;

src/bin/initdb/initdb.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1836,7 +1836,7 @@ setup_collation(void)
18361836
#if defined(HAVE_LOCALE_T) && !defined(WIN32)
18371837
int i;
18381838
FILE *locale_a_handle;
1839-
char localebuf[NAMEDATALEN];
1839+
char localebuf[NAMEDATALEN]; /* we assume ASCII so this is fine */
18401840
int count = 0;
18411841

18421842
PG_CMD_DECL;

0 commit comments

Comments
 (0)