func_odbc: acf_odbc_read() and cli_odbc_read() unicode support
authorBoris P. Korzun <drtr0jan@yandex.ru>
Wed, 28 Aug 2019 10:07:13 +0000 (20:07 +1000)
committerBoris P. Korzun <drtr0jan@yandex.ru>
Sat, 14 Sep 2019 11:53:25 +0000 (21:53 +1000)
Added ast_odbc_ast_str_SQLGetData() considers SQL_DESC_OCTET_LENGTH
column attribute for correct allocating the buffer.

ASTERISK-28497 #close

Change-Id: I50e86c8a277996f13d4a4b9b318ece0d60b279bf

funcs/func_odbc.c

index 126a339..f9fa971 100644 (file)
@@ -920,15 +920,17 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
 
                        if (y == 0) {
                                char colname[256];
-                               SQLULEN maxcol = 0;
+                               SQLLEN octetlength = 0;
 
-                               res = SQLDescribeCol(stmt, x + 1, (unsigned char *)colname, sizeof(colname), &collength, NULL, &maxcol, NULL, NULL);
-                               ast_debug(3, "Got collength of %d and maxcol of %d for column '%s' (offset %d)\n", (int)collength, (int)maxcol, colname, x);
+                               res = SQLDescribeCol(stmt, x + 1, (unsigned char *)colname, sizeof(colname), &collength, NULL, NULL, NULL, NULL);
+                               ast_debug(3, "Got collength of %d for column '%s' (offset %d)\n", (int)collength, colname, x);
                                if (((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) || collength == 0) {
                                        snprintf(colname, sizeof(colname), "field%d", x);
                                }
 
-                               ast_str_make_space(&coldata, maxcol + 1);
+                               SQLColAttribute(stmt, x + 1, SQL_DESC_OCTET_LENGTH, NULL, 0, NULL, &octetlength);
+
+                               ast_str_make_space(&coldata, octetlength + 1);
 
                                if (ast_str_strlen(colnames)) {
                                        ast_str_append(&colnames, 0, ",");
@@ -1498,10 +1500,9 @@ static char *cli_odbc_read(struct ast_cli_entry *e, int cmd, struct ast_cli_args
                SQLHSTMT stmt;
                int rows = 0, res, x;
                SQLSMALLINT colcount = 0, collength;
-               SQLLEN indicator;
+               SQLLEN indicator, octetlength;
                struct ast_str *coldata = ast_str_thread_get(&coldata_buf, 16);
                char colname[256];
-               SQLULEN maxcol;
 
                if (!coldata) {
                        AST_RWLIST_UNLOCK(&queries);
@@ -1560,14 +1561,15 @@ static char *cli_odbc_read(struct ast_cli_entry *e, int cmd, struct ast_cli_args
                        }
                        for (;;) {
                                for (x = 0; x < colcount; x++) {
-                                       maxcol = 0;
-
-                                       res = SQLDescribeCol(stmt, x + 1, (unsigned char *)colname, sizeof(colname), &collength, NULL, &maxcol, NULL, NULL);
+                                       res = SQLDescribeCol(stmt, x + 1, (unsigned char *)colname, sizeof(colname), &collength, NULL, NULL, NULL, NULL);
                                        if (((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) || collength == 0) {
                                                snprintf(colname, sizeof(colname), "field%d", x);
                                        }
 
-                                       res = ast_odbc_ast_str_SQLGetData(&coldata, maxcol, stmt, x + 1, SQL_CHAR, &indicator);
+                                       octetlength = 0;
+                                       SQLColAttribute(stmt, x + 1, SQL_DESC_OCTET_LENGTH, NULL, 0, NULL, &octetlength);
+
+                                       res = ast_odbc_ast_str_SQLGetData(&coldata, octetlength + 1, stmt, x + 1, SQL_CHAR, &indicator);
                                        if (indicator == SQL_NULL_DATA) {
                                                ast_str_set(&coldata, 0, "(nil)");
                                                res = SQL_SUCCESS;