diff --git a/src/qli/compile.cpp b/src/qli/compile.cpp index 7e4e6231f5..709dcd8b1e 100644 --- a/src/qli/compile.cpp +++ b/src/qli/compile.cpp @@ -34,6 +34,7 @@ #include "../qli/forma_proto.h" #include "../qli/meta_proto.h" #include "../jrd/dsc_proto.h" +#include "../jrd/align.h" const USHORT PROMPT_LENGTH = 80; @@ -114,8 +115,10 @@ void CMP_alloc_temp(qli_nod* node) if (node->nod_desc.dsc_address) return; - qli_str* string = (qli_str*) ALLOCDV(type_str, node->nod_desc.dsc_length); - node->nod_desc.dsc_address = (UCHAR *) string->str_data; + qli_str* string = (qli_str*) ALLOCDV(type_str, node->nod_desc.dsc_length + + type_alignments[node->nod_desc.dsc_dtype]); + node->nod_desc.dsc_address = (UCHAR *) FB_ALIGN((FB_UINT64)(U_IPTR)(string->str_data), type_alignments[node->nod_desc.dsc_dtype]); + QLI_validate_desc(node->nod_desc); } @@ -428,6 +431,7 @@ static qli_nod* compile_edit( qli_nod* node, qli_req* request) node->nod_desc.dsc_dtype = dtype_blob; node->nod_desc.dsc_length = 8; node->nod_desc.dsc_address = (UCHAR *) & node->nod_arg[e_edt_id1]; + QLI_validate_desc(node->nod_desc); return node; } @@ -663,6 +667,7 @@ static qli_nod* compile_expression( qli_nod* node, qli_req* request, bool intern case nod_variable: field = (qli_fld*) node->nod_arg[e_fld_field]; node->nod_desc.dsc_address = field->fld_data; + QLI_validate_desc(node->nod_desc); make_descriptor(node, &node->nod_desc); if (internal_flag) { @@ -1121,6 +1126,7 @@ static qli_nod* compile_prompt( qli_nod* node) node->nod_desc.dsc_dtype = dtype_varying; node->nod_desc.dsc_length = prompt_length; node->nod_desc.dsc_address = (UCHAR *) string->str_data; + QLI_validate_desc(node->nod_desc); return node; } diff --git a/src/qli/dtr.cpp b/src/qli/dtr.cpp index 4366e529bb..4456cc1245 100644 --- a/src/qli/dtr.cpp +++ b/src/qli/dtr.cpp @@ -54,6 +54,7 @@ #include "../jrd/perf_proto.h" #include "../include/fb_exception.h" #include "../common/utils_proto.h" +#include "../jrd/align.h" using MsgFormat::SafeArg; @@ -662,3 +663,14 @@ static bool yes_no(USHORT number, const TEXT* arg1) } } +#ifdef DEV_BUILD +void QLI_validate_desc(const dsc* d) +{ + fb_assert(d->dsc_dtype > dtype_unknown); + fb_assert(d->dsc_dtype < DTYPE_TYPE_MAX); + ULONG addr = (ULONG) (U_IPTR) (d->dsc_address); // safely ignore higher bits even if present + USHORT ta = type_alignments[d->dsc_dtype]; + if (ta > 1) + fb_assert((addr & (ta - 1)) == 0); +} +#endif diff --git a/src/qli/dtr.h b/src/qli/dtr.h index 1e2fbc41f2..cc47bf2540 100644 --- a/src/qli/dtr.h +++ b/src/qli/dtr.h @@ -536,5 +536,12 @@ EXTERN qli_req* QLI_requests; // Requests in statement #include "../qli/all_proto.h" +#ifdef DEV_BUILD +void QLI_validate_desc(const dsc*); +#else +inline void QLI_validate_desc(const dsc*) { } +#endif +inline void QLI_validate_desc(const dsc& d) { QLI_validate_desc(&d); } + #endif // QLI_DTR_H diff --git a/src/qli/eval.cpp b/src/qli/eval.cpp index 04eff096c4..a5dddf1394 100644 --- a/src/qli/eval.cpp +++ b/src/qli/eval.cpp @@ -335,6 +335,7 @@ dsc* EVAL_parameter(qli_par* parameter) } desc->dsc_address = message->msg_buffer + parameter->par_offset; + QLI_validate_desc(desc); return desc; } diff --git a/src/qli/exe.cpp b/src/qli/exe.cpp index cd77b0ab76..ef66930794 100644 --- a/src/qli/exe.cpp +++ b/src/qli/exe.cpp @@ -1063,6 +1063,7 @@ static void map_data( qli_msg* message) { dsc* desc = ¶meter->par_desc; desc->dsc_address = message->msg_buffer + parameter->par_offset; + QLI_validate_desc(desc); qli_par* missing_parameter = parameter->par_missing; if (missing_parameter) { USHORT* missing_flag = (USHORT*) (message->msg_buffer + diff --git a/src/qli/expand.cpp b/src/qli/expand.cpp index 42990b1599..d0be6e230e 100644 --- a/src/qli/expand.cpp +++ b/src/qli/expand.cpp @@ -2758,6 +2758,7 @@ static qli_nod* possible_literal(qli_syntax* input, constant->con_desc.dsc_dtype = dtype_text; constant->con_desc.dsc_length = l; constant->con_desc.dsc_address = constant->con_data; + QLI_validate_desc(constant->con_desc); TEXT* p = (TEXT*) constant->con_data; const TEXT* q = name->nam_string; diff --git a/src/qli/format.cpp b/src/qli/format.cpp index 780faab52c..3f14119812 100644 --- a/src/qli/format.cpp +++ b/src/qli/format.cpp @@ -401,6 +401,7 @@ qli_nod* FMT_list(qli_nod* list) value->nod_desc.dsc_length = name->sym_length; value->nod_desc.dsc_address = (UCHAR *) name->sym_string; } + QLI_validate_desc(value->nod_desc); column = MAX(column, value->nod_desc.dsc_length); new_item->itm_picture = PIC_analyze(0, &value->nod_desc); } diff --git a/src/qli/gener.cpp b/src/qli/gener.cpp index da44670ebc..567ff9af10 100644 --- a/src/qli/gener.cpp +++ b/src/qli/gener.cpp @@ -498,6 +498,7 @@ static void gen_any( qli_nod* node, qli_req* request) desc.dsc_scale = 0; desc.dsc_sub_type = 0; desc.dsc_address = (UCHAR*) &value; + QLI_validate_desc(desc); STUFF(blr_assignment); value = TRUE; @@ -1094,6 +1095,7 @@ static void gen_for( qli_nod* node, qli_req* request) desc.dsc_scale = 0; desc.dsc_sub_type = 0; desc.dsc_address = (UCHAR*) &value; + QLI_validate_desc(desc); STUFF(blr_assignment); value = FALSE; @@ -1497,8 +1499,8 @@ static void gen_request( qli_req* request) STUFF(message->msg_number); STUFF_WORD(message->msg_parameter); - qli_str* string = (qli_str*) ALLOCDV(type_str, message->msg_length); - message->msg_buffer = (UCHAR*) string->str_data; + qli_str* string = (qli_str*) ALLOCDV(type_str, message->msg_length + DOUBLE_ALIGN - 1); + message->msg_buffer = (UCHAR*) FB_ALIGN((FB_UINT64)(U_IPTR)(string->str_data), DOUBLE_ALIGN); for (param = message->msg_parameters; param; param = param->par_next) { gen_descriptor(¶m->par_desc, request); diff --git a/src/qli/meta.epp b/src/qli/meta.epp index 43ee587ee2..3f58837644 100644 --- a/src/qli/meta.epp +++ b/src/qli/meta.epp @@ -3251,6 +3251,7 @@ static qli_syntax* parse_blr( UCHAR ** ptr, qli_symbol* symbol) constant->con_desc.dsc_scale = scale; constant->con_desc.dsc_length = length; constant->con_desc.dsc_address = p = constant->con_data; + QLI_validate_desc(constant->con_desc); if (dtype == dtype_text) while (l--) *p++ = BLR_BYTE; diff --git a/src/qli/mov.cpp b/src/qli/mov.cpp index ec86c3310d..ac410eb273 100644 --- a/src/qli/mov.cpp +++ b/src/qli/mov.cpp @@ -348,6 +348,7 @@ double MOVQ_date_to_double(const dsc* desc) temp_desc.dsc_sub_type = 0; date = temp; temp_desc.dsc_address = (UCHAR *) date; + QLI_validate_desc(temp_desc); MOVQ_move(desc, &temp_desc); } @@ -695,6 +696,7 @@ int MOVQ_get_string(const dsc* desc, const TEXT** address, vary* temp, temp_desc.dsc_scale = 0; temp_desc.dsc_dtype = dtype_varying; temp_desc.dsc_sub_type = ttype_ascii; + QLI_validate_desc(temp_desc); MOVQ_move(desc, &temp_desc); *address = temp->vary_string; @@ -1075,6 +1077,7 @@ static void sql_date_to_text( SLONG date[1], DSC * to) desc.dsc_dtype = dtype_text; desc.dsc_scale = 0; desc.dsc_sub_type = ttype_ascii; + QLI_validate_desc(desc); MOVQ_move(&desc, to); } @@ -1114,6 +1117,7 @@ static void sql_time_to_text( ULONG date[1], DSC * to) desc.dsc_dtype = dtype_text; desc.dsc_scale = 0; desc.dsc_sub_type = ttype_ascii; + QLI_validate_desc(desc); MOVQ_move(&desc, to); } @@ -1155,6 +1159,7 @@ static void timestamp_to_text( SLONG date[2], DSC * to) desc.dsc_dtype = dtype_text; desc.dsc_scale = 0; desc.dsc_sub_type = ttype_ascii; + QLI_validate_desc(desc); MOVQ_move(&desc, to); } @@ -1246,6 +1251,7 @@ static void numeric_to_text(const dsc* from, dsc* to) intermediate.dsc_scale = scale; intermediate.dsc_sub_type = 0; intermediate.dsc_address = (UCHAR *) &n; + QLI_validate_desc(intermediate); MOVQ_move(from, &intermediate); diff --git a/src/qli/parse.cpp b/src/qli/parse.cpp index 515f910cd7..e64a4a6725 100644 --- a/src/qli/parse.cpp +++ b/src/qli/parse.cpp @@ -591,6 +591,7 @@ static qli_const* make_numeric_constant(const TEXT* string, USHORT length) while (--length) *p++ = *string++; } + QLI_validate_desc(constant->con_desc); return constant; } @@ -2207,6 +2208,7 @@ static qli_const* parse_literal(void) constant = (qli_const*) ALLOCDV(type_con, l); constant->con_desc.dsc_dtype = dtype_text; UCHAR* p = constant->con_desc.dsc_address = constant->con_data; + QLI_validate_desc(constant->con_desc); if (constant->con_desc.dsc_length = l) do { *p++ = *q++; diff --git a/src/qli/picstr.cpp b/src/qli/picstr.cpp index 1fa47074ad..e718db63ae 100644 --- a/src/qli/picstr.cpp +++ b/src/qli/picstr.cpp @@ -575,6 +575,7 @@ static void edit_date( const dsc* desc, pics* picture, TEXT** output) temp_desc.dsc_sub_type = 0; temp_desc.dsc_length = sizeof(date); temp_desc.dsc_address = (UCHAR *) date; + QLI_validate_desc(temp_desc); MOVQ_move(desc, &temp_desc); tm times;