Skip to content

Commit b4d64a6

Browse files
committed
Remove our dependencies on MB_CUR_MAX in favor of believing that
pg_database_encoding_max_length() predicts the maximum character length returned by wchar2char(). Per Hiroshi Inoue, MB_CUR_MAX isn't usable on Windows because we allow encoding = UTF8 when the locale says differently; and getting rid of it seems a good idea on general principles because it narrows our dependence on libc's locale API just a little bit more. Also install a check for overflow of the buffer size computation.
1 parent 5f3724d commit b4d64a6

File tree

1 file changed

+34
-10
lines changed

1 file changed

+34
-10
lines changed

src/backend/utils/adt/formatting.c

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* -----------------------------------------------------------------------
22
* formatting.c
33
*
4-
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.151 2008/12/01 17:11:18 heikki Exp $
4+
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.152 2008/12/15 14:55:50 tgl Exp $
55
*
66
*
77
* Portions Copyright (c) 1999-2008, PostgreSQL Global Development Group
@@ -1461,7 +1461,14 @@ str_tolower(const char *buff, size_t nbytes)
14611461
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
14621462
{
14631463
wchar_t *workspace;
1464-
int curr_char = 0;
1464+
size_t curr_char;
1465+
size_t result_size;
1466+
1467+
/* Overflow paranoia */
1468+
if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
1469+
ereport(ERROR,
1470+
(errcode(ERRCODE_OUT_OF_MEMORY),
1471+
errmsg("out of memory")));
14651472

14661473
/* Output workspace cannot have more codes than input bytes */
14671474
workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
@@ -1472,9 +1479,10 @@ str_tolower(const char *buff, size_t nbytes)
14721479
workspace[curr_char] = towlower(workspace[curr_char]);
14731480

14741481
/* Make result large enough; case change might change number of bytes */
1475-
result = palloc(curr_char * MB_CUR_MAX + 1);
1482+
result_size = curr_char * pg_database_encoding_max_length() + 1;
1483+
result = palloc(result_size);
14761484

1477-
wchar2char(result, workspace, curr_char * MB_CUR_MAX + 1);
1485+
wchar2char(result, workspace, result_size);
14781486
pfree(workspace);
14791487
}
14801488
else
@@ -1509,7 +1517,14 @@ str_toupper(const char *buff, size_t nbytes)
15091517
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
15101518
{
15111519
wchar_t *workspace;
1512-
int curr_char = 0;
1520+
size_t curr_char;
1521+
size_t result_size;
1522+
1523+
/* Overflow paranoia */
1524+
if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
1525+
ereport(ERROR,
1526+
(errcode(ERRCODE_OUT_OF_MEMORY),
1527+
errmsg("out of memory")));
15131528

15141529
/* Output workspace cannot have more codes than input bytes */
15151530
workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
@@ -1520,9 +1535,10 @@ str_toupper(const char *buff, size_t nbytes)
15201535
workspace[curr_char] = towupper(workspace[curr_char]);
15211536

15221537
/* Make result large enough; case change might change number of bytes */
1523-
result = palloc(curr_char * MB_CUR_MAX + 1);
1538+
result_size = curr_char * pg_database_encoding_max_length() + 1;
1539+
result = palloc(result_size);
15241540

1525-
wchar2char(result, workspace, curr_char * MB_CUR_MAX + 1);
1541+
wchar2char(result, workspace, result_size);
15261542
pfree(workspace);
15271543
}
15281544
else
@@ -1558,7 +1574,14 @@ str_initcap(const char *buff, size_t nbytes)
15581574
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
15591575
{
15601576
wchar_t *workspace;
1561-
int curr_char = 0;
1577+
size_t curr_char;
1578+
size_t result_size;
1579+
1580+
/* Overflow paranoia */
1581+
if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
1582+
ereport(ERROR,
1583+
(errcode(ERRCODE_OUT_OF_MEMORY),
1584+
errmsg("out of memory")));
15621585

15631586
/* Output workspace cannot have more codes than input bytes */
15641587
workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
@@ -1575,9 +1598,10 @@ str_initcap(const char *buff, size_t nbytes)
15751598
}
15761599

15771600
/* Make result large enough; case change might change number of bytes */
1578-
result = palloc(curr_char * MB_CUR_MAX + 1);
1601+
result_size = curr_char * pg_database_encoding_max_length() + 1;
1602+
result = palloc(result_size);
15791603

1580-
wchar2char(result, workspace, curr_char * MB_CUR_MAX + 1);
1604+
wchar2char(result, workspace, result_size);
15811605
pfree(workspace);
15821606
}
15831607
else

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy