From 2ce77e7cdf726019ab8bc67d01b0d58dbc8f1577 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Fri, 10 May 2024 10:19:42 -0400 Subject: [PATCH] tds5_process_dyn_result2: Don't trust Sybase w/blob params. As of ASE 16.0, Sybase servers have started allowing dynamic query (prepared statement) declarations with IMAGE or (N)TEXT parameters. However, subsequent attempts to instantiate these queries have been failing with message 3805, "The token datastream length was not correct." In such cases, switch on dynamic query emulation (as already needed for older Sybase versions that immediately reject these declarations) and explicitly discard column information to avoid misconstruing the status of subsequent queries that yield no row results. Signed-off-by: Aaron M. Ucko --- src/tds/token.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/tds/token.c b/src/tds/token.c index 1cafae71cc..f3e6739a15 100644 --- a/src/tds/token.c +++ b/src/tds/token.c @@ -2687,6 +2687,7 @@ tds5_process_dyn_result2(TDSSOCKET * tds) unsigned int col, num_cols; TDSCOLUMN *curcol; TDSPARAMINFO *info; + TDSDYNAMIC *dyn = NULL; CHECK_TDS_EXTRA(tds); @@ -2697,7 +2698,7 @@ tds5_process_dyn_result2(TDSSOCKET * tds) if ((info = tds_alloc_results(num_cols)) == NULL) return TDS_FAIL; if (tds->cur_dyn) { - TDSDYNAMIC *dyn = tds->cur_dyn; + dyn = tds->cur_dyn; tds_free_param_results(dyn->res_info); dyn->res_info = info; } else { @@ -2740,6 +2741,29 @@ tds5_process_dyn_result2(TDSSOCKET * tds) curcol->column_varint_size); tdsdump_log(TDS_DBG_INFO1, "\tcolsize=%d prec=%d scale=%d\n", curcol->column_size, curcol->column_prec, curcol->column_scale); + + /* + * As of ASE 16.0, Sybase servers have started allowing + * dynamic query (prepared statement) declarations with + * IMAGE or (N)TEXT parameters. However, subsequent + * attempts to instantiate these queries have been failing + * with message 3805, "The token datastream length was not + * correct." In such cases, switch on dynamic query + * emulation (as already needed for older Sybase versions + * that immediately reject these declarations) and + * explicitly discard column information to avoid + * misconstruing the status of subsequent queries that + * yield no row results. + */ + if (dyn != NULL && is_blob_col(curcol)) { + dyn->emulated = 1; + tds_dynamic_deallocated(tds->conn, tds->cur_dyn); + dyn = NULL; + } + } + + if (tds->cur_dyn != NULL && tds->cur_dyn->emulated) { + tds_set_current_results(tds, NULL); } return tds_alloc_row(info);