From e206227017f399c183b37f751ff4215b78011fa2 Mon Sep 17 00:00:00 2001 From: Popa Marius Adrian Date: Tue, 20 Oct 2026 17:18:09 +0300 Subject: [PATCH 1/2] Fix #9222: Reset ttype_dynamic to ttype_none in DsqlDmlRequest::metadataToFormat Restore the ttype_dynamic -> ttype_none reset for text items in DSQL message metadata (originally in DsqlRequest::parseMetadata before #8145) so clients that encode SQL_TEXT/SQL_VARYING with plain blr_text/blr_varying do not fail with string right truncation or malformed string on NONE/OCTETS columns over multi-byte connection charsets. --- src/dsql/DsqlRequests.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/dsql/DsqlRequests.cpp b/src/dsql/DsqlRequests.cpp index 438a83a23e3..a50320ece62 100644 --- a/src/dsql/DsqlRequests.cpp +++ b/src/dsql/DsqlRequests.cpp @@ -858,6 +858,15 @@ void DsqlDmlRequest::metadataToFormat(Firebird::IMessageMetadata* meta, const ds const auto textType = CSetId(meta->getCharSet(&st, index)); checkD(&st); desc.setTextType(textType); + + // ASF: Older than 2.5 engine hasn't validating strings in DSQL. After this has been + // implemented in 2.5, selecting a NONE column with UTF-8 attachment charset started + // failing. The real problem is that the client encodes SQL_TEXT/SQL_VARYING using + // blr_text/blr_varying (i.e. with the connection charset). I'm reseting the charset + // here at the server as a way to make older (and not yet changed) client work + // correctly. + if (desc.isText() && desc.getTextType() == ttype_dynamic) + desc.setTextType(ttype_none); desc.dsc_address = (UCHAR*)(IPTR) meta->getOffset(&st, index); checkD(&st); ++assigned; From d5b7692071da2627224ddbcd146d31ac6e207a61 Mon Sep 17 00:00:00 2001 From: Popa Marius Adrian Date: Tue, 20 Oct 2026 23:01:22 +0300 Subject: [PATCH 2/2] Use oldFormat text type when textType is ttype_dynamic before setTextType --- src/dsql/DsqlRequests.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/dsql/DsqlRequests.cpp b/src/dsql/DsqlRequests.cpp index a50320ece62..56a63030b37 100644 --- a/src/dsql/DsqlRequests.cpp +++ b/src/dsql/DsqlRequests.cpp @@ -855,18 +855,11 @@ void DsqlDmlRequest::metadataToFormat(Firebird::IMessageMetadata* meta, const ds checkD(&st); desc.dsc_sub_type = meta->getSubType(&st, index); checkD(&st); - const auto textType = CSetId(meta->getCharSet(&st, index)); + TTypeId textType = CSetId(meta->getCharSet(&st, index)); checkD(&st); + if (desc.isText() && textType == ttype_dynamic) + textType = oldFormat->fmt_desc[param->par_parameter].getTextType(); desc.setTextType(textType); - - // ASF: Older than 2.5 engine hasn't validating strings in DSQL. After this has been - // implemented in 2.5, selecting a NONE column with UTF-8 attachment charset started - // failing. The real problem is that the client encodes SQL_TEXT/SQL_VARYING using - // blr_text/blr_varying (i.e. with the connection charset). I'm reseting the charset - // here at the server as a way to make older (and not yet changed) client work - // correctly. - if (desc.isText() && desc.getTextType() == ttype_dynamic) - desc.setTextType(ttype_none); desc.dsc_address = (UCHAR*)(IPTR) meta->getOffset(&st, index); checkD(&st); ++assigned;