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

Commit e9e63b7

Browse files
committed
Fix inappropriate uses of PG_GETARG_UINT32()
The chr() function used PG_GETARG_UINT32() even though the argument is declared as (signed) integer. As a result, you can pass negative arguments to this function and it internally interprets them as positive. Ultimately ends up being harmless, but it seems wrong, so fix this and rearrange the internal error checking a bit to accommodate this. Another case was in the documentation, where example code used PG_GETARG_UINT32() with an argument declared as signed integer. Reviewed-by: Nathan Bossart <bossartn@amazon.com> Discussion: https://www.postgresql.org/message-id/flat/7e43869b-d412-8f81-30a3-809783edc9a3%40enterprisedb.com
1 parent d4596a2 commit e9e63b7

File tree

2 files changed

+21
-14
lines changed

2 files changed

+21
-14
lines changed

doc/src/sgml/xfunc.sgml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3193,7 +3193,7 @@ retcomposite(PG_FUNCTION_ARGS)
31933193
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
31943194

31953195
/* total number of tuples to be returned */
3196-
funcctx->max_calls = PG_GETARG_UINT32(0);
3196+
funcctx->max_calls = PG_GETARG_INT32(0);
31973197

31983198
/* Build a tuple descriptor for our result type */
31993199
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)

src/backend/utils/adt/oracle_compat.c

+20-13
Original file line numberDiff line numberDiff line change
@@ -999,10 +999,26 @@ ascii(PG_FUNCTION_ARGS)
999999
Datum
10001000
chr (PG_FUNCTION_ARGS)
10011001
{
1002-
uint32 cvalue = PG_GETARG_UINT32(0);
1002+
int32 arg = PG_GETARG_INT32(0);
1003+
uint32 cvalue;
10031004
text *result;
10041005
int encoding = GetDatabaseEncoding();
10051006

1007+
/*
1008+
* Error out on arguments that make no sense or that we can't validly
1009+
* represent in the encoding.
1010+
*/
1011+
if (arg < 0)
1012+
ereport(ERROR,
1013+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1014+
errmsg("character number must be positive")));
1015+
else if (arg == 0)
1016+
ereport(ERROR,
1017+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1018+
errmsg("null character not permitted")));
1019+
1020+
cvalue = arg;
1021+
10061022
if (encoding == PG_UTF8 && cvalue > 127)
10071023
{
10081024
/* for Unicode we treat the argument as a code point */
@@ -1017,7 +1033,7 @@ chr (PG_FUNCTION_ARGS)
10171033
if (cvalue > 0x0010ffff)
10181034
ereport(ERROR,
10191035
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1020-
errmsg("requested character too large for encoding: %d",
1036+
errmsg("requested character too large for encoding: %u",
10211037
cvalue)));
10221038

10231039
if (cvalue > 0xffff)
@@ -1058,28 +1074,19 @@ chr (PG_FUNCTION_ARGS)
10581074
if (!pg_utf8_islegal(wch, bytes))
10591075
ereport(ERROR,
10601076
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1061-
errmsg("requested character not valid for encoding: %d",
1077+
errmsg("requested character not valid for encoding: %u",
10621078
cvalue)));
10631079
}
10641080
else
10651081
{
10661082
bool is_mb;
10671083

1068-
/*
1069-
* Error out on arguments that make no sense or that we can't validly
1070-
* represent in the encoding.
1071-
*/
1072-
if (cvalue == 0)
1073-
ereport(ERROR,
1074-
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1075-
errmsg("null character not permitted")));
1076-
10771084
is_mb = pg_encoding_max_length(encoding) > 1;
10781085

10791086
if ((is_mb && (cvalue > 127)) || (!is_mb && (cvalue > 255)))
10801087
ereport(ERROR,
10811088
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1082-
errmsg("requested character too large for encoding: %d",
1089+
errmsg("requested character too large for encoding: %u",
10831090
cvalue)));
10841091

10851092
result = (text *) palloc(VARHDRSZ + 1);

0 commit comments

Comments
 (0)