From a17d8f30868ed5f4d2c159fc00fe8c54730a8b0a Mon Sep 17 00:00:00 2001 From: Bogdan Pintea Date: Wed, 11 Mar 2020 20:42:32 +0100 Subject: [PATCH 1/2] fix overrun when converting a c-string to interval When converting a C-string to a wide string, the conversion function 0-terminates the output. However, the allocated destination buffer lacked the space for the terminator. This commit fixes that. --- driver/convert.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/driver/convert.c b/driver/convert.c index f5270f2a..d9a36d35 100644 --- a/driver/convert.c +++ b/driver/convert.c @@ -4495,7 +4495,9 @@ static SQLRETURN c2sql_str2interval(esodbc_rec_st *arec, esodbc_rec_st *irec, INFOH(stmt, "translation buffer too small (%zu < %lld), " "allocation needed.", sizeof(wbuff)/sizeof(wbuff[0]), (size_t)octet_len); - wptr = malloc(octet_len * sizeof(SQLWCHAR)); + /* 0-term is most of the time not counted in input str and + * ascii_c2w() writes it -> always allocate space for it */ + wptr = malloc((octet_len + 1) * sizeof(SQLWCHAR)); if (! wptr) { ERRNH(stmt, "OOM for %lld x SQLWCHAR", octet_len); RET_HDIAGS(stmt, SQL_STATE_HY001); @@ -4514,6 +4516,8 @@ static SQLRETURN c2sql_str2interval(esodbc_rec_st *arec, esodbc_rec_st *irec, } /* should only happen on too short input string */ RET_HDIAGS(stmt, SQL_STATE_22018); + } else { + assert(ret <= octet_len + 1); /* no overrun */ } wstr.str = wptr; wstr.cnt = (size_t)octet_len; From 4c3c717b95ca32a90c64ed66bd4f8a4f623cf489 Mon Sep 17 00:00:00 2001 From: Bogdan Pintea Date: Wed, 11 Mar 2020 20:53:30 +0100 Subject: [PATCH 2/2] fix catalog setting The API function provides the byte count for the wide string name of the catalog, not the character count, as so far implemented. This commit fixes the lenght handling. --- driver/connect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/driver/connect.c b/driver/connect.c index 7201c123..e102e2e6 100644 --- a/driver/connect.c +++ b/driver/connect.c @@ -3127,7 +3127,7 @@ static SQLRETURN check_catalog_name(esodbc_dbc_st *dbc, SQLWCHAR *name, if (len < 0) { catalog.cnt = wcslen(name); } else { - catalog.cnt = (size_t)len; + catalog.cnt = ((size_t)len)/sizeof(SQLWCHAR); } if (! EQ_WSTR(&dbc->catalog, &catalog)) { if (! dbc->catalog.cnt) { @@ -3281,7 +3281,7 @@ SQLRETURN EsSQLSetConnectAttrW( case SQL_ATTR_CURRENT_CATALOG: INFOH(dbc, "setting current catalog to: `" LWPDL "`.", /* string should be 0-term'd */ - 0 <= StringLength ? StringLength : SHRT_MAX, + 0 <= StringLength ? StringLength/sizeof(SQLWCHAR) : SHRT_MAX, (SQLWCHAR *)Value); return check_catalog_name(dbc, (SQLWCHAR *)Value, StringLength);