Skip to content

Commit d566ad3

Browse files
committed
Fix string truncation to be multibyte-aware in text_name and bpchar_name.
Previously, casts to name could generate invalidly-encoded results. Also, make these functions match namein() more exactly, by consistently using palloc0() instead of ad-hoc zeroing code. Back-patch to all supported branches. Karl Schnaitter and Tom Lane
1 parent 965d76f commit d566ad3

File tree

3 files changed

+14
-22
lines changed

3 files changed

+14
-22
lines changed

src/backend/utils/adt/name.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,17 @@ Datum
4646
namein(PG_FUNCTION_ARGS)
4747
{
4848
char *s = PG_GETARG_CSTRING(0);
49-
NameData *result;
49+
Name result;
5050
int len;
5151

5252
len = strlen(s);
53-
len = pg_mbcliplen(s, len, NAMEDATALEN - 1);
5453

55-
result = (NameData *) palloc0(NAMEDATALEN);
54+
/* Truncate oversize input */
55+
if (len >= NAMEDATALEN)
56+
len = pg_mbcliplen(s, len, NAMEDATALEN - 1);
57+
58+
/* We use palloc0 here to ensure result is zero-padded */
59+
result = (Name) palloc0(NAMEDATALEN);
5660
memcpy(NameStr(*result), s, len);
5761

5862
PG_RETURN_NAME(result);

src/backend/utils/adt/varchar.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,9 @@ bpchar_name(PG_FUNCTION_ARGS)
371371
len = VARSIZE_ANY_EXHDR(s);
372372
s_data = VARDATA_ANY(s);
373373

374-
/* Truncate to max length for a Name */
374+
/* Truncate oversize input */
375375
if (len >= NAMEDATALEN)
376-
len = NAMEDATALEN - 1;
376+
len = pg_mbcliplen(s_data, len, NAMEDATALEN - 1);
377377

378378
/* Remove trailing blanks */
379379
while (len > 0)
@@ -383,16 +383,10 @@ bpchar_name(PG_FUNCTION_ARGS)
383383
len--;
384384
}
385385

386-
result = (NameData *) palloc(NAMEDATALEN);
386+
/* We use palloc0 here to ensure result is zero-padded */
387+
result = (Name) palloc0(NAMEDATALEN);
387388
memcpy(NameStr(*result), s_data, len);
388389

389-
/* Now null pad to full length... */
390-
while (len < NAMEDATALEN)
391-
{
392-
*(NameStr(*result) + len) = '\0';
393-
len++;
394-
}
395-
396390
PG_RETURN_NAME(result);
397391
}
398392

src/backend/utils/adt/varlena.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,18 +2145,12 @@ text_name(PG_FUNCTION_ARGS)
21452145

21462146
/* Truncate oversize input */
21472147
if (len >= NAMEDATALEN)
2148-
len = NAMEDATALEN - 1;
2148+
len = pg_mbcliplen(VARDATA_ANY(s), len, NAMEDATALEN - 1);
21492149

2150-
result = (Name) palloc(NAMEDATALEN);
2150+
/* We use palloc0 here to ensure result is zero-padded */
2151+
result = (Name) palloc0(NAMEDATALEN);
21512152
memcpy(NameStr(*result), VARDATA_ANY(s), len);
21522153

2153-
/* now null pad to full length... */
2154-
while (len < NAMEDATALEN)
2155-
{
2156-
*(NameStr(*result) + len) = '\0';
2157-
len++;
2158-
}
2159-
21602154
PG_RETURN_NAME(result);
21612155
}
21622156

0 commit comments

Comments
 (0)