mirror of
https://github.com/postgres/postgres.git
synced 2026-04-07 10:17:24 -04:00
Bounds-check access to TupleDescAttr with an Assert.
The second argument to TupleDescAttr should always be at least zero and less than natts; otherwise, we index outside of the attribute array. Assert that this is the case. Various violations, or possible violations, of this rule that are currently in the tree are actually harmless, because while we do call TupleDescAttr() before verifying that the argument is within range, we don't actually dereference it unless the argument was within range all along. Nonetheless, the Assert means we should be more careful, so tidy up accordingly. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: http://postgr.es/m/CA+TgmoacixUZVvi00hOjk_d9B4iYKswWP1gNqQ8Vfray-AcOCA@mail.gmail.com
This commit is contained in:
parent
e2f289e5b9
commit
c98ad086ad
4 changed files with 26 additions and 16 deletions
|
|
@ -246,10 +246,11 @@ CreateTupleDescCopy(TupleDesc tupdesc)
|
|||
|
||||
desc = CreateTemplateTupleDesc(tupdesc->natts);
|
||||
|
||||
/* Flat-copy the attribute array */
|
||||
memcpy(TupleDescAttr(desc, 0),
|
||||
TupleDescAttr(tupdesc, 0),
|
||||
desc->natts * sizeof(FormData_pg_attribute));
|
||||
/* Flat-copy the attribute array (unless there are no attributes) */
|
||||
if (desc->natts > 0)
|
||||
memcpy(TupleDescAttr(desc, 0),
|
||||
TupleDescAttr(tupdesc, 0),
|
||||
desc->natts * sizeof(FormData_pg_attribute));
|
||||
|
||||
/*
|
||||
* Since we're not copying constraints and defaults, clear fields
|
||||
|
|
@ -294,10 +295,11 @@ CreateTupleDescTruncatedCopy(TupleDesc tupdesc, int natts)
|
|||
|
||||
desc = CreateTemplateTupleDesc(natts);
|
||||
|
||||
/* Flat-copy the attribute array */
|
||||
memcpy(TupleDescAttr(desc, 0),
|
||||
TupleDescAttr(tupdesc, 0),
|
||||
desc->natts * sizeof(FormData_pg_attribute));
|
||||
/* Flat-copy the attribute array (unless there are no attributes) */
|
||||
if (desc->natts > 0)
|
||||
memcpy(TupleDescAttr(desc, 0),
|
||||
TupleDescAttr(tupdesc, 0),
|
||||
desc->natts * sizeof(FormData_pg_attribute));
|
||||
|
||||
/*
|
||||
* Since we're not copying constraints and defaults, clear fields
|
||||
|
|
@ -339,10 +341,11 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
|
|||
|
||||
desc = CreateTemplateTupleDesc(tupdesc->natts);
|
||||
|
||||
/* Flat-copy the attribute array */
|
||||
memcpy(TupleDescAttr(desc, 0),
|
||||
TupleDescAttr(tupdesc, 0),
|
||||
desc->natts * sizeof(FormData_pg_attribute));
|
||||
/* Flat-copy the attribute array (unless there are no attributes) */
|
||||
if (desc->natts > 0)
|
||||
memcpy(TupleDescAttr(desc, 0),
|
||||
TupleDescAttr(tupdesc, 0),
|
||||
desc->natts * sizeof(FormData_pg_attribute));
|
||||
|
||||
for (i = 0; i < desc->natts; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -179,6 +179,8 @@ TupleDescAttr(TupleDesc tupdesc, int i)
|
|||
{
|
||||
FormData_pg_attribute *attrs = TupleDescAttrAddress(tupdesc);
|
||||
|
||||
Assert(i >= 0 && i < tupdesc->natts);
|
||||
|
||||
return &attrs[i];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1093,7 +1093,7 @@ plperl_build_tuple_result(HV *perlhash, TupleDesc td)
|
|||
SV *val = HeVAL(he);
|
||||
char *key = hek2cstr(he);
|
||||
int attn = SPI_fnumber(td, key);
|
||||
Form_pg_attribute attr = TupleDescAttr(td, attn - 1);
|
||||
Form_pg_attribute attr;
|
||||
|
||||
if (attn == SPI_ERROR_NOATTRIBUTE)
|
||||
ereport(ERROR,
|
||||
|
|
@ -1106,6 +1106,7 @@ plperl_build_tuple_result(HV *perlhash, TupleDesc td)
|
|||
errmsg("cannot set system attribute \"%s\"",
|
||||
key)));
|
||||
|
||||
attr = TupleDescAttr(td, attn - 1);
|
||||
values[attn - 1] = plperl_sv_to_datum(val,
|
||||
attr->atttypid,
|
||||
attr->atttypmod,
|
||||
|
|
@ -1799,7 +1800,7 @@ plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup)
|
|||
char *key = hek2cstr(he);
|
||||
SV *val = HeVAL(he);
|
||||
int attn = SPI_fnumber(tupdesc, key);
|
||||
Form_pg_attribute attr = TupleDescAttr(tupdesc, attn - 1);
|
||||
Form_pg_attribute attr;
|
||||
|
||||
if (attn == SPI_ERROR_NOATTRIBUTE)
|
||||
ereport(ERROR,
|
||||
|
|
@ -1811,6 +1812,8 @@ plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup)
|
|||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot set system attribute \"%s\"",
|
||||
key)));
|
||||
|
||||
attr = TupleDescAttr(tupdesc, attn - 1);
|
||||
if (attr->attgenerated)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
|
|
|
|||
|
|
@ -3401,7 +3401,7 @@ exec_stmt_return_next(PLpgSQL_execstate *estate,
|
|||
PLpgSQL_var *var = (PLpgSQL_var *) retvar;
|
||||
Datum retval = var->value;
|
||||
bool isNull = var->isnull;
|
||||
Form_pg_attribute attr = TupleDescAttr(tupdesc, 0);
|
||||
Form_pg_attribute attr;
|
||||
|
||||
if (natts != 1)
|
||||
ereport(ERROR,
|
||||
|
|
@ -3414,6 +3414,7 @@ exec_stmt_return_next(PLpgSQL_execstate *estate,
|
|||
var->datatype->typlen);
|
||||
|
||||
/* coerce type if needed */
|
||||
attr = TupleDescAttr(tupdesc, 0);
|
||||
retval = exec_cast_value(estate,
|
||||
retval,
|
||||
&isNull,
|
||||
|
|
@ -3532,7 +3533,7 @@ exec_stmt_return_next(PLpgSQL_execstate *estate,
|
|||
}
|
||||
else
|
||||
{
|
||||
Form_pg_attribute attr = TupleDescAttr(tupdesc, 0);
|
||||
Form_pg_attribute attr;
|
||||
|
||||
/* Simple scalar result */
|
||||
if (natts != 1)
|
||||
|
|
@ -3541,6 +3542,7 @@ exec_stmt_return_next(PLpgSQL_execstate *estate,
|
|||
errmsg("wrong result type supplied in RETURN NEXT")));
|
||||
|
||||
/* coerce type if needed */
|
||||
attr = TupleDescAttr(tupdesc, 0);
|
||||
retval = exec_cast_value(estate,
|
||||
retval,
|
||||
&isNull,
|
||||
|
|
|
|||
Loading…
Reference in a new issue