Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb1756da

Browse files
committed
Specify the encoding of input to fmtId()
This commit adds fmtIdEnc() and fmtQualifiedIdEnc(), which allow to specifythe encoding as an explicit argument. Additionally setFmtEncoding() isprovided, which defines the encoding when no explicit encoding is provided, toavoid breaking all code using fmtId().All users of fmtId()/fmtQualifiedId() are either converted to the explicitversion or a call to setFmtEncoding() has been added.This commit does not yet utilize the now well-defined encoding, that willhappen in a subsequent commit.Reviewed-by: Noah Misch <noah@leadboat.com>Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>Backpatch-through: 13Security:CVE-2025-1094
1 parent703b3fd commitb1756da

File tree

13 files changed

+112
-22
lines changed

13 files changed

+112
-22
lines changed

‎src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2733,6 +2733,7 @@ processEncodingEntry(ArchiveHandle *AH, TocEntry *te)
27332733
pg_fatal("unrecognized encoding \"%s\"",
27342734
ptr1);
27352735
AH->public.encoding=encoding;
2736+
setFmtEncoding(encoding);
27362737
}
27372738
else
27382739
pg_fatal("invalid ENCODING item: %s",

‎src/bin/pg_dump/pg_dump.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,7 @@ setup_connection(Archive *AH, const char *dumpencoding,
10951095
* we know how to escape strings.
10961096
*/
10971097
AH->encoding = PQclientEncoding(conn);
1098+
setFmtEncoding(AH->encoding);
10981099

10991100
std_strings = PQparameterStatus(conn, "standard_conforming_strings");
11001101
AH->std_strings = (std_strings && strcmp(std_strings, "on") == 0);

‎src/bin/pg_dump/pg_dumpall.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,7 @@ main(int argc, char *argv[])
494494
* we know how to escape strings.
495495
*/
496496
encoding=PQclientEncoding(conn);
497+
setFmtEncoding(encoding);
497498
std_strings=PQparameterStatus(conn,"standard_conforming_strings");
498499
if (!std_strings)
499500
std_strings="off";

‎src/bin/psql/command.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,7 @@ exec_command_encoding(PsqlScanState scan_state, bool active_branch)
12851285
/* save encoding info into psql internal data */
12861286
pset.encoding=PQclientEncoding(pset.db);
12871287
pset.popt.topt.encoding=pset.encoding;
1288+
setFmtEncoding(pset.encoding);
12881289
SetVariable(pset.vars,"ENCODING",
12891290
pg_encoding_to_char(pset.encoding));
12901291
}
@@ -3740,6 +3741,8 @@ SyncVariables(void)
37403741
pset.popt.topt.encoding=pset.encoding;
37413742
pset.sversion=PQserverVersion(pset.db);
37423743

3744+
setFmtEncoding(pset.encoding);
3745+
37433746
SetVariable(pset.vars,"DBNAME",PQdb(pset.db));
37443747
SetVariable(pset.vars,"USER",PQuser(pset.db));
37453748
SetVariable(pset.vars,"HOST",PQhost(pset.db));

‎src/bin/scripts/common.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,9 @@ appendQualifiedRelation(PQExpBuffer buf, const char *spec,
112112
exit(1);
113113
}
114114
appendPQExpBufferStr(buf,
115-
fmtQualifiedId(PQgetvalue(res,0,1),
116-
PQgetvalue(res,0,0)));
115+
fmtQualifiedIdEnc(PQgetvalue(res,0,1),
116+
PQgetvalue(res,0,0),
117+
PQclientEncoding(conn)));
117118
appendPQExpBufferStr(buf,columns);
118119
PQclear(res);
119120
termPQExpBuffer(&sql);

‎src/bin/scripts/createdb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ main(int argc, char *argv[])
196196

197197
conn=connectMaintenanceDatabase(&cparams,progname,echo);
198198

199+
setFmtEncoding(PQclientEncoding(conn));
200+
199201
initPQExpBuffer(&sql);
200202

201203
appendPQExpBuffer(&sql,"CREATE DATABASE %s",

‎src/bin/scripts/createuser.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ main(int argc, char *argv[])
261261

262262
conn=connectMaintenanceDatabase(&cparams,progname,echo);
263263

264+
setFmtEncoding(PQclientEncoding(conn));
265+
264266
initPQExpBuffer(&sql);
265267

266268
printfPQExpBuffer(&sql,"CREATE ROLE %s",fmtId(newuser));

‎src/bin/scripts/dropdb.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,6 @@ main(int argc, char *argv[])
129129
exit(0);
130130
}
131131

132-
initPQExpBuffer(&sql);
133-
134-
appendPQExpBuffer(&sql,"DROP DATABASE %s%s%s;",
135-
(if_exists ?"IF EXISTS " :""),
136-
fmtId(dbname),
137-
force ?" WITH (FORCE)" :"");
138-
139132
/* Avoid trying to drop postgres db while we are connected to it. */
140133
if (maintenance_db==NULL&&strcmp(dbname,"postgres")==0)
141134
maintenance_db="template1";
@@ -149,6 +142,12 @@ main(int argc, char *argv[])
149142

150143
conn=connectMaintenanceDatabase(&cparams,progname,echo);
151144

145+
initPQExpBuffer(&sql);
146+
appendPQExpBuffer(&sql,"DROP DATABASE %s%s%s;",
147+
(if_exists ?"IF EXISTS " :""),
148+
fmtIdEnc(dbname,PQclientEncoding(conn)),
149+
force ?" WITH (FORCE)" :"");
150+
152151
if (echo)
153152
printf("%s\n",sql.data);
154153
result=PQexec(conn,sql.data);

‎src/bin/scripts/dropuser.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ main(int argc, char *argv[])
143143

144144
initPQExpBuffer(&sql);
145145
appendPQExpBuffer(&sql,"DROP ROLE %s%s;",
146-
(if_exists ?"IF EXISTS " :""),fmtId(dropuser));
146+
(if_exists ?"IF EXISTS " :""),
147+
fmtIdEnc(dropuser,PQclientEncoding(conn)));
147148

148149
if (echo)
149150
printf("%s\n",sql.data);

‎src/bin/scripts/reindexdb.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,8 @@ run_reindex_command(PGconn *conn, ReindexType type, const char *name,
501501

502502
if (tablespace)
503503
{
504-
appendPQExpBuffer(&sql,"%sTABLESPACE %s",sep,fmtId(tablespace));
504+
appendPQExpBuffer(&sql,"%sTABLESPACE %s",sep,
505+
fmtIdEnc(tablespace,PQclientEncoding(conn)));
505506
sep=comma;
506507
}
507508

@@ -541,7 +542,8 @@ run_reindex_command(PGconn *conn, ReindexType type, const char *name,
541542
{
542543
caseREINDEX_DATABASE:
543544
caseREINDEX_SYSTEM:
544-
appendPQExpBufferStr(&sql,fmtId(name));
545+
appendPQExpBufferStr(&sql,
546+
fmtIdEnc(name,PQclientEncoding(conn)));
545547
break;
546548
caseREINDEX_INDEX:
547549
caseREINDEX_TABLE:
@@ -711,8 +713,9 @@ get_parallel_object_list(PGconn *conn, ReindexType type,
711713
for (i=0;i<ntups;i++)
712714
{
713715
appendPQExpBufferStr(&buf,
714-
fmtQualifiedId(PQgetvalue(res,i,1),
715-
PQgetvalue(res,i,0)));
716+
fmtQualifiedIdEnc(PQgetvalue(res,i,1),
717+
PQgetvalue(res,i,0),
718+
PQclientEncoding(conn)));
716719

717720
simple_string_list_append(tables,buf.data);
718721
resetPQExpBuffer(&buf);

‎src/bin/scripts/vacuumdb.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,9 @@ vacuum_one_database(ConnParams *cparams,
646646
for (i=0;i<ntups;i++)
647647
{
648648
appendPQExpBufferStr(&buf,
649-
fmtQualifiedId(PQgetvalue(res,i,1),
650-
PQgetvalue(res,i,0)));
649+
fmtQualifiedIdEnc(PQgetvalue(res,i,1),
650+
PQgetvalue(res,i,0),
651+
PQclientEncoding(conn)));
651652

652653
if (tables_listed&& !PQgetisnull(res,i,2))
653654
appendPQExpBufferStr(&buf,PQgetvalue(res,i,2));

‎src/fe_utils/string_utils.c

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@
1919

2020
#include"common/keywords.h"
2121
#include"fe_utils/string_utils.h"
22+
#include"mb/pg_wchar.h"
2223

2324
staticPQExpBufferdefaultGetLocalPQExpBuffer(void);
2425

2526
/* Globals exported by this file */
2627
intquote_all_identifiers=0;
2728
PQExpBuffer (*getLocalPQExpBuffer) (void)=defaultGetLocalPQExpBuffer;
2829

30+
staticintfmtIdEncoding=-1;
31+
2932

3033
/*
3134
* Returns a temporary PQExpBuffer, valid until the next call to the function.
@@ -54,14 +57,48 @@ defaultGetLocalPQExpBuffer(void)
5457
returnid_return;
5558
}
5659

60+
/*
61+
* Set the encoding that fmtId() and fmtQualifiedId() use.
62+
*
63+
* This is not safe against multiple connections having different encodings,
64+
* but there is no real other way to address the need to know the encoding for
65+
* fmtId()/fmtQualifiedId() input for safe escaping. Eventually we should get
66+
* rid of fmtId().
67+
*/
68+
void
69+
setFmtEncoding(intencoding)
70+
{
71+
fmtIdEncoding=encoding;
72+
}
73+
74+
/*
75+
* Return the currently configured encoding for fmtId() and fmtQualifiedId().
76+
*/
77+
staticint
78+
getFmtEncoding(void)
79+
{
80+
if (fmtIdEncoding!=-1)
81+
returnfmtIdEncoding;
82+
83+
/*
84+
* In assertion builds it seems best to fail hard if the encoding was not
85+
* set, to make it easier to find places with missing calls. But in
86+
* production builds that seems like a bad idea, thus we instead just
87+
* default to UTF-8.
88+
*/
89+
Assert(fmtIdEncoding!=-1);
90+
91+
returnPG_UTF8;
92+
}
93+
5794
/*
5895
*Quotes input string if it's not a legitimate SQL identifier as-is.
5996
*
60-
*Note that the returned string must be used before callingfmtId again,
97+
*Note that the returned string must be used before callingfmtIdEnc again,
6198
*since we re-use the same return buffer each time.
6299
*/
63100
constchar*
64-
fmtId(constchar*rawid)
101+
fmtIdEnc(constchar*rawid,intencoding)
65102
{
66103
PQExpBufferid_return=getLocalPQExpBuffer();
67104

@@ -134,25 +171,42 @@ fmtId(const char *rawid)
134171
}
135172

136173
/*
137-
* fmtQualifiedId - construct a schema-qualified name, with quoting as needed.
174+
*Quotes input string if it's not a legitimate SQL identifier as-is.
175+
*
176+
*Note that the returned string must be used before calling fmtId again,
177+
*since we re-use the same return buffer each time.
178+
*
179+
* NB: This assumes setFmtEncoding() previously has been called to configure
180+
* the encoding of rawid. It is preferable to use fmtIdEnc() with an
181+
* explicit encoding.
182+
*/
183+
constchar*
184+
fmtId(constchar*rawid)
185+
{
186+
returnfmtIdEnc(rawid,getFmtEncoding());
187+
}
188+
189+
/*
190+
* fmtQualifiedIdEnc - construct a schema-qualified name, with quoting as
191+
* needed.
138192
*
139193
* Like fmtId, use the result before calling again.
140194
*
141195
* Since we call fmtId and it also uses getLocalPQExpBuffer() we cannot
142196
* use that buffer until we're finished with calling fmtId().
143197
*/
144198
constchar*
145-
fmtQualifiedId(constchar*schema,constchar*id)
199+
fmtQualifiedIdEnc(constchar*schema,constchar*id,intencoding)
146200
{
147201
PQExpBufferid_return;
148202
PQExpBufferlcl_pqexp=createPQExpBuffer();
149203

150204
/* Some callers might fail to provide a schema name */
151205
if (schema&&*schema)
152206
{
153-
appendPQExpBuffer(lcl_pqexp,"%s.",fmtId(schema));
207+
appendPQExpBuffer(lcl_pqexp,"%s.",fmtIdEnc(schema,encoding));
154208
}
155-
appendPQExpBufferStr(lcl_pqexp,fmtId(id));
209+
appendPQExpBufferStr(lcl_pqexp,fmtIdEnc(id,encoding));
156210

157211
id_return=getLocalPQExpBuffer();
158212

@@ -162,6 +216,24 @@ fmtQualifiedId(const char *schema, const char *id)
162216
returnid_return->data;
163217
}
164218

219+
/*
220+
* fmtQualifiedId - construct a schema-qualified name, with quoting as needed.
221+
*
222+
* Like fmtId, use the result before calling again.
223+
*
224+
* Since we call fmtId and it also uses getLocalPQExpBuffer() we cannot
225+
* use that buffer until we're finished with calling fmtId().
226+
*
227+
* NB: This assumes setFmtEncoding() previously has been called to configure
228+
* the encoding of schema/id. It is preferable to use fmtQualifiedIdEnc()
229+
* with an explicit encoding.
230+
*/
231+
constchar*
232+
fmtQualifiedId(constchar*schema,constchar*id)
233+
{
234+
returnfmtQualifiedIdEnc(schema,id,getFmtEncoding());
235+
}
236+
165237

166238
/*
167239
* Format a Postgres version number (in the PG_VERSION_NUM integer format

‎src/include/fe_utils/string_utils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ extern PQExpBuffer (*getLocalPQExpBuffer) (void);
2525

2626
/* Functions */
2727
externconstchar*fmtId(constchar*identifier);
28+
externconstchar*fmtIdEnc(constchar*identifier,intencoding);
2829
externconstchar*fmtQualifiedId(constchar*schema,constchar*id);
30+
externconstchar*fmtQualifiedIdEnc(constchar*schema,constchar*id,intencoding);
31+
externvoidsetFmtEncoding(intencoding);
2932

3033
externchar*formatPGVersionNumber(intversion_number,boolinclude_minor,
3134
char*buf,size_tbuflen);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp