Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c410af0

Browse files
committed
Mop up some no-longer-necessary hacks around printf %.*s format.
Commit 54cd4f0 added some kluges to work around an old glibc bug, namely that %.*s could misbehave if glibc thought any characters in the supplied string were incorrectly encoded. Now that we use our own snprintf.c implementation, we need not worry about that bug (even if it still exists in the wild). Revert a couple of particularly ugly hacks, and remove or improve assorted comments. Note that there can still be encoding-related hazards here: blindly clipping at a fixed length risks producing wrongly-encoded output if the clip splits a multibyte character. However, code that's doing correct multibyte-aware clipping doesn't really need a comment about that, while code that isn't needs an explanation why not, rather than a red-herring comment about an obsolete bug. Discussion: https://postgr.es/m/279428.1593373684@sss.pgh.pa.us
1 parent f7a476f commit c410af0

File tree

9 files changed

+16
-75
lines changed

9 files changed

+16
-75
lines changed

src/backend/commands/copy.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,11 +2303,7 @@ CopyFromErrorCallback(void *arg)
23032303
/*
23042304
* Make sure we don't print an unreasonable amount of COPY data in a message.
23052305
*
2306-
* It would seem a lot easier to just use the sprintf "precision" limit to
2307-
* truncate the string. However, some versions of glibc have a bug/misfeature
2308-
* that vsnprintf will always fail (return -1) if it is asked to truncate
2309-
* a string that contains invalid byte sequences for the current encoding.
2310-
* So, do our own truncation. We return a pstrdup'd copy of the input.
2306+
* Returns a pstrdup'd copy of the input.
23112307
*/
23122308
static char *
23132309
limit_printout_length(const char *str)

src/backend/parser/scansup.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -189,20 +189,10 @@ truncate_identifier(char *ident, int len, bool warn)
189189
{
190190
len = pg_mbcliplen(ident, len, NAMEDATALEN - 1);
191191
if (warn)
192-
{
193-
/*
194-
* We avoid using %.*s here because it can misbehave if the data
195-
* is not valid in what libc thinks is the prevailing encoding.
196-
*/
197-
char buf[NAMEDATALEN];
198-
199-
memcpy(buf, ident, len);
200-
buf[len] = '\0';
201192
ereport(NOTICE,
202193
(errcode(ERRCODE_NAME_TOO_LONG),
203-
errmsg("identifier \"%s\" will be truncated to \"%s\"",
204-
ident, buf)));
205-
}
194+
errmsg("identifier \"%s\" will be truncated to \"%.*s\"",
195+
ident, len, ident)));
206196
ident[len] = '\0';
207197
}
208198
}

src/backend/tsearch/wparser_def.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,6 @@ TParserInit(char *str, int len)
324324
prs->state->state = TPS_Base;
325325

326326
#ifdef WPARSER_TRACE
327-
328-
/*
329-
* Use of %.*s here is a bit risky since it can misbehave if the data is
330-
* not in what libc thinks is the prevailing encoding. However, since
331-
* this is just a debugging aid, we choose to live with that.
332-
*/
333327
fprintf(stderr, "parsing \"%.*s\"\n", len, str);
334328
#endif
335329

@@ -366,7 +360,6 @@ TParserCopyInit(const TParser *orig)
366360
prs->state->state = TPS_Base;
367361

368362
#ifdef WPARSER_TRACE
369-
/* See note above about %.*s */
370363
fprintf(stderr, "parsing copy of \"%.*s\"\n", prs->lenstr, prs->str);
371364
#endif
372365

src/backend/utils/adt/datetime.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4013,7 +4013,8 @@ EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char
40134013

40144014
/*
40154015
* Note: the uses of %.*s in this function would be risky if the
4016-
* timezone names ever contain non-ASCII characters. However, all
4016+
* timezone names ever contain non-ASCII characters, since we are
4017+
* not being careful to do encoding-aware clipping. However, all
40174018
* TZ abbreviations in the IANA database are plain ASCII.
40184019
*/
40194020
if (print_tz)

src/backend/utils/adt/ruleutils.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3554,11 +3554,6 @@ set_rtable_names(deparse_namespace *dpns, List *parent_namespaces,
35543554
hentry->counter++;
35553555
for (;;)
35563556
{
3557-
/*
3558-
* We avoid using %.*s here because it can misbehave
3559-
* if the data is not valid in what libc thinks is the
3560-
* prevailing encoding.
3561-
*/
35623557
memcpy(modname, refname, refnamelen);
35633558
sprintf(modname + refnamelen, "_%d", hentry->counter);
35643559
if (strlen(modname) < NAMEDATALEN)
@@ -4438,11 +4433,6 @@ make_colname_unique(char *colname, deparse_namespace *dpns,
44384433
i++;
44394434
for (;;)
44404435
{
4441-
/*
4442-
* We avoid using %.*s here because it can misbehave if the
4443-
* data is not valid in what libc thinks is the prevailing
4444-
* encoding.
4445-
*/
44464436
memcpy(modname, colname, colnamelen);
44474437
sprintf(modname + colnamelen, "_%d", i);
44484438
if (strlen(modname) < NAMEDATALEN)

src/fe_utils/print.c

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -305,20 +305,6 @@ format_numeric_locale(const char *my_str)
305305
}
306306

307307

308-
/*
309-
* fputnbytes: print exactly N bytes to a file
310-
*
311-
* We avoid using %.*s here because it can misbehave if the data
312-
* is not valid in what libc thinks is the prevailing encoding.
313-
*/
314-
static void
315-
fputnbytes(FILE *f, const char *str, size_t n)
316-
{
317-
while (n-- > 0)
318-
fputc(*str++, f);
319-
}
320-
321-
322308
static void
323309
print_separator(struct separator sep, FILE *fout)
324310
{
@@ -1042,16 +1028,14 @@ print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager)
10421028
{
10431029
/* spaces first */
10441030
fprintf(fout, "%*s", width_wrap[j] - chars_to_output, "");
1045-
fputnbytes(fout,
1046-
(char *) (this_line->ptr + bytes_output[j]),
1047-
bytes_to_output);
1031+
fwrite((char *) (this_line->ptr + bytes_output[j]),
1032+
1, bytes_to_output, fout);
10481033
}
10491034
else /* Left aligned cell */
10501035
{
10511036
/* spaces second */
1052-
fputnbytes(fout,
1053-
(char *) (this_line->ptr + bytes_output[j]),
1054-
bytes_to_output);
1037+
fwrite((char *) (this_line->ptr + bytes_output[j]),
1038+
1, bytes_to_output, fout);
10551039
}
10561040

10571041
bytes_output[j] += bytes_to_output;
@@ -1637,8 +1621,8 @@ print_aligned_vertical(const printTableContent *cont,
16371621
*/
16381622
bytes_to_output = strlen_max_width(dlineptr[dline].ptr + offset,
16391623
&target_width, encoding);
1640-
fputnbytes(fout, (char *) (dlineptr[dline].ptr + offset),
1641-
bytes_to_output);
1624+
fwrite((char *) (dlineptr[dline].ptr + offset),
1625+
1, bytes_to_output, fout);
16421626

16431627
chars_to_output -= target_width;
16441628
offset += bytes_to_output;

src/interfaces/ecpg/ecpglib/error.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,6 @@ ecpg_raise_backend(int line, PGresult *result, PGconn *conn, int compat)
270270
else
271271
sqlca->sqlcode = ECPG_PGSQL;
272272

273-
/* %.*s is safe here as long as sqlstate is all-ASCII */
274273
ecpg_log("raising sqlstate %.*s (sqlcode %ld): %s\n",
275274
(int) sizeof(sqlca->sqlstate), sqlca->sqlstate, sqlca->sqlcode, sqlca->sqlerrm.sqlerrmc);
276275

src/interfaces/ecpg/pgtypeslib/dt_common.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,8 @@ EncodeDateTime(struct tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tz
826826

827827
/*
828828
* Note: the uses of %.*s in this function would be risky if the
829-
* timezone names ever contain non-ASCII characters. However, all
829+
* timezone names ever contain non-ASCII characters, since we are
830+
* not being careful to do encoding-aware clipping. However, all
830831
* TZ abbreviations in the IANA database are plain ASCII.
831832
*/
832833

src/interfaces/libpq/fe-misc.c

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,6 @@ PQlibVersion(void)
6868
return PG_VERSION_NUM;
6969
}
7070

71-
/*
72-
* fputnbytes: print exactly N bytes to a file
73-
*
74-
* We avoid using %.*s here because it can misbehave if the data
75-
* is not valid in what libc thinks is the prevailing encoding.
76-
*/
77-
static void
78-
fputnbytes(FILE *f, const char *str, size_t n)
79-
{
80-
while (n-- > 0)
81-
fputc(*str++, f);
82-
}
83-
8471

8572
/*
8673
* pqGetc: get 1 character from the connection
@@ -204,7 +191,7 @@ pqGetnchar(char *s, size_t len, PGconn *conn)
204191
if (conn->Pfdebug)
205192
{
206193
fprintf(conn->Pfdebug, "From backend (%lu)> ", (unsigned long) len);
207-
fputnbytes(conn->Pfdebug, s, len);
194+
fwrite(s, 1, len, conn->Pfdebug);
208195
fprintf(conn->Pfdebug, "\n");
209196
}
210197

@@ -228,7 +215,7 @@ pqSkipnchar(size_t len, PGconn *conn)
228215
if (conn->Pfdebug)
229216
{
230217
fprintf(conn->Pfdebug, "From backend (%lu)> ", (unsigned long) len);
231-
fputnbytes(conn->Pfdebug, conn->inBuffer + conn->inCursor, len);
218+
fwrite(conn->inBuffer + conn->inCursor, 1, len, conn->Pfdebug);
232219
fprintf(conn->Pfdebug, "\n");
233220
}
234221

@@ -250,7 +237,7 @@ pqPutnchar(const char *s, size_t len, PGconn *conn)
250237
if (conn->Pfdebug)
251238
{
252239
fprintf(conn->Pfdebug, "To backend> ");
253-
fputnbytes(conn->Pfdebug, s, len);
240+
fwrite(s, 1, len, conn->Pfdebug);
254241
fprintf(conn->Pfdebug, "\n");
255242
}
256243

0 commit comments

Comments
 (0)