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

Commit d3b97d1

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 73cc7d3 commit d3b97d1

File tree

3 files changed

+14
-22
lines changed

3 files changed

+14
-22
lines changed

src/backend/utils/adt/name.c

+7-3
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

+4-10
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,9 @@ bpchar_name(PG_FUNCTION_ARGS)
372372
len = VARSIZE_ANY_EXHDR(s);
373373
s_data = VARDATA_ANY(s);
374374

375-
/* Truncate to max length for a Name */
375+
/* Truncate oversize input */
376376
if (len >= NAMEDATALEN)
377-
len = NAMEDATALEN - 1;
377+
len = pg_mbcliplen(s_data, len, NAMEDATALEN - 1);
378378

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

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

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

src/backend/utils/adt/varlena.c

+3-9
Original file line numberDiff line numberDiff line change
@@ -2256,18 +2256,12 @@ text_name(PG_FUNCTION_ARGS)
22562256

22572257
/* Truncate oversize input */
22582258
if (len >= NAMEDATALEN)
2259-
len = NAMEDATALEN - 1;
2259+
len = pg_mbcliplen(VARDATA_ANY(s), len, NAMEDATALEN - 1);
22602260

2261-
result = (Name) palloc(NAMEDATALEN);
2261+
/* We use palloc0 here to ensure result is zero-padded */
2262+
result = (Name) palloc0(NAMEDATALEN);
22622263
memcpy(NameStr(*result), VARDATA_ANY(s), len);
22632264

2264-
/* now null pad to full length... */
2265-
while (len < NAMEDATALEN)
2266-
{
2267-
*(NameStr(*result) + len) = '\0';
2268-
len++;
2269-
}
2270-
22712265
PG_RETURN_NAME(result);
22722266
}
22732267

0 commit comments

Comments
 (0)