From 0041555fcd57be9bb133c03fdb1fc0f417baf805 Mon Sep 17 00:00:00 2001 From: "HOME5\\dmitr" Date: Wed, 29 Nov 2023 23:37:59 +0300 Subject: [PATCH 1/3] Correct construction of scalar_array_desc structure It is a fix for issue #7892. Additional verifications of array dimension were added. Work with memory was improved. --- src/jrd/fun.epp | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/jrd/fun.epp b/src/jrd/fun.epp index 786f65d90ab..572d26027dc 100644 --- a/src/jrd/fun.epp +++ b/src/jrd/fun.epp @@ -292,8 +292,7 @@ enum UdfError static SSHORT blob_get_segment(blb*, UCHAR*, USHORT, USHORT*); static void blob_put_segment(blb*, const UCHAR*, USHORT); static SLONG blob_lseek(blb*, USHORT, SLONG); -static ULONG get_scalar_array(thread_db* tdbb, const Parameter*, DSC*, - scalar_array_desc*, UCharStack&); +static scalar_array_desc* get_scalar_array(thread_db* tdbb, const Parameter*, DSC*, UCharStack&); static void invoke(thread_db* tdbb, const Function* function, const Parameter* return_ptr, @@ -478,8 +477,10 @@ void FUN_evaluate(thread_db* tdbb, const Function* function, const NestValueArra } else if (parameter->prm_fun_mechanism == FUN_scalar_array) { - length = get_scalar_array(tdbb, parameter, input, (scalar_array_desc*) temp_ptr, - array_stack); + scalar_array_desc* const scalar_array = get_scalar_array(tdbb, parameter, input, array_stack); + + *arg_ptr++ = (UDF_ARG)(IPTR)scalar_array; + continue; } else { @@ -976,11 +977,10 @@ static SSHORT blob_get_segment(blb* blob, UCHAR* buffer, USHORT length, USHORT* } -static ULONG get_scalar_array(thread_db* tdbb, - const Parameter* arg, - DSC* value, - scalar_array_desc* scalar_desc, - UCharStack& stack) +static scalar_array_desc* get_scalar_array(thread_db* const tdbb, + const Parameter* const arg, + DSC* const value, + UCharStack& stack) { /************************************** * @@ -1007,6 +1007,14 @@ static ULONG get_scalar_array(thread_db* tdbb, blob->BLB_get_data(tdbb, data, array_desc->iad_total_length); const USHORT dimensions = array_desc->iad_dimensions; + if (dimensions == 0) // todo: correct this message + status_exception::raise(Arg::Gds(isc_random) << "Array dimension can not be zero."); + + static_assert(MAX_ARRAY_DIMENSIONS == 16, ""); + + if (MAX_ARRAY_DIMENSIONS < dimensions) + status_exception::raise(Arg::Gds(isc_random) << "Array has more than 16 dimensions."); + // Convert array, if necessary dsc to = arg->prm_desc; @@ -1031,11 +1039,22 @@ static ULONG get_scalar_array(thread_db* tdbb, } // Fill out the scalar array descriptor + size_t const scalar_array_desc_sz + = sizeof(scalar_array_desc) + (dimensions - 1u) * sizeof(scalar_array_desc::sad_repeat); + + AutoPtr scalar_array_desc_mem(FB_NEW_POOL(pool) UCHAR[scalar_array_desc_sz]); + + scalar_array_desc* const scalar_desc = (scalar_array_desc*) scalar_array_desc_mem.get(); + + // check a pointer align + fb_assert((((uintptr_t)scalar_desc) % sizeof(void*)) == 0); + + // scalar_desc->sad_rpt has one element + static_assert(sizeof(scalar_desc->sad_rpt) == sizeof(scalar_desc->sad_rpt[0]), ""); scalar_desc->sad_desc = arg->prm_desc; scalar_desc->sad_desc.dsc_address = data; scalar_desc->sad_dimensions = dimensions; - stack.push(data.release()); const Ods::InternalArrayDesc::iad_repeat* tail1 = array_desc->iad_rpt; scalar_array_desc::sad_repeat* tail2 = scalar_desc->sad_rpt; @@ -1046,8 +1065,13 @@ static ULONG get_scalar_array(thread_db* tdbb, tail2->sad_lower = tail1->iad_lower; } - return static_cast(sizeof(scalar_array_desc) + - (dimensions - 1u) * sizeof(scalar_array_desc::sad_repeat)); + stack.push(data.get()); + data.release(); + + stack.push(scalar_array_desc_mem.get()); + scalar_array_desc_mem.release(); + + return scalar_desc; } From 40436bcf244dc2af87d276d369a0a0b6d1daf452 Mon Sep 17 00:00:00 2001 From: "HOME5\\dmitr" Date: Thu, 30 Nov 2023 11:03:53 +0300 Subject: [PATCH 2/3] Calculation of function->fun_temp_length takes into account FUN_scalar_array It is the second part of fix for issue #7892 --- src/jrd/Function.epp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/jrd/Function.epp b/src/jrd/Function.epp index cc54bdbd19e..cf3eec623f6 100644 --- a/src/jrd/Function.epp +++ b/src/jrd/Function.epp @@ -360,8 +360,19 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT if (parameter->prm_desc.dsc_dtype == dtype_cstring) parameter->prm_desc.dsc_length++; - length += (parameter->prm_desc.dsc_dtype == dtype_blob) ? - sizeof(udf_blob) : FB_ALIGN(parameter->prm_desc.dsc_length, FB_DOUBLE_ALIGN); + if (parameter->prm_fun_mechanism == FUN_scalar_array) + { + //scalar_array_desc is always allocated separately. See get_scalar_array in fun.epp + } + else + if (parameter->prm_desc.dsc_dtype == dtype_blob) + { + length += sizeof(udf_blob); + } + else + { + length += FB_ALIGN(parameter->prm_desc.dsc_length, FB_DOUBLE_ALIGN); + } count = MAX(count, size_t(Y.RDB$ARGUMENT_POSITION)); } From d10c2a6464477724d71a6d0e6b5f8be28e69b7ae Mon Sep 17 00:00:00 2001 From: "HOME5\\dmitr" Date: Thu, 30 Nov 2023 18:09:07 +0300 Subject: [PATCH 3/3] C++ normalization --- src/jrd/fun.epp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jrd/fun.epp b/src/jrd/fun.epp index 572d26027dc..c7a4131d5b2 100644 --- a/src/jrd/fun.epp +++ b/src/jrd/fun.epp @@ -479,7 +479,7 @@ void FUN_evaluate(thread_db* tdbb, const Function* function, const NestValueArra { scalar_array_desc* const scalar_array = get_scalar_array(tdbb, parameter, input, array_stack); - *arg_ptr++ = (UDF_ARG)(IPTR)scalar_array; + *arg_ptr++ = reinterpret_cast(scalar_array); continue; } else