mirror of
https://github.com/postgres/postgres.git
synced 2025-06-11 20:28:21 +03:00
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
This commit is contained in:
@ -3193,7 +3193,7 @@ retcomposite(PG_FUNCTION_ARGS)
|
|||||||
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
||||||
|
|
||||||
/* total number of tuples to be returned */
|
/* total number of tuples to be returned */
|
||||||
funcctx->max_calls = PG_GETARG_UINT32(0);
|
funcctx->max_calls = PG_GETARG_INT32(0);
|
||||||
|
|
||||||
/* Build a tuple descriptor for our result type */
|
/* Build a tuple descriptor for our result type */
|
||||||
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
||||||
|
@ -999,10 +999,26 @@ ascii(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
chr (PG_FUNCTION_ARGS)
|
chr (PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
uint32 cvalue = PG_GETARG_UINT32(0);
|
int32 arg = PG_GETARG_INT32(0);
|
||||||
|
uint32 cvalue;
|
||||||
text *result;
|
text *result;
|
||||||
int encoding = GetDatabaseEncoding();
|
int encoding = GetDatabaseEncoding();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error out on arguments that make no sense or that we can't validly
|
||||||
|
* represent in the encoding.
|
||||||
|
*/
|
||||||
|
if (arg < 0)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
|
errmsg("character number must be positive")));
|
||||||
|
else if (arg == 0)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||||
|
errmsg("null character not permitted")));
|
||||||
|
|
||||||
|
cvalue = arg;
|
||||||
|
|
||||||
if (encoding == PG_UTF8 && cvalue > 127)
|
if (encoding == PG_UTF8 && cvalue > 127)
|
||||||
{
|
{
|
||||||
/* for Unicode we treat the argument as a code point */
|
/* for Unicode we treat the argument as a code point */
|
||||||
@ -1017,7 +1033,7 @@ chr (PG_FUNCTION_ARGS)
|
|||||||
if (cvalue > 0x0010ffff)
|
if (cvalue > 0x0010ffff)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||||
errmsg("requested character too large for encoding: %d",
|
errmsg("requested character too large for encoding: %u",
|
||||||
cvalue)));
|
cvalue)));
|
||||||
|
|
||||||
if (cvalue > 0xffff)
|
if (cvalue > 0xffff)
|
||||||
@ -1058,28 +1074,19 @@ chr (PG_FUNCTION_ARGS)
|
|||||||
if (!pg_utf8_islegal(wch, bytes))
|
if (!pg_utf8_islegal(wch, bytes))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||||
errmsg("requested character not valid for encoding: %d",
|
errmsg("requested character not valid for encoding: %u",
|
||||||
cvalue)));
|
cvalue)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool is_mb;
|
bool is_mb;
|
||||||
|
|
||||||
/*
|
|
||||||
* Error out on arguments that make no sense or that we can't validly
|
|
||||||
* represent in the encoding.
|
|
||||||
*/
|
|
||||||
if (cvalue == 0)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
|
||||||
errmsg("null character not permitted")));
|
|
||||||
|
|
||||||
is_mb = pg_encoding_max_length(encoding) > 1;
|
is_mb = pg_encoding_max_length(encoding) > 1;
|
||||||
|
|
||||||
if ((is_mb && (cvalue > 127)) || (!is_mb && (cvalue > 255)))
|
if ((is_mb && (cvalue > 127)) || (!is_mb && (cvalue > 255)))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||||
errmsg("requested character too large for encoding: %d",
|
errmsg("requested character too large for encoding: %u",
|
||||||
cvalue)));
|
cvalue)));
|
||||||
|
|
||||||
result = (text *) palloc(VARHDRSZ + 1);
|
result = (text *) palloc(VARHDRSZ + 1);
|
||||||
|
Reference in New Issue
Block a user