mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									af275a12df
								
							
						
					
					
						commit
						dc9896a245
					
				| @ -23,7 +23,7 @@ static void get_db_infos(ClusterInfo *cluster); | |||||||
| static void get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo); | static void get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo); | ||||||
| static void free_rel_infos(RelInfoArr *rel_arr); | static void free_rel_infos(RelInfoArr *rel_arr); | ||||||
| static void print_db_infos(DbInfoArr *dbinfo); | 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; | 	map->new_relfilenode = new_rel->relfilenode; | ||||||
| 
 | 
 | ||||||
| 	/* used only for logging and error reporing, old/new are identical */ | 	/* used only for logging and error reporing, old/new are identical */ | ||||||
| 	snprintf(map->nspname, sizeof(map->nspname), "%s", old_rel->nspname); | 	map->nspname = old_rel->nspname; | ||||||
| 	snprintf(map->relname, sizeof(map->relname), "%s", old_rel->relname); | 	map->relname = old_rel->relname; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -223,8 +223,7 @@ get_db_infos(ClusterInfo *cluster) | |||||||
| 	for (tupnum = 0; tupnum < ntups; tupnum++) | 	for (tupnum = 0; tupnum < ntups; tupnum++) | ||||||
| 	{ | 	{ | ||||||
| 		dbinfos[tupnum].db_oid = atooid(PQgetvalue(res, tupnum, i_oid)); | 		dbinfos[tupnum].db_oid = atooid(PQgetvalue(res, tupnum, i_oid)); | ||||||
| 		snprintf(dbinfos[tupnum].db_name, sizeof(dbinfos[tupnum].db_name), "%s", | 		dbinfos[tupnum].db_name = pg_strdup(PQgetvalue(res, tupnum, i_datname)); | ||||||
| 				 PQgetvalue(res, tupnum, i_datname)); |  | ||||||
| 		snprintf(dbinfos[tupnum].db_tblspace, sizeof(dbinfos[tupnum].db_tblspace), "%s", | 		snprintf(dbinfos[tupnum].db_tblspace, sizeof(dbinfos[tupnum].db_tblspace), "%s", | ||||||
| 				 PQgetvalue(res, tupnum, i_spclocation)); | 				 PQgetvalue(res, tupnum, i_spclocation)); | ||||||
| 	} | 	} | ||||||
| @ -349,10 +348,10 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo) | |||||||
| 		curr->reloid = atooid(PQgetvalue(res, relnum, i_oid)); | 		curr->reloid = atooid(PQgetvalue(res, relnum, i_oid)); | ||||||
| 
 | 
 | ||||||
| 		nspname = PQgetvalue(res, relnum, i_nspname); | 		nspname = PQgetvalue(res, relnum, i_nspname); | ||||||
| 		strlcpy(curr->nspname, nspname, sizeof(curr->nspname)); | 		curr->nspname = pg_strdup(nspname); | ||||||
| 
 | 
 | ||||||
| 		relname = PQgetvalue(res, relnum, i_relname); | 		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)); | 		curr->relfilenode = atooid(PQgetvalue(res, relnum, i_relfilenode)); | ||||||
| 
 | 
 | ||||||
| @ -380,7 +379,10 @@ free_db_and_rel_infos(DbInfoArr *db_arr) | |||||||
| 	int			dbnum; | 	int			dbnum; | ||||||
| 
 | 
 | ||||||
| 	for (dbnum = 0; dbnum < db_arr->ndbs; dbnum++) | 	for (dbnum = 0; dbnum < db_arr->ndbs; dbnum++) | ||||||
|  | 	{ | ||||||
| 		free_rel_infos(&db_arr->dbs[dbnum].rel_arr); | 		free_rel_infos(&db_arr->dbs[dbnum].rel_arr); | ||||||
|  | 		pg_free(db_arr->dbs[dbnum].db_name); | ||||||
|  | 	} | ||||||
| 	pg_free(db_arr->dbs); | 	pg_free(db_arr->dbs); | ||||||
| 	db_arr->dbs = NULL; | 	db_arr->dbs = NULL; | ||||||
| 	db_arr->ndbs = 0; | 	db_arr->ndbs = 0; | ||||||
| @ -390,6 +392,13 @@ free_db_and_rel_infos(DbInfoArr *db_arr) | |||||||
| static void | static void | ||||||
| free_rel_infos(RelInfoArr *rel_arr) | 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); | 	pg_free(rel_arr->rels); | ||||||
| 	rel_arr->nrels = 0; | 	rel_arr->nrels = 0; | ||||||
| } | } | ||||||
| @ -410,12 +419,12 @@ print_db_infos(DbInfoArr *db_arr) | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| print_rel_infos(RelInfoArr *arr) | print_rel_infos(RelInfoArr *rel_arr) | ||||||
| { | { | ||||||
| 	int			relnum; | 	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", | 		pg_log(PG_VERBOSE, "relname: %s.%s: reloid: %u reltblspace: %s\n", | ||||||
| 			   arr->rels[relnum].nspname, arr->rels[relnum].relname, | 			   rel_arr->rels[relnum].nspname, rel_arr->rels[relnum].relname, | ||||||
| 			   arr->rels[relnum].reloid, arr->rels[relnum].tablespace); | 			   rel_arr->rels[relnum].reloid, rel_arr->rels[relnum].tablespace); | ||||||
| } | } | ||||||
|  | |||||||
| @ -114,8 +114,9 @@ extern char *output_files[]; | |||||||
|  */ |  */ | ||||||
| typedef struct | typedef struct | ||||||
| { | { | ||||||
| 	char		nspname[NAMEDATALEN];	/* namespace name */ | 	/* Can't use NAMEDATALEN;  not guaranteed to fit on client */ | ||||||
| 	char		relname[NAMEDATALEN];	/* relation name */ | 	char		*nspname;		/* namespace name */ | ||||||
|  | 	char		*relname;		/* relation name */ | ||||||
| 	Oid			reloid;			/* relation oid */ | 	Oid			reloid;			/* relation oid */ | ||||||
| 	Oid			relfilenode;	/* relation relfile node */ | 	Oid			relfilenode;	/* relation relfile node */ | ||||||
| 	/* relation tablespace path, or "" for the cluster default */ | 	/* relation tablespace path, or "" for the cluster default */ | ||||||
| @ -143,8 +144,8 @@ typedef struct | |||||||
| 	Oid			old_relfilenode; | 	Oid			old_relfilenode; | ||||||
| 	Oid			new_relfilenode; | 	Oid			new_relfilenode; | ||||||
| 	/* the rest are used only for logging and error reporting */ | 	/* the rest are used only for logging and error reporting */ | ||||||
| 	char		nspname[NAMEDATALEN];	/* namespaces */ | 	char		*nspname;		/* namespaces */ | ||||||
| 	char		relname[NAMEDATALEN]; | 	char		*relname; | ||||||
| } FileNameMap; | } FileNameMap; | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
| @ -153,7 +154,7 @@ typedef struct | |||||||
| typedef struct | typedef struct | ||||||
| { | { | ||||||
| 	Oid			db_oid;			/* oid of the database */ | 	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 */ | 	char		db_tblspace[MAXPGPATH]; /* database default tablespace path */ | ||||||
| 	RelInfoArr	rel_arr;		/* array of all user relinfos */ | 	RelInfoArr	rel_arr;		/* array of all user relinfos */ | ||||||
| } DbInfo; | } DbInfo; | ||||||
|  | |||||||
| @ -1836,7 +1836,7 @@ setup_collation(void) | |||||||
| #if defined(HAVE_LOCALE_T) && !defined(WIN32) | #if defined(HAVE_LOCALE_T) && !defined(WIN32) | ||||||
| 	int			i; | 	int			i; | ||||||
| 	FILE	   *locale_a_handle; | 	FILE	   *locale_a_handle; | ||||||
| 	char		localebuf[NAMEDATALEN]; | 	char		localebuf[NAMEDATALEN]; /* we assume ASCII so this is fine */ | ||||||
| 	int			count = 0; | 	int			count = 0; | ||||||
| 
 | 
 | ||||||
| 	PG_CMD_DECL; | 	PG_CMD_DECL; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user