From eb6492f41e27e04a8d414b1cd186b009289bcfbb Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Wed, 8 May 2024 16:21:30 -0400 Subject: [PATCH 01/49] Fix compilation errors in single-threaded builds. * Conditionally stub out the tests that require threading (as of 1.4.12) and don't yet have such logic. * include/freetds/thread.h: Never try to add extra checks around stubs. --- include/freetds/thread.h | 2 +- src/odbc/unittests/qn.c | 10 +++++++++- src/tds/unittests/freeze.c | 8 ++++++++ src/tds/unittests/log_elision.c | 8 ++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/freetds/thread.h b/include/freetds/thread.h index 508dc01436..979adaae80 100644 --- a/include/freetds/thread.h +++ b/include/freetds/thread.h @@ -331,7 +331,7 @@ static inline int tds_thread_is_current(tds_thread_id th) # define tds_cond_init tds_raw_cond_init # define tds_cond_destroy tds_raw_cond_destroy # define tds_cond_signal tds_raw_cond_signal -# if !ENABLE_EXTRA_CHECKS +# if !ENABLE_EXTRA_CHECKS || !defined(TDS_HAVE_MUTEX) # define TDS_MUTEX_INITIALIZER TDS_RAW_MUTEX_INITIALIZER # define tds_mutex tds_raw_mutex # define tds_mutex_lock tds_raw_mutex_lock diff --git a/src/odbc/unittests/qn.c b/src/odbc/unittests/qn.c index cf344e5ad3..8249c07ae0 100644 --- a/src/odbc/unittests/qn.c +++ b/src/odbc/unittests/qn.c @@ -7,6 +7,7 @@ /* test query notifications */ +#ifdef TDS_HAVE_MUTEX #define SWAP(t,a,b) do { t xyz = a; a = b; b = xyz; } while(0) #define SWAP_CONN() do { SWAP(HENV,env,odbc_env); SWAP(HDBC,dbc,odbc_conn); SWAP(HSTMT,stmt,odbc_stmt);} while(0) @@ -131,4 +132,11 @@ main(void) return 0; } - +#else +int main(int argc, char *argv[]) +{ + printf("Not possible for this platform.\n"); + odbc_test_skipped(); + return 0; +} +#endif diff --git a/src/tds/unittests/freeze.c b/src/tds/unittests/freeze.c index d64e9063c2..db37072ce9 100644 --- a/src/tds/unittests/freeze.c +++ b/src/tds/unittests/freeze.c @@ -31,6 +31,7 @@ #include +#ifdef TDS_HAVE_MUTEX #ifdef _WIN32 #define SHUT_WR SD_SEND #endif @@ -483,3 +484,10 @@ main(void) return 0; } +#else /* !TDS_HAVE_MUTEX */ +int main(int argc, char *argv[]) +{ + printf("Not possible for this platform.\n"); + return 0; // 77? +} +#endif diff --git a/src/tds/unittests/log_elision.c b/src/tds/unittests/log_elision.c index 1d737f9494..4818f07131 100644 --- a/src/tds/unittests/log_elision.c +++ b/src/tds/unittests/log_elision.c @@ -29,6 +29,7 @@ #include #endif /* HAVE_UNISTD_H */ +#ifdef TDS_HAVE_MUTEX enum { LOOP = 100, THREADS = 3, @@ -142,3 +143,10 @@ main(void) return 0; } +#else /* !TDS_HAVE_MUTEX */ +int main(int argc, char *argv[]) +{ + printf("Not possible for this platform.\n"); + return 0; // 77? +} +#endif From 12dd4573b8c8a5bd332555ab58f541e0fcecca3b Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Wed, 8 May 2024 16:49:13 -0400 Subject: [PATCH 02/49] Address Windows build errors, most config-dependent. * In the absence of an external SQLGetPrivateProfileString, fail the build only when expecting to use an external driver manager, and expose tds_SQLGetPrivateProfileString to the odbc "connect" unit test. Don't let that test attempt to use SQLGetPrivateProfileStringW even in Unicode builds. * src/odbc/win*.c: Accommodate static builds, with no hinstFreeTDS; in particular, never attempt to show FreeTDS dialog boxes there. * src/utils/unittests/challenge.c: #include to ensure the availability of strcasecmp. --- src/odbc/connectparams.c | 15 +++++++++++---- src/odbc/unittests/connect.c | 17 ++++++++++++----- src/odbc/winlogin.c | 4 ++++ src/odbc/winsetup.c | 8 +++++++- src/utils/unittests/challenge.c | 1 + 5 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c index 46e2ce20c6..5999af3e17 100644 --- a/src/odbc/connectparams.c +++ b/src/odbc/connectparams.c @@ -95,8 +95,12 @@ static FILE *tdoGetIniFileName(void); * expect see tdoGetIniFileName(). * */ -static int SQLGetPrivateProfileString(LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer, - LPCSTR pszFileName); +#ifndef _WIN32 +static +#endif +int SQLGetPrivateProfileString(LPCSTR pszSection, LPCSTR pszEntry, + LPCSTR pszDefault, LPSTR pRetBuffer, + int nRetBuffer, LPCSTR pszFileName); #endif #if defined(FILENAME_MAX) && FILENAME_MAX < 512 @@ -556,7 +560,7 @@ odbc_build_connect_string(TDS_ERRS *errs, TDS_PARSED_PARAM *params, char **out) #if !HAVE_SQLGETPRIVATEPROFILESTRING -#ifdef _WIN32 +#if defined(_WIN32) && !defined(TDS_NO_DM) # error There is something wrong in configuration... #endif @@ -584,7 +588,10 @@ tdoParseProfile(const char *option, const char *value, void *param) return true; } -static int +#ifndef _WIN32 +static +#endif +int SQLGetPrivateProfileString(LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer, LPCSTR pszFileName) { diff --git a/src/odbc/unittests/connect.c b/src/odbc/unittests/connect.c index 96ea32342e..0034353cd4 100644 --- a/src/odbc/unittests/connect.c +++ b/src/odbc/unittests/connect.c @@ -12,18 +12,25 @@ init_connect(void) #ifdef _WIN32 #include +#undef SQLGetPrivateProfileString +#if !HAVE_SQLGETPRIVATEPROFILESTRING +# define SQLGetPrivateProfileString tds_SQLGetPrivateProfileString +int tds_SQLGetPrivateProfileString(LPCSTR pszSection, LPCSTR pszEntry, + LPCSTR pszDefault, LPSTR pRetBuffer, + int nRetBuffer, LPCSTR pszFileName); +#endif static char *entry = NULL; static char * get_entry(const char *key) { - static TCHAR buf[256]; - + static char buf[256]; + entry = NULL; - if (SQLGetPrivateProfileString((LPCTSTR) T(odbc_server), (LPCTSTR) T(key), TEXT(""), - buf, TDS_VECTOR_SIZE(buf), TEXT("odbc.ini")) > 0) - entry = C(buf); + if (SQLGetPrivateProfileString(odbc_server, key, "", buf, + TDS_VECTOR_SIZE(buf), "odbc.ini") > 0) + entry = buf; return entry; } diff --git a/src/odbc/winlogin.c b/src/odbc/winlogin.c index 5c14cbe2d0..f074c2b534 100644 --- a/src/odbc/winlogin.c +++ b/src/odbc/winlogin.c @@ -173,5 +173,9 @@ LoginDlgProc(HWND hDlg, UINT message, WPARAM wParam, /* */ bool get_login_info(HWND hwndParent, TDSLOGIN * login) { +#ifdef DLL_EXPORT return !!DialogBoxParam(hinstFreeTDS, MAKEINTRESOURCE(IDD_LOGIN), hwndParent, (DLGPROC) LoginDlgProc, (LPARAM) login); +#else + return false; +#endif } diff --git a/src/odbc/winsetup.c b/src/odbc/winsetup.c index d711ffe6c5..8ec5ad4d9a 100644 --- a/src/odbc/winsetup.c +++ b/src/odbc/winsetup.c @@ -318,7 +318,12 @@ ConfigDSN(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszAttribut /* Maybe allow the user to edit it */ if (hwndParent && fRequest != ODBC_REMOVE_DSN) { INT_PTR result; +#ifdef DLL_EXPORT result = DialogBoxParam(hinstFreeTDS, MAKEINTRESOURCE(IDD_DSN), hwndParent, (DLGPROC) DSNDlgProc, (LPARAM) di); +#else + result = -1; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); +#endif if (result < 0) { DWORD errorcode = GetLastError(); char buf[1000]; @@ -428,6 +433,7 @@ check_installer_errors(void) return SQL_SUCCEEDED(ret); } +#ifdef DLL_EXPORT /** * Allow install using regsvr32 */ @@ -476,4 +482,4 @@ DllUnregisterServer(void) return SELFREG_E_CLASS; return S_OK; } - +#endif /* DLL_EXPORT */ diff --git a/src/utils/unittests/challenge.c b/src/utils/unittests/challenge.c index cfe38bac46..4607a8ada5 100644 --- a/src/utils/unittests/challenge.c +++ b/src/utils/unittests/challenge.c @@ -35,6 +35,7 @@ #endif #include "tds_sysdep_public.h" +#include #include #include #include From a0145126d03bb12a2d5a17b746bace3b0fa6ed5f Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Thu, 9 May 2024 11:32:51 -0400 Subject: [PATCH 03/49] Predefine _FREETDS_LIBRARY_SOURCE for all library code. This distinction will initially be useful only for ctlib and dblib, but applying it across the board may avoid possible confusion if it turns out to be useful elsewhere too. --- src/ctlib/CMakeLists.txt | 2 ++ src/ctlib/Makefile.am | 2 +- src/dblib/CMakeLists.txt | 2 ++ src/dblib/Makefile.am | 2 +- src/odbc/CMakeLists.txt | 2 ++ src/odbc/Makefile.am | 3 ++- src/replacements/CMakeLists.txt | 1 + src/replacements/Makefile.am | 3 ++- src/tds/CMakeLists.txt | 1 + src/tds/Makefile.am | 3 ++- src/utils/CMakeLists.txt | 1 + src/utils/Makefile.am | 2 +- 12 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/ctlib/CMakeLists.txt b/src/ctlib/CMakeLists.txt index e83b0b1a42..b775b849ca 100644 --- a/src/ctlib/CMakeLists.txt +++ b/src/ctlib/CMakeLists.txt @@ -12,11 +12,13 @@ add_library(ct SHARED ) target_compile_definitions(ct PUBLIC DLL_EXPORT=1) +target_compile_definitions(ct PRIVATE _FREETDS_LIBRARY_SOURCE) target_link_libraries(ct tds replacements tdsutils ${lib_NETWORK} ${lib_BASE}) add_library(ct-static STATIC ct.c cs.c blk.c ctutil.c ) +target_compile_definitions(ct-static PRIVATE _FREETDS_LIBRARY_SOURCE) # See http://www.cmake.org/Wiki/CMake_FAQ#How_do_I_make_my_shared_and_static_libraries_have_the_same_root_name.2C_but_different_suffixes.3F SET_TARGET_PROPERTIES(ct-static PROPERTIES OUTPUT_NAME ${static_lib_name}) SET_TARGET_PROPERTIES(ct PROPERTIES CLEAN_DIRECT_OUTPUT 1) diff --git a/src/ctlib/Makefile.am b/src/ctlib/Makefile.am index 0db8f67a22..57a4c65e85 100644 --- a/src/ctlib/Makefile.am +++ b/src/ctlib/Makefile.am @@ -1,5 +1,5 @@ SUBDIRS = . unittests -AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include -D_FREETDS_LIBRARY_SOURCE lib_LTLIBRARIES = libct.la libct_la_SOURCES= ct.c cs.c blk.c ctutil.c ct_small_checks.c ct_large_checks.c ct_checks.h diff --git a/src/dblib/CMakeLists.txt b/src/dblib/CMakeLists.txt index 5f1766f45f..2888c071a0 100644 --- a/src/dblib/CMakeLists.txt +++ b/src/dblib/CMakeLists.txt @@ -10,12 +10,14 @@ add_library(sybdb SHARED ${win_SRCS} ) target_compile_definitions(sybdb PUBLIC DLL_EXPORT=1) +target_compile_definitions(sybdb PRIVATE _FREETDS_LIBRARY_SOURCE) add_dependencies(sybdb encodings_h) target_link_libraries(sybdb tds replacements tdsutils ${lib_NETWORK} ${lib_BASE}) add_library(db-lib STATIC dblib.c dbutil.c rpc.c bcp.c xact.c dbpivot.c buffering.h ) +target_compile_definitions(db-lib PRIVATE _FREETDS_LIBRARY_SOURCE) add_dependencies(db-lib encodings_h) target_link_libraries(db-lib tds replacements tdsutils ${lib_NETWORK} ${lib_BASE}) diff --git a/src/dblib/Makefile.am b/src/dblib/Makefile.am index fb454f31ac..3fd31634ea 100644 --- a/src/dblib/Makefile.am +++ b/src/dblib/Makefile.am @@ -1,5 +1,5 @@ SUBDIRS = . unittests -AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include -D_FREETDS_LIBRARY_SOURCE lib_LTLIBRARIES = libsybdb.la libsybdb_la_SOURCES= dblib.c dbutil.c rpc.c bcp.c xact.c dbpivot.c diff --git a/src/odbc/CMakeLists.txt b/src/odbc/CMakeLists.txt index ec8eaadd03..de656b94c9 100644 --- a/src/odbc/CMakeLists.txt +++ b/src/odbc/CMakeLists.txt @@ -37,6 +37,7 @@ add_library(tdsodbc SHARED target_include_directories(tdsodbc PUBLIC "${CMAKE_CURRENT_BINARY_DIR}") add_dependencies(tdsodbc odbc_exports_h encodings_h) target_compile_definitions(tdsodbc PUBLIC DLL_EXPORT=1) +target_compile_definitions(tdsodbc PRIVATE _FREETDS_LIBRARY_SOURCE) # TODO libiconv, odbcinstlib and other dynamics target_link_libraries(tdsodbc tds replacements tdsutils ${libs} ${lib_NETWORK} ${lib_BASE}) @@ -52,6 +53,7 @@ add_library(tdsodbc_static STATIC ) target_include_directories(tdsodbc_static PUBLIC "${CMAKE_CURRENT_BINARY_DIR}") add_dependencies(tdsodbc_static odbc_exports_h encodings_h) +target_compile_definitions(tdsodbc_static PRIVATE _FREETDS_LIBRARY_SOURCE) if (NOT WIN32) set_target_properties(tdsodbc_static PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() diff --git a/src/odbc/Makefile.am b/src/odbc/Makefile.am index 8a1a007029..7e7443a2fc 100644 --- a/src/odbc/Makefile.am +++ b/src/odbc/Makefile.am @@ -1,5 +1,6 @@ SUBDIRS = . unittests -AM_CPPFLAGS = -I$(top_srcdir)/include $(ODBC_INC) +AM_CPPFLAGS = -I$(top_srcdir)/include $(ODBC_INC) \ + -D_FREETDS_LIBRARY_SOURCE lib_LTLIBRARIES = libtdsodbc.la ##EXTRA_LTLIBRARIES = libtdsodbc.la diff --git a/src/replacements/CMakeLists.txt b/src/replacements/CMakeLists.txt index 48d7e53634..6223495d0b 100644 --- a/src/replacements/CMakeLists.txt +++ b/src/replacements/CMakeLists.txt @@ -35,6 +35,7 @@ add_library(replacements STATIC getaddrinfo.c ${add_SRCS} ) +target_compile_definitions(replacements PRIVATE _FREETDS_LIBRARY_SOURCE) target_include_directories(replacements PUBLIC "${CMAKE_CURRENT_BINARY_DIR}") add_dependencies(replacements iconv_charsets_h) if (NOT WIN32) diff --git a/src/replacements/Makefile.am b/src/replacements/Makefile.am index 467c147c3f..56fceeadf1 100644 --- a/src/replacements/Makefile.am +++ b/src/replacements/Makefile.am @@ -1,6 +1,7 @@ NULL = SUBDIRS = . unittests -AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src/replacements +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src/replacements \ + -D_FREETDS_LIBRARY_SOURCE noinst_LTLIBRARIES = libreplacements.la libreplacements_la_SOURCES = \ iconv.c \ diff --git a/src/tds/CMakeLists.txt b/src/tds/CMakeLists.txt index 134a30cb8b..d36c87d447 100644 --- a/src/tds/CMakeLists.txt +++ b/src/tds/CMakeLists.txt @@ -60,6 +60,7 @@ add_library(tds STATIC ${add_SRCS} ) target_include_directories(tds PUBLIC "${CMAKE_CURRENT_BINARY_DIR}") +target_compile_definitions(tds PRIVATE _FREETDS_LIBRARY_SOURCE) add_dependencies(tds encodings_h) if (NOT WIN32) set_target_properties(tds PROPERTIES POSITION_INDEPENDENT_CODE ON) diff --git a/src/tds/Makefile.am b/src/tds/Makefile.am index ab55a7874f..e8acb8e660 100644 --- a/src/tds/Makefile.am +++ b/src/tds/Makefile.am @@ -1,6 +1,7 @@ NULL= SUBDIRS = . unittests -AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include \ + -D_FREETDS_LIBRARY_SOURCE noinst_LTLIBRARIES = libtds.la libtds_la_SOURCES = \ diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index c91650740d..3c1ef20e0e 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(tdsutils STATIC path.c ${add_SRCS} ) +target_compile_definitions(tdsutils PRIVATE _FREETDS_LIBRARY_SOURCE) if (NOT WIN32) set_target_properties(tdsutils PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am index 48329c746e..58137ff149 100644 --- a/src/utils/Makefile.am +++ b/src/utils/Makefile.am @@ -1,6 +1,6 @@ NULL = SUBDIRS = . unittests -AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include -D_FREETDS_LIBRARY_SOURCE noinst_LTLIBRARIES = libtdsutils.la libtdsutils_la_SOURCES = \ md4.c \ From 8fce34742cf7828e8f15faca7e221b3abe0ccd58 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Thu, 9 May 2024 11:55:40 -0400 Subject: [PATCH 04/49] Accommodate potential mass renaming of non-ODBC symbols. * #include from several more internal headers to facilitate injecting most renaming through there; some of these headers consult HAVE_* macros anyway. * Account for possible renaming of cs_dt_crack (not just aliasing it to ..._v2), dbopen, tdsdump_dump_buf, and tdsdump_log; for the latter two, change the underlying functions' names to tdsdump_do_... modulo possible mass renaming. --- include/cspublic.h | 9 +++++++-- include/freetds/bool.h | 2 ++ include/freetds/sysdep_private.h | 2 ++ include/freetds/tds.h | 10 ++++++---- include/freetds/utils/des.h | 2 ++ include/freetds/utils/dlist.h | 2 ++ include/freetds/utils/hmac_md5.h | 2 ++ include/freetds/utils/md4.h | 2 ++ include/freetds/utils/md5.h | 2 ++ include/sybdb.h | 3 +++ src/ctlib/cs.c | 2 -- src/dblib/dbopen.c | 4 ---- src/odbc/odbc_export.pl | 6 +++--- src/tds/log.c | 4 ++-- 14 files changed, 35 insertions(+), 17 deletions(-) diff --git a/include/cspublic.h b/include/cspublic.h index 38d6fb7fa5..17ec3cb5f9 100644 --- a/include/cspublic.h +++ b/include/cspublic.h @@ -770,10 +770,15 @@ CS_RETCODE cs_ctx_drop(CS_CONTEXT * ctx); CS_RETCODE cs_config(CS_CONTEXT * ctx, CS_INT action, CS_INT property, CS_VOID * buffer, CS_INT buflen, CS_INT * outlen); CS_RETCODE cs_strbuild(CS_CONTEXT * ctx, CS_CHAR * buffer, CS_INT buflen, CS_INT * resultlen, CS_CHAR * text, CS_INT textlen, CS_CHAR * formats, CS_INT formatlen, ...); -#undef cs_dt_crack +#ifndef cs_dt_crack_v2 +# undef cs_dt_crack +#endif CS_RETCODE cs_dt_crack(CS_CONTEXT * ctx, CS_INT datetype, CS_VOID * dateval, CS_DATEREC * daterec); CS_RETCODE cs_dt_crack_v2(CS_CONTEXT * ctx, CS_INT datetype, CS_VOID * dateval, CS_DATEREC * daterec); -#define cs_dt_crack cs_dt_crack_v2 +#ifndef _FREETDS_LIBRARY_SOURCE +# undef cs_dt_crack +# define cs_dt_crack cs_dt_crack_v2 +#endif CS_RETCODE cs_loc_alloc(CS_CONTEXT * ctx, CS_LOCALE ** locptr); CS_RETCODE cs_loc_drop(CS_CONTEXT * ctx, CS_LOCALE * locale); CS_RETCODE cs_locale(CS_CONTEXT * ctx, CS_INT action, CS_LOCALE * locale, CS_INT type, CS_VOID * buffer, CS_INT buflen, diff --git a/include/freetds/bool.h b/include/freetds/bool.h index 59ff11dfc2..53468dd077 100644 --- a/include/freetds/bool.h +++ b/include/freetds/bool.h @@ -20,6 +20,8 @@ #ifndef freetds_bool_h_ #define freetds_bool_h_ +#include + #ifndef __cplusplus #ifdef HAVE_STDBOOL_H diff --git a/include/freetds/sysdep_private.h b/include/freetds/sysdep_private.h index 422d7efa04..ea6b72e030 100644 --- a/include/freetds/sysdep_private.h +++ b/include/freetds/sysdep_private.h @@ -21,6 +21,8 @@ #ifndef _tds_sysdep_private_h_ #define _tds_sysdep_private_h_ +#include + #define TDS_ADDITIONAL_SPACE 16 #ifdef MSG_NOSIGNAL diff --git a/include/freetds/tds.h b/include/freetds/tds.h index deb6321e35..7d5becb88a 100644 --- a/include/freetds/tds.h +++ b/include/freetds/tds.h @@ -1536,10 +1536,12 @@ int tdsdump_isopen(void); int tdsdump_open(const tds_dir_char *filename); #include void tdsdump_close(void); -void tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, const void *buf, size_t length); +void tdsdump_do_dump_buf(const char* file, unsigned int level_line, + const char *msg, const void *buf, size_t length); void tdsdump_col(const TDSCOLUMN *col); #undef tdsdump_log -void tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...) +void tdsdump_do_log(const char* file, unsigned int level_line, + const char *fmt, ...) #if defined(__GNUC__) && __GNUC__ >= 2 #if defined(__MINGW32__) __attribute__ ((__format__ (ms_printf, 3, 4))) @@ -1548,9 +1550,9 @@ void tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ... #endif #endif ; -#define TDSDUMP_LOG_FAST if (TDS_UNLIKELY(tds_write_dump)) tdsdump_log +#define TDSDUMP_LOG_FAST if (TDS_UNLIKELY(tds_write_dump)) tdsdump_do_log #define tdsdump_log TDSDUMP_LOG_FAST -#define TDSDUMP_BUF_FAST if (TDS_UNLIKELY(tds_write_dump)) tdsdump_dump_buf +#define TDSDUMP_BUF_FAST if (TDS_UNLIKELY(tds_write_dump)) tdsdump_do_dump_buf #define tdsdump_dump_buf TDSDUMP_BUF_FAST extern int tds_write_dump; diff --git a/include/freetds/utils/des.h b/include/freetds/utils/des.h index a05a207657..cf63ae6b82 100644 --- a/include/freetds/utils/des.h +++ b/include/freetds/utils/des.h @@ -1,6 +1,8 @@ #ifndef DES_H #define DES_H +#include + #ifdef HAVE_NETTLE #include diff --git a/include/freetds/utils/dlist.h b/include/freetds/utils/dlist.h index 3a4eb7a9b5..2a9c87aa86 100644 --- a/include/freetds/utils/dlist.h +++ b/include/freetds/utils/dlist.h @@ -20,6 +20,8 @@ #ifndef TDS_DLIST_H #define TDS_DLIST_H +#include + typedef struct dlist_ring { struct dlist_ring *next; struct dlist_ring *prev; diff --git a/include/freetds/utils/hmac_md5.h b/include/freetds/utils/hmac_md5.h index 26196ecded..e4be2b5f20 100644 --- a/include/freetds/utils/hmac_md5.h +++ b/include/freetds/utils/hmac_md5.h @@ -20,6 +20,8 @@ #ifndef _hmac_md5_h_ #define _hmac_md5_h_ +#include + #include void hmac_md5(const unsigned char key[16], const unsigned char* data, size_t data_len, diff --git a/include/freetds/utils/md4.h b/include/freetds/utils/md4.h index 23bce53043..91d52e6fac 100644 --- a/include/freetds/utils/md4.h +++ b/include/freetds/utils/md4.h @@ -1,6 +1,8 @@ #ifndef MD4_H #define MD4_H +#include + #ifndef HAVE_NETTLE #include diff --git a/include/freetds/utils/md5.h b/include/freetds/utils/md5.h index 4fb908cbf8..31d16d9095 100644 --- a/include/freetds/utils/md5.h +++ b/include/freetds/utils/md5.h @@ -1,6 +1,8 @@ #ifndef MD5_H #define MD5_H +#include + #ifndef HAVE_NETTLE #include diff --git a/include/sybdb.h b/include/sybdb.h index c9c83674f4..155da47177 100644 --- a/include/sybdb.h +++ b/include/sybdb.h @@ -845,11 +845,14 @@ RETCODE dbpivot(DBPROCESS *dbproc, int nkeys, int *keys, int ncols, int *cols, D DBPIVOT_FUNC dbpivot_lookup_name( const char name[] ); +#ifndef _FREETDS_LIBRARY_SOURCE +#undef dbopen #ifdef MSDBLIB #define dbopen(x,y) tdsdbopen((x),(y), 1) #else #define dbopen(x,y) tdsdbopen((x),(y), 0) #endif +#endif /* fix PHP problem */ #ifdef PHP_SYBASE_DBOPEN diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c index ad89d6130d..8a29bbcba4 100644 --- a/src/ctlib/cs.c +++ b/src/ctlib/cs.c @@ -41,8 +41,6 @@ #include "cspublic.h" #include "ctlib.h" -#undef cs_dt_crack - static CS_INT cs_diag_storemsg(CS_CONTEXT *context, CS_CLIENTMSG *message); static CS_INT cs_diag_clearmsg(CS_CONTEXT *context, CS_INT type); static CS_INT cs_diag_getmsg(CS_CONTEXT *context, CS_INT idx, CS_CLIENTMSG *message); diff --git a/src/dblib/dbopen.c b/src/dblib/dbopen.c index e98dd46178..36b7ddf5dd 100644 --- a/src/dblib/dbopen.c +++ b/src/dblib/dbopen.c @@ -23,10 +23,6 @@ #include #include -#ifdef dbopen -#undef dbopen -#endif - /** * Normally not used. * The function is linked in only if the --enable-sybase-compat configure option is used. diff --git a/src/odbc/odbc_export.pl b/src/odbc/odbc_export.pl index 5e470d5bb3..9a2347ab7b 100644 --- a/src/odbc/odbc_export.pl +++ b/src/odbc/odbc_export.pl @@ -35,7 +35,7 @@ my $params_all = ''; my $pass_aw = ''; my $sep = ''; - my $log = "tdsdump_log(TDS_DBG_FUNC, \"$func("; + my $log = "tdsdump_do_log(TDS_DBG_FUNC, \"$func("; my $log_p = ''; $wide = 1 if $args =~ / WIDE ?$/; $args =~ s/ WIDE ?$//; @@ -104,13 +104,13 @@ SQLWSTR_FREE(); }"; } else { - $log_w =~ s/\btdsdump_log\b/TDSDUMP_LOG_FAST/g; + $log_w =~ s/\btdsdump_do_log\b/TDSDUMP_LOG_FAST/g; } $log =~ s/%ls/%s/g; $log =~ s/STRING\((.*?),(.*?)\)/(const char*) $1/g; - $log =~ s/\btdsdump_log\b/TDSDUMP_LOG_FAST/g; + $log =~ s/\btdsdump_do_log\b/TDSDUMP_LOG_FAST/g; print "#ifdef ENABLE_ODBC_WIDE static SQLRETURN _$func($params_all, int wide); diff --git a/src/tds/log.c b/src/tds/log.c index f54cdedf0a..fa6eb6c71d 100644 --- a/src/tds/log.c +++ b/src/tds/log.c @@ -290,7 +290,7 @@ current_thread_is_excluded(void) * \param length number of bytes in the buffer */ void -tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, const void *buf, size_t length) +tdsdump_do_dump_buf(const char* file, unsigned int level_line, const char *msg, const void *buf, size_t length) { size_t i, j; #define BYTES_PER_LINE 16 @@ -393,7 +393,7 @@ tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, con * \param fmt printf-like format string */ void -tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...) +tdsdump_do_log(const char* file, unsigned int level_line, const char *fmt, ...) { const int debug_lvl = level_line & 15; const int line = level_line >> 4; From 4ef90f3bb6d5116639e14d97838caa7d18e62abe Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Thu, 9 May 2024 14:02:36 -0400 Subject: [PATCH 05/49] {dblib,odbc}/unittests/common.h: Allow FREETDS_SRCDIR overrides. --- src/dblib/unittests/common.h | 2 ++ src/odbc/unittests/common.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/dblib/unittests/common.h b/src/dblib/unittests/common.h index 6532a129c5..eb987f7117 100644 --- a/src/dblib/unittests/common.h +++ b/src/dblib/unittests/common.h @@ -41,7 +41,9 @@ #define EXIT_SUCCESS 0 #endif +#ifndef FREETDS_SRCDIR #define FREETDS_SRCDIR FREETDS_TOPDIR "/src/dblib/unittests" +#endif #if defined(HAVE__SNPRINTF) && !defined(HAVE_SNPRINTF) #define snprintf _snprintf diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h index e3f88434c0..2a5a843cfc 100644 --- a/src/odbc/unittests/common.h +++ b/src/odbc/unittests/common.h @@ -41,7 +41,9 @@ #endif #endif +#ifndef FREETDS_SRCDIR #define FREETDS_SRCDIR FREETDS_TOPDIR "/src/odbc/unittests" +#endif extern HENV odbc_env; extern HDBC odbc_conn; From 893c4903128a416c195a88837d8455a90bf93634 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Thu, 9 May 2024 14:19:34 -0400 Subject: [PATCH 06/49] unit tests: Accommodate using a substitute for . * Introduce a that at baseline simply forwards to . * Include it from */unittests/*.c (even those that didn't include ) and for good measure from dblib/unittests/common.h (which did), as late as possible to avoid losing out to inclusions coming from elsewhere. * Remove all direct inclusion from tests. --- include/freetds/test_assert.h | 1 + src/apps/unittests/defncopy.c | 3 ++- src/ctlib/unittests/all_types.c | 3 ++- src/ctlib/unittests/array_bind.c | 2 ++ src/ctlib/unittests/blk_in.c | 3 ++- src/ctlib/unittests/blk_in2.c | 3 ++- src/ctlib/unittests/blk_out.c | 2 ++ src/ctlib/unittests/cancel.c | 2 ++ src/ctlib/unittests/common.c | 2 ++ src/ctlib/unittests/connect_fail.c | 2 ++ src/ctlib/unittests/cs_config.c | 2 ++ src/ctlib/unittests/cs_convert.c | 3 ++- src/ctlib/unittests/cs_diag.c | 2 ++ src/ctlib/unittests/ct_command.c | 2 ++ src/ctlib/unittests/ct_cursor.c | 2 ++ src/ctlib/unittests/ct_cursors.c | 2 ++ src/ctlib/unittests/ct_diagall.c | 2 ++ src/ctlib/unittests/ct_diagclient.c | 2 ++ src/ctlib/unittests/ct_diagserver.c | 2 ++ src/ctlib/unittests/ct_dynamic.c | 2 ++ src/ctlib/unittests/ct_options.c | 2 ++ src/ctlib/unittests/data.c | 3 ++- src/ctlib/unittests/datafmt.c | 2 ++ src/ctlib/unittests/errors.c | 4 +++- src/ctlib/unittests/get_send_data.c | 2 ++ src/ctlib/unittests/lang_ct_param.c | 2 ++ src/ctlib/unittests/long_binary.c | 2 ++ src/ctlib/unittests/row_count.c | 3 ++- src/ctlib/unittests/rpc_ct_param.c | 2 ++ src/ctlib/unittests/rpc_ct_setparam.c | 2 ++ src/ctlib/unittests/rpc_fail.c | 2 ++ src/ctlib/unittests/t0001.c | 2 ++ src/ctlib/unittests/t0002.c | 2 ++ src/ctlib/unittests/t0003.c | 2 ++ src/ctlib/unittests/t0004.c | 2 ++ src/ctlib/unittests/t0005.c | 2 ++ src/ctlib/unittests/t0007.c | 2 ++ src/ctlib/unittests/t0008.c | 2 ++ src/ctlib/unittests/t0009.c | 2 ++ src/ctlib/unittests/variant.c | 3 ++- src/ctlib/unittests/will_convert.c | 3 ++- src/dblib/unittests/batch_stmt_ins_sel.c | 2 ++ src/dblib/unittests/batch_stmt_ins_upd.c | 2 ++ src/dblib/unittests/bcp.c | 4 ++-- src/dblib/unittests/bcp2.c | 2 +- src/dblib/unittests/bcp_getl.c | 2 ++ src/dblib/unittests/cancel.c | 2 ++ src/dblib/unittests/canquery.c | 2 ++ src/dblib/unittests/colinfo.c | 2 ++ src/dblib/unittests/common.c | 2 ++ src/dblib/unittests/common.h | 3 ++- src/dblib/unittests/dbmorecmds.c | 2 ++ src/dblib/unittests/dbsafestr.c | 2 ++ src/dblib/unittests/done_handling.c | 2 ++ src/dblib/unittests/empty_rowsets.c | 2 ++ src/dblib/unittests/hang.c | 2 ++ src/dblib/unittests/null.c | 2 ++ src/dblib/unittests/null2.c | 2 ++ src/dblib/unittests/numeric.c | 2 ++ src/dblib/unittests/pending.c | 2 ++ src/dblib/unittests/proc_limit.c | 2 ++ src/dblib/unittests/rpc.c | 2 ++ src/dblib/unittests/setnull.c | 2 ++ src/dblib/unittests/spid.c | 2 ++ src/dblib/unittests/string_bind.c | 2 ++ src/dblib/unittests/t0001.c | 2 ++ src/dblib/unittests/t0002.c | 3 ++- src/dblib/unittests/t0003.c | 2 ++ src/dblib/unittests/t0004.c | 2 ++ src/dblib/unittests/t0005.c | 2 ++ src/dblib/unittests/t0006.c | 2 ++ src/dblib/unittests/t0007.c | 2 ++ src/dblib/unittests/t0008.c | 2 ++ src/dblib/unittests/t0009.c | 2 ++ src/dblib/unittests/t0011.c | 2 ++ src/dblib/unittests/t0012.c | 2 ++ src/dblib/unittests/t0013.c | 2 ++ src/dblib/unittests/t0014.c | 2 ++ src/dblib/unittests/t0015.c | 2 ++ src/dblib/unittests/t0016.c | 2 ++ src/dblib/unittests/t0017.c | 3 ++- src/dblib/unittests/t0018.c | 2 ++ src/dblib/unittests/t0019.c | 2 ++ src/dblib/unittests/t0020.c | 2 ++ src/dblib/unittests/t0022.c | 3 ++- src/dblib/unittests/t0023.c | 3 ++- src/dblib/unittests/text_buffer.c | 2 ++ src/dblib/unittests/thread.c | 2 ++ src/dblib/unittests/timeout.c | 2 ++ src/odbc/unittests/all_types.c | 3 ++- src/odbc/unittests/array.c | 3 ++- src/odbc/unittests/array_error.c | 3 ++- src/odbc/unittests/array_out.c | 3 ++- src/odbc/unittests/attributes.c | 2 ++ src/odbc/unittests/base.c | 2 ++ src/odbc/unittests/bcp.c | 3 ++- src/odbc/unittests/binary_test.c | 3 ++- src/odbc/unittests/blob1.c | 3 ++- src/odbc/unittests/c2string.c | 3 ++- src/odbc/unittests/cancel.c | 3 ++- src/odbc/unittests/closestmt.c | 2 ++ src/odbc/unittests/common.c | 3 ++- src/odbc/unittests/compute.c | 3 ++- src/odbc/unittests/connect.c | 2 ++ src/odbc/unittests/connect2.c | 2 ++ src/odbc/unittests/connection_string_parse.c | 3 ++- src/odbc/unittests/const_params.c | 2 ++ src/odbc/unittests/convert_error.c | 2 ++ src/odbc/unittests/copydesc.c | 2 ++ src/odbc/unittests/cursor1.c | 2 ++ src/odbc/unittests/cursor2.c | 2 ++ src/odbc/unittests/cursor3.c | 2 ++ src/odbc/unittests/cursor4.c | 2 ++ src/odbc/unittests/cursor5.c | 2 ++ src/odbc/unittests/cursor6.c | 2 ++ src/odbc/unittests/cursor7.c | 2 ++ src/odbc/unittests/data.c | 3 ++- src/odbc/unittests/date.c | 2 ++ src/odbc/unittests/descrec.c | 2 ++ src/odbc/unittests/describecol.c | 2 ++ src/odbc/unittests/describecol2.c | 2 ++ src/odbc/unittests/earlybind.c | 2 ++ src/odbc/unittests/empty_query.c | 2 ++ src/odbc/unittests/error.c | 2 ++ src/odbc/unittests/freeclose.c | 2 ++ src/odbc/unittests/funccall.c | 2 ++ src/odbc/unittests/genparams.c | 3 ++- src/odbc/unittests/getdata.c | 3 ++- src/odbc/unittests/hidden.c | 2 ++ src/odbc/unittests/insert_speed.c | 3 ++- src/odbc/unittests/lang_error.c | 2 ++ src/odbc/unittests/long_error.c | 2 ++ src/odbc/unittests/mars1.c | 2 ++ src/odbc/unittests/moreandcount.c | 2 ++ src/odbc/unittests/moreresults.c | 2 ++ src/odbc/unittests/norowset.c | 2 ++ src/odbc/unittests/oldpwd.c | 2 ++ src/odbc/unittests/paramcore.c | 2 ++ src/odbc/unittests/params.c | 2 ++ src/odbc/unittests/parser.c | 3 ++- src/odbc/unittests/peter.c | 3 ++- src/odbc/unittests/prepare_results.c | 2 ++ src/odbc/unittests/prepare_warn.c | 2 ++ src/odbc/unittests/prepclose.c | 2 ++ src/odbc/unittests/preperror.c | 2 ++ src/odbc/unittests/print.c | 2 ++ src/odbc/unittests/putdata.c | 2 ++ src/odbc/unittests/qn.c | 3 ++- src/odbc/unittests/raiserror.c | 2 ++ src/odbc/unittests/rebindpar.c | 2 ++ src/odbc/unittests/rownumber.c | 2 ++ src/odbc/unittests/rowset.c | 2 ++ src/odbc/unittests/rpc.c | 3 ++- src/odbc/unittests/scroll.c | 2 ++ src/odbc/unittests/stats.c | 2 ++ src/odbc/unittests/t0001.c | 2 ++ src/odbc/unittests/t0002.c | 2 ++ src/odbc/unittests/t0003.c | 2 ++ src/odbc/unittests/tables.c | 2 ++ src/odbc/unittests/test64.c | 2 ++ src/odbc/unittests/testodbc.c | 2 ++ src/odbc/unittests/timeout.c | 3 ++- src/odbc/unittests/timeout2.c | 4 ++-- src/odbc/unittests/timeout3.c | 2 ++ src/odbc/unittests/timeout4.c | 2 ++ src/odbc/unittests/transaction.c | 2 ++ src/odbc/unittests/transaction2.c | 3 ++- src/odbc/unittests/transaction3.c | 2 ++ src/odbc/unittests/transaction4.c | 2 ++ src/odbc/unittests/tvp.c | 3 ++- src/odbc/unittests/type.c | 3 ++- src/odbc/unittests/typeinfo.c | 2 ++ src/odbc/unittests/utf8.c | 2 ++ src/odbc/unittests/utf8_2.c | 2 ++ src/odbc/unittests/utf8_3.c | 3 ++- src/odbc/unittests/utf8_4.c | 3 ++- src/odbc/unittests/warning.c | 2 ++ src/odbc/unittests/wchar.c | 2 ++ src/replacements/unittests/strings.c | 4 ++-- src/replacements/unittests/strsep.c | 3 ++- src/replacements/unittests/strtok_r.c | 2 ++ src/tds/unittests/allcolumns.c | 3 ++- src/tds/unittests/charconv.c | 2 +- src/tds/unittests/collations.c | 3 ++- src/tds/unittests/common.c | 2 ++ src/tds/unittests/convert.c | 3 ++- src/tds/unittests/convert_bounds.c | 3 ++- src/tds/unittests/corrupt.c | 2 ++ src/tds/unittests/dataread.c | 3 ++- src/tds/unittests/declarations.c | 3 ++- src/tds/unittests/dynamic1.c | 2 ++ src/tds/unittests/flags.c | 2 ++ src/tds/unittests/freeze.c | 3 ++- src/tds/unittests/iconv_fread.c | 2 +- src/tds/unittests/log_elision.c | 3 ++- src/tds/unittests/nulls.c | 2 ++ src/tds/unittests/numeric.c | 3 ++- src/tds/unittests/parsing.c | 2 ++ src/tds/unittests/portconf.c | 2 ++ src/tds/unittests/readconf.c | 2 ++ src/tds/unittests/strftime.c | 3 ++- src/tds/unittests/t0001.c | 2 ++ src/tds/unittests/t0002.c | 2 ++ src/tds/unittests/t0003.c | 2 ++ src/tds/unittests/t0004.c | 2 ++ src/tds/unittests/t0005.c | 2 ++ src/tds/unittests/t0006.c | 2 ++ src/tds/unittests/t0007.c | 2 ++ src/tds/unittests/t0008.c | 2 ++ src/tds/unittests/tls.c | 2 ++ src/tds/unittests/toodynamic.c | 2 ++ src/tds/unittests/utf8.c | 3 ++- src/tds/unittests/utf8_1.c | 3 ++- src/tds/unittests/utf8_2.c | 3 ++- src/tds/unittests/utf8_3.c | 3 ++- src/utils/unittests/bytes.c | 3 ++- src/utils/unittests/challenge.c | 3 ++- src/utils/unittests/condition.c | 2 ++ src/utils/unittests/dlist.c | 3 ++- src/utils/unittests/mutex1.c | 2 ++ src/utils/unittests/passarg.c | 4 ++-- src/utils/unittests/path.c | 3 ++- src/utils/unittests/smp.c | 3 ++- 223 files changed, 443 insertions(+), 72 deletions(-) create mode 100644 include/freetds/test_assert.h diff --git a/include/freetds/test_assert.h b/include/freetds/test_assert.h new file mode 100644 index 0000000000..f5711e7692 --- /dev/null +++ b/include/freetds/test_assert.h @@ -0,0 +1 @@ +#include diff --git a/src/apps/unittests/defncopy.c b/src/apps/unittests/defncopy.c index 5e5abac32c..f20a61a7d6 100644 --- a/src/apps/unittests/defncopy.c +++ b/src/apps/unittests/defncopy.c @@ -26,7 +26,6 @@ #include #include -#include #if HAVE_STRING_H #include @@ -48,6 +47,8 @@ #include #include +#include + static char USER[512]; static char SERVER[512]; static char PASSWORD[512]; diff --git a/src/ctlib/unittests/all_types.c b/src/ctlib/unittests/all_types.c index 40e2e02d72..cf02e3c2cf 100644 --- a/src/ctlib/unittests/all_types.c +++ b/src/ctlib/unittests/all_types.c @@ -7,11 +7,12 @@ #include #include "common.h" #include -#include #define TDS_DONT_DEFINE_DEFAULT_FUNCTIONS #include "../../tds/unittests/common.h" #include +#include + static CS_CONTEXT *ctx = NULL; static void test_type(TDSSOCKET *tds TDS_UNUSED, TDSCOLUMN *col) diff --git a/src/ctlib/unittests/array_bind.c b/src/ctlib/unittests/array_bind.c index a01d62df44..da49e6dbd4 100644 --- a/src/ctlib/unittests/array_bind.c +++ b/src/ctlib/unittests/array_bind.c @@ -10,6 +10,8 @@ #include #include "common.h" +#include + /* Testing: array binding of result set */ int main(void) diff --git a/src/ctlib/unittests/blk_in.c b/src/ctlib/unittests/blk_in.c index 00bdb171de..a1e654e129 100644 --- a/src/ctlib/unittests/blk_in.c +++ b/src/ctlib/unittests/blk_in.c @@ -1,7 +1,6 @@ #include #include -#include #if HAVE_STDLIB_H #include @@ -21,6 +20,8 @@ #include "common.h" #include "blk_in.h" +#include + static CS_RETCODE do_bind(CS_BLKDESC * blkdesc, int colnum, CS_INT host_format, CS_INT host_type, CS_INT host_maxlen, void *var_addr, diff --git a/src/ctlib/unittests/blk_in2.c b/src/ctlib/unittests/blk_in2.c index 01bcbcc2f6..5ac0b4c13c 100644 --- a/src/ctlib/unittests/blk_in2.c +++ b/src/ctlib/unittests/blk_in2.c @@ -7,7 +7,6 @@ #include #include -#include #if HAVE_STDLIB_H #include @@ -26,6 +25,8 @@ #include #include "common.h" +#include + static const char create_table_sql[] = "CREATE TABLE hogexxx (col varchar(100))"; static void diff --git a/src/ctlib/unittests/blk_out.c b/src/ctlib/unittests/blk_out.c index 746dab1150..a09c5d363f 100644 --- a/src/ctlib/unittests/blk_out.c +++ b/src/ctlib/unittests/blk_out.c @@ -9,6 +9,8 @@ #include #include "common.h" +#include + /* Testing: array binding of result set */ int main(void) diff --git a/src/ctlib/unittests/cancel.c b/src/ctlib/unittests/cancel.c index 8da0c10134..2b49048af4 100644 --- a/src/ctlib/unittests/cancel.c +++ b/src/ctlib/unittests/cancel.c @@ -16,6 +16,8 @@ #include +#include + #if defined(HAVE_ALARM) && defined(HAVE_SETITIMER) /* protos */ diff --git a/src/ctlib/unittests/common.c b/src/ctlib/unittests/common.c index ee55f5c451..853f7f396d 100644 --- a/src/ctlib/unittests/common.c +++ b/src/ctlib/unittests/common.c @@ -23,6 +23,8 @@ #include "ctlib.h" #endif +#include + char USER[512]; char SERVER[512]; char PASSWORD[512]; diff --git a/src/ctlib/unittests/connect_fail.c b/src/ctlib/unittests/connect_fail.c index cfb9ecf625..ce2304fad0 100644 --- a/src/ctlib/unittests/connect_fail.c +++ b/src/ctlib/unittests/connect_fail.c @@ -4,6 +4,8 @@ #include #include "common.h" +#include + int main(void) { diff --git a/src/ctlib/unittests/cs_config.c b/src/ctlib/unittests/cs_config.c index 505dbff33e..5287760ef2 100644 --- a/src/ctlib/unittests/cs_config.c +++ b/src/ctlib/unittests/cs_config.c @@ -10,6 +10,8 @@ #include #include "common.h" +#include + int main(void) { diff --git a/src/ctlib/unittests/cs_convert.c b/src/ctlib/unittests/cs_convert.c index c782518ced..3d67ad78e3 100644 --- a/src/ctlib/unittests/cs_convert.c +++ b/src/ctlib/unittests/cs_convert.c @@ -5,10 +5,11 @@ #endif /* HAVE_STRING_H */ #include -#include #include #include "common.h" +#include + static CS_CONTEXT *ctx; static int allSuccess = 1; diff --git a/src/ctlib/unittests/cs_diag.c b/src/ctlib/unittests/cs_diag.c index 2ebabae8b8..dc30e08d48 100644 --- a/src/ctlib/unittests/cs_diag.c +++ b/src/ctlib/unittests/cs_diag.c @@ -5,6 +5,8 @@ #include #include "common.h" +#include + /* * ct_send SQL |select name = @@servername| * ct_bind variable diff --git a/src/ctlib/unittests/ct_command.c b/src/ctlib/unittests/ct_command.c index 898dfbb1b2..5c95e704a9 100644 --- a/src/ctlib/unittests/ct_command.c +++ b/src/ctlib/unittests/ct_command.c @@ -5,6 +5,8 @@ #include #include "common.h" +#include + /* * ct_command with CS_MORE option */ diff --git a/src/ctlib/unittests/ct_cursor.c b/src/ctlib/unittests/ct_cursor.c index 41ef0be403..8c702c2104 100644 --- a/src/ctlib/unittests/ct_cursor.c +++ b/src/ctlib/unittests/ct_cursor.c @@ -9,6 +9,8 @@ #include #include "common.h" +#include + static int update_second_table(CS_COMMAND * cmd2, char *value); int diff --git a/src/ctlib/unittests/ct_cursors.c b/src/ctlib/unittests/ct_cursors.c index b5475cc8af..3c019bd512 100644 --- a/src/ctlib/unittests/ct_cursors.c +++ b/src/ctlib/unittests/ct_cursors.c @@ -9,6 +9,8 @@ #include #include "common.h" +#include + int main(void) { diff --git a/src/ctlib/unittests/ct_diagall.c b/src/ctlib/unittests/ct_diagall.c index 193316f0bc..411c979ad8 100644 --- a/src/ctlib/unittests/ct_diagall.c +++ b/src/ctlib/unittests/ct_diagall.c @@ -10,6 +10,8 @@ #include #include "common.h" +#include + /* Testing: Client and server Messages */ int main(void) diff --git a/src/ctlib/unittests/ct_diagclient.c b/src/ctlib/unittests/ct_diagclient.c index 3e3f82da00..5a3bc2892d 100644 --- a/src/ctlib/unittests/ct_diagclient.c +++ b/src/ctlib/unittests/ct_diagclient.c @@ -8,6 +8,8 @@ #include #include "common.h" +#include + /* Testing: Client Messages */ int main(void) diff --git a/src/ctlib/unittests/ct_diagserver.c b/src/ctlib/unittests/ct_diagserver.c index 86da8c8ce5..ec8ba66796 100644 --- a/src/ctlib/unittests/ct_diagserver.c +++ b/src/ctlib/unittests/ct_diagserver.c @@ -8,6 +8,8 @@ #include #include "common.h" +#include + /* Testing: Server messages limit */ int main(void) diff --git a/src/ctlib/unittests/ct_dynamic.c b/src/ctlib/unittests/ct_dynamic.c index e8c6af293d..d8d104d365 100644 --- a/src/ctlib/unittests/ct_dynamic.c +++ b/src/ctlib/unittests/ct_dynamic.c @@ -14,6 +14,8 @@ #include #include "common.h" +#include + static int verbose = 0; static CS_CONTEXT *ctx; diff --git a/src/ctlib/unittests/ct_options.c b/src/ctlib/unittests/ct_options.c index 8010066f89..ea642bf736 100644 --- a/src/ctlib/unittests/ct_options.c +++ b/src/ctlib/unittests/ct_options.c @@ -8,6 +8,8 @@ #include #include "common.h" +#include + /* Testing: Set and get options with ct_options */ int main(int argc, char *argv[]) diff --git a/src/ctlib/unittests/data.c b/src/ctlib/unittests/data.c index 464421aef2..fa9c808170 100644 --- a/src/ctlib/unittests/data.c +++ b/src/ctlib/unittests/data.c @@ -9,9 +9,10 @@ #include #include #include -#include #include "common.h" +#include + int main(int argc, char *argv[]) { diff --git a/src/ctlib/unittests/datafmt.c b/src/ctlib/unittests/datafmt.c index 09489414d5..b322981691 100644 --- a/src/ctlib/unittests/datafmt.c +++ b/src/ctlib/unittests/datafmt.c @@ -9,6 +9,8 @@ #include #include "common.h" +#include + /* Testing: data truncation behavior of ct_fetch */ int main(int argc, char *argv[]) diff --git a/src/ctlib/unittests/errors.c b/src/ctlib/unittests/errors.c index 149273e8c3..7cd397c198 100644 --- a/src/ctlib/unittests/errors.c +++ b/src/ctlib/unittests/errors.c @@ -10,7 +10,9 @@ #include #include "common.h" -#define ALL_TESTS \ +#include + +#define ALL_TESTS \ TEST(ct_callback) \ TEST(ct_res_info) \ TEST(ct_send) \ diff --git a/src/ctlib/unittests/get_send_data.c b/src/ctlib/unittests/get_send_data.c index 976f93c814..acd92cdc0d 100644 --- a/src/ctlib/unittests/get_send_data.c +++ b/src/ctlib/unittests/get_send_data.c @@ -10,6 +10,8 @@ #include #include "common.h" +#include + static CS_CONNECTION *conn = NULL; /* Testing: Retrieve CS_TEXT_TYPE using ct_bind() */ diff --git a/src/ctlib/unittests/lang_ct_param.c b/src/ctlib/unittests/lang_ct_param.c index 4478428a4b..e16596e71f 100644 --- a/src/ctlib/unittests/lang_ct_param.c +++ b/src/ctlib/unittests/lang_ct_param.c @@ -14,6 +14,8 @@ #include #include "common.h" +#include + static const char *query = "insert into #ctparam_lang (name,name2,age,cost,bdate,fval) values (@in1, @in2, @in3, @moneyval, @dateval, @floatval)"; diff --git a/src/ctlib/unittests/long_binary.c b/src/ctlib/unittests/long_binary.c index 464a111de9..8f78b12447 100644 --- a/src/ctlib/unittests/long_binary.c +++ b/src/ctlib/unittests/long_binary.c @@ -17,6 +17,8 @@ #include +#include + static const CS_INT unused = CS_UNUSED, nullterm = CS_NULLTERM; static CS_INT result_len = -1; diff --git a/src/ctlib/unittests/row_count.c b/src/ctlib/unittests/row_count.c index eabbc83e7b..7e2c0d6c4e 100644 --- a/src/ctlib/unittests/row_count.c +++ b/src/ctlib/unittests/row_count.c @@ -65,11 +65,12 @@ #include #endif /* HAVE_STRING_H */ -#include #include #include "common.h" #include +#include + static CS_CONTEXT *ctx; static CS_CONNECTION *conn; static CS_COMMAND *cmd; diff --git a/src/ctlib/unittests/rpc_ct_param.c b/src/ctlib/unittests/rpc_ct_param.c index 9ae1e8984a..c27e12bbf1 100644 --- a/src/ctlib/unittests/rpc_ct_param.c +++ b/src/ctlib/unittests/rpc_ct_param.c @@ -13,6 +13,8 @@ #include #include "common.h" +#include + #define MAX(X,Y) (((X) > (Y)) ? (X) : (Y)) #define MIN(X,Y) (((X) < (Y)) ? (X) : (Y)) diff --git a/src/ctlib/unittests/rpc_ct_setparam.c b/src/ctlib/unittests/rpc_ct_setparam.c index 883cb7cebc..e2b05fc796 100644 --- a/src/ctlib/unittests/rpc_ct_setparam.c +++ b/src/ctlib/unittests/rpc_ct_setparam.c @@ -13,6 +13,8 @@ #include #include "common.h" +#include + #define MAX(X,Y) (((X) > (Y)) ? (X) : (Y)) #define MIN(X,Y) (((X) < (Y)) ? (X) : (Y)) diff --git a/src/ctlib/unittests/rpc_fail.c b/src/ctlib/unittests/rpc_fail.c index ffaff4bc24..d2a789bf93 100644 --- a/src/ctlib/unittests/rpc_fail.c +++ b/src/ctlib/unittests/rpc_fail.c @@ -13,6 +13,8 @@ #include #include "common.h" +#include + int main(void) { diff --git a/src/ctlib/unittests/t0001.c b/src/ctlib/unittests/t0001.c index 597a7994b5..1399e11cbd 100644 --- a/src/ctlib/unittests/t0001.c +++ b/src/ctlib/unittests/t0001.c @@ -4,6 +4,8 @@ #include #include "common.h" +#include + int main(void) { diff --git a/src/ctlib/unittests/t0002.c b/src/ctlib/unittests/t0002.c index 06fbfd7804..6933e77003 100644 --- a/src/ctlib/unittests/t0002.c +++ b/src/ctlib/unittests/t0002.c @@ -5,6 +5,8 @@ #include #include "common.h" +#include + static int sp_who(CS_COMMAND *cmd); /* diff --git a/src/ctlib/unittests/t0003.c b/src/ctlib/unittests/t0003.c index e6c7563bdc..93672ae518 100644 --- a/src/ctlib/unittests/t0003.c +++ b/src/ctlib/unittests/t0003.c @@ -9,6 +9,8 @@ #include #include "common.h" +#include + /* Testing: Retrieve CS_TEXT_TYPE using ct_bind() */ int main(void) diff --git a/src/ctlib/unittests/t0004.c b/src/ctlib/unittests/t0004.c index 1648bc8195..4be6dfeae7 100644 --- a/src/ctlib/unittests/t0004.c +++ b/src/ctlib/unittests/t0004.c @@ -4,6 +4,8 @@ #include #include "common.h" +#include + /* protos */ int do_fetch(CS_COMMAND * cmd); CS_RETCODE do_results(CS_COMMAND * cmd, CS_INT * results); diff --git a/src/ctlib/unittests/t0005.c b/src/ctlib/unittests/t0005.c index f8a0b9fb41..78316f7730 100644 --- a/src/ctlib/unittests/t0005.c +++ b/src/ctlib/unittests/t0005.c @@ -6,6 +6,8 @@ #include #include "common.h" +#include + int main(void) { diff --git a/src/ctlib/unittests/t0007.c b/src/ctlib/unittests/t0007.c index 09b7dc8ef5..91cac8f945 100644 --- a/src/ctlib/unittests/t0007.c +++ b/src/ctlib/unittests/t0007.c @@ -8,6 +8,8 @@ #include #include "common.h" +#include + /* Testing: Retrieve CS_TEXT_TYPE using ct_bind() */ int main(void) diff --git a/src/ctlib/unittests/t0008.c b/src/ctlib/unittests/t0008.c index 32c19ead32..0489297e48 100644 --- a/src/ctlib/unittests/t0008.c +++ b/src/ctlib/unittests/t0008.c @@ -5,6 +5,8 @@ #include #include "common.h" +#include + /* * ct_send SQL |select name = @@servername| * ct_bind variable diff --git a/src/ctlib/unittests/t0009.c b/src/ctlib/unittests/t0009.c index d99ed62522..353884303e 100644 --- a/src/ctlib/unittests/t0009.c +++ b/src/ctlib/unittests/t0009.c @@ -8,6 +8,8 @@ #include #include "common.h" +#include + static CS_RETCODE ex_servermsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_SERVERMSG * errmsg); static int compute_supported = 1; diff --git a/src/ctlib/unittests/variant.c b/src/ctlib/unittests/variant.c index 66e8be8c52..a97dcaeca5 100644 --- a/src/ctlib/unittests/variant.c +++ b/src/ctlib/unittests/variant.c @@ -6,10 +6,11 @@ #endif /* HAVE_STRING_H */ #include -#include #include #include "common.h" +#include + /* Testing: Retrieving SQL_VARIANT */ int main(void) diff --git a/src/ctlib/unittests/will_convert.c b/src/ctlib/unittests/will_convert.c index f0bbbc7408..0c7cdfc9e6 100644 --- a/src/ctlib/unittests/will_convert.c +++ b/src/ctlib/unittests/will_convert.c @@ -13,10 +13,11 @@ #include #endif /* HAVE_STRING_H */ -#include #include #include "common.h" +#include + static CS_CONTEXT *context; typedef struct { diff --git a/src/dblib/unittests/batch_stmt_ins_sel.c b/src/dblib/unittests/batch_stmt_ins_sel.c index 5902dfd074..d3c394d44f 100644 --- a/src/dblib/unittests/batch_stmt_ins_sel.c +++ b/src/dblib/unittests/batch_stmt_ins_sel.c @@ -6,6 +6,8 @@ #include "common.h" +#include + int main(int argc, char **argv) { diff --git a/src/dblib/unittests/batch_stmt_ins_upd.c b/src/dblib/unittests/batch_stmt_ins_upd.c index 570826b2c9..1fa91246a4 100644 --- a/src/dblib/unittests/batch_stmt_ins_upd.c +++ b/src/dblib/unittests/batch_stmt_ins_upd.c @@ -6,6 +6,8 @@ #include "common.h" +#include + int main(int argc, char **argv) { diff --git a/src/dblib/unittests/bcp.c b/src/dblib/unittests/bcp.c index 3644fa5fb2..19c397542d 100644 --- a/src/dblib/unittests/bcp.c +++ b/src/dblib/unittests/bcp.c @@ -5,14 +5,14 @@ #include "common.h" -#include - #if HAVE_SYS_STAT_H #include #endif /* HAVE_SYS_STAT_H */ #include "bcp.h" +#include + static char cmd[1024]; static int init(DBPROCESS * dbproc, const char *name); static void test_bind(DBPROCESS * dbproc); diff --git a/src/dblib/unittests/bcp2.c b/src/dblib/unittests/bcp2.c index 752fc051da..4ccf42a310 100644 --- a/src/dblib/unittests/bcp2.c +++ b/src/dblib/unittests/bcp2.c @@ -5,7 +5,7 @@ #include "common.h" -#include +#include static void doexit(int value) diff --git a/src/dblib/unittests/bcp_getl.c b/src/dblib/unittests/bcp_getl.c index 3e167af165..fca7ff85b0 100644 --- a/src/dblib/unittests/bcp_getl.c +++ b/src/dblib/unittests/bcp_getl.c @@ -1,6 +1,8 @@ #include "common.h" +#include + int main(void) { diff --git a/src/dblib/unittests/cancel.c b/src/dblib/unittests/cancel.c index 2ec285138a..57a8aa6e89 100644 --- a/src/dblib/unittests/cancel.c +++ b/src/dblib/unittests/cancel.c @@ -6,6 +6,8 @@ #include "common.h" +#include + static int cancel_msg_handler(DBPROCESS * dbproc, DBINT msgno TDS_UNUSED, int msgstate TDS_UNUSED, int severity TDS_UNUSED, char *msgtext TDS_UNUSED, char *srvname TDS_UNUSED, char *procname TDS_UNUSED, int line TDS_UNUSED) diff --git a/src/dblib/unittests/canquery.c b/src/dblib/unittests/canquery.c index c433184d6a..a073a04391 100644 --- a/src/dblib/unittests/canquery.c +++ b/src/dblib/unittests/canquery.c @@ -5,6 +5,8 @@ #include "common.h" +#include + int main(int argc, char **argv) { diff --git a/src/dblib/unittests/colinfo.c b/src/dblib/unittests/colinfo.c index 73f62e73ae..8c088bc332 100644 --- a/src/dblib/unittests/colinfo.c +++ b/src/dblib/unittests/colinfo.c @@ -5,6 +5,8 @@ #include "common.h" +#include + static int failed = 0; static void diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c index 329f260869..0330a2337b 100644 --- a/src/dblib/unittests/common.c +++ b/src/dblib/unittests/common.c @@ -21,6 +21,8 @@ #include +#include + #if !defined(PATH_MAX) #define PATH_MAX 256 #endif diff --git a/src/dblib/unittests/common.h b/src/dblib/unittests/common.h index eb987f7117..474fb5cce3 100644 --- a/src/dblib/unittests/common.h +++ b/src/dblib/unittests/common.h @@ -8,7 +8,6 @@ #include #include -#include #if HAVE_UNISTD_H #include @@ -36,6 +35,8 @@ #include #include +#include + #if !defined(EXIT_FAILURE) #define EXIT_FAILURE 1 #define EXIT_SUCCESS 0 diff --git a/src/dblib/unittests/dbmorecmds.c b/src/dblib/unittests/dbmorecmds.c index 2385e83325..1c102dd631 100644 --- a/src/dblib/unittests/dbmorecmds.c +++ b/src/dblib/unittests/dbmorecmds.c @@ -5,6 +5,8 @@ #include "common.h" +#include + int main(int argc, char **argv) { diff --git a/src/dblib/unittests/dbsafestr.c b/src/dblib/unittests/dbsafestr.c index dd25e75149..11fc7a1040 100644 --- a/src/dblib/unittests/dbsafestr.c +++ b/src/dblib/unittests/dbsafestr.c @@ -5,6 +5,8 @@ #include "common.h" +#include + #ifndef DBNTWIN32 static int failed = 0; diff --git a/src/dblib/unittests/done_handling.c b/src/dblib/unittests/done_handling.c index bdfd600c0a..1ffde008ba 100644 --- a/src/dblib/unittests/done_handling.c +++ b/src/dblib/unittests/done_handling.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* * This test try do discovery how dblib process token looking for state * at every iteration. It issue a query to server and check diff --git a/src/dblib/unittests/empty_rowsets.c b/src/dblib/unittests/empty_rowsets.c index 228fb32847..ce75a4d5cb 100644 --- a/src/dblib/unittests/empty_rowsets.c +++ b/src/dblib/unittests/empty_rowsets.c @@ -5,6 +5,8 @@ #include "common.h" +#include + static int failed = 0; static void set_failed(int line) { diff --git a/src/dblib/unittests/hang.c b/src/dblib/unittests/hang.c index ce30d1d900..c3a948f4fc 100644 --- a/src/dblib/unittests/hang.c +++ b/src/dblib/unittests/hang.c @@ -32,6 +32,8 @@ #include +#include + char *UNITTEST; #if HAVE_FSTAT && defined(S_IFSOCK) diff --git a/src/dblib/unittests/null.c b/src/dblib/unittests/null.c index adfa894d00..9f6cb99d6e 100644 --- a/src/dblib/unittests/null.c +++ b/src/dblib/unittests/null.c @@ -9,6 +9,8 @@ #include #endif /* HAVE_UNISTD_H */ +#include + #ifndef DBNTWIN32 static DBPROCESS *dbproc = NULL; diff --git a/src/dblib/unittests/null2.c b/src/dblib/unittests/null2.c index a81fa7796b..408b9bfe46 100644 --- a/src/dblib/unittests/null2.c +++ b/src/dblib/unittests/null2.c @@ -8,6 +8,8 @@ #include #endif /* HAVE_UNISTD_H */ +#include + static DBPROCESS *dbproc = NULL; static int failed = 0; diff --git a/src/dblib/unittests/numeric.c b/src/dblib/unittests/numeric.c index 9f9e7fba44..dd32c1a66d 100644 --- a/src/dblib/unittests/numeric.c +++ b/src/dblib/unittests/numeric.c @@ -1,6 +1,8 @@ #define MSDBLIB 1 #include "common.h" +#include + static void dump_addr(FILE *out, const char *msg, const void *p, size_t len) { diff --git a/src/dblib/unittests/pending.c b/src/dblib/unittests/pending.c index facf2b2a92..572f8c5184 100644 --- a/src/dblib/unittests/pending.c +++ b/src/dblib/unittests/pending.c @@ -6,6 +6,8 @@ #include "common.h" +#include + int main(int argc, char **argv) { diff --git a/src/dblib/unittests/proc_limit.c b/src/dblib/unittests/proc_limit.c index 1a8fc409f3..178e9c0cd7 100644 --- a/src/dblib/unittests/proc_limit.c +++ b/src/dblib/unittests/proc_limit.c @@ -6,6 +6,8 @@ #include "common.h" #include +#include + static bool proc_limit_hit = false; static int diff --git a/src/dblib/unittests/rpc.c b/src/dblib/unittests/rpc.c index e5c7965920..4f73f4fb89 100644 --- a/src/dblib/unittests/rpc.c +++ b/src/dblib/unittests/rpc.c @@ -5,6 +5,8 @@ #include "common.h" +#include + static RETCODE init_proc(DBPROCESS * dbproc, const char *name); int ignore_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr); int ignore_msg_handler(DBPROCESS * dbproc, DBINT msgno, int state, int severity, char *text, char *server, char *proc, int line); diff --git a/src/dblib/unittests/setnull.c b/src/dblib/unittests/setnull.c index c3049d096b..5faa144542 100644 --- a/src/dblib/unittests/setnull.c +++ b/src/dblib/unittests/setnull.c @@ -5,6 +5,8 @@ #include "common.h" #include +#include + static int failed = 0; static DBPROCESS *dbproc = NULL; diff --git a/src/dblib/unittests/spid.c b/src/dblib/unittests/spid.c index c7ed5f3083..a2a7041f45 100644 --- a/src/dblib/unittests/spid.c +++ b/src/dblib/unittests/spid.c @@ -5,6 +5,8 @@ #include "common.h" +#include + int main(int argc, char **argv) { diff --git a/src/dblib/unittests/string_bind.c b/src/dblib/unittests/string_bind.c index 9e200277c2..f2ba6378e8 100644 --- a/src/dblib/unittests/string_bind.c +++ b/src/dblib/unittests/string_bind.c @@ -5,6 +5,8 @@ #include "common.h" +#include + static DBPROCESS *dbproc = NULL; static int bind_len = -1; static int expected_error = 0; diff --git a/src/dblib/unittests/t0001.c b/src/dblib/unittests/t0001.c index b6b5c4272a..afeaef9517 100644 --- a/src/dblib/unittests/t0001.c +++ b/src/dblib/unittests/t0001.c @@ -5,6 +5,8 @@ #include "common.h" +#include + int failed = 0; diff --git a/src/dblib/unittests/t0002.c b/src/dblib/unittests/t0002.c index 0138e463ac..e2b6efcf85 100644 --- a/src/dblib/unittests/t0002.c +++ b/src/dblib/unittests/t0002.c @@ -8,7 +8,8 @@ #endif #include "common.h" -#include + +#include int failed = 0; diff --git a/src/dblib/unittests/t0003.c b/src/dblib/unittests/t0003.c index cc0b5c3afc..07767f59c4 100644 --- a/src/dblib/unittests/t0003.c +++ b/src/dblib/unittests/t0003.c @@ -5,6 +5,8 @@ #include "common.h" +#include + int failed = 0; diff --git a/src/dblib/unittests/t0004.c b/src/dblib/unittests/t0004.c index f827764412..30552f00da 100644 --- a/src/dblib/unittests/t0004.c +++ b/src/dblib/unittests/t0004.c @@ -6,6 +6,8 @@ #include "common.h" #include +#include + int main(int argc, char **argv) { diff --git a/src/dblib/unittests/t0005.c b/src/dblib/unittests/t0005.c index 40f3835f31..3f56f948ee 100644 --- a/src/dblib/unittests/t0005.c +++ b/src/dblib/unittests/t0005.c @@ -5,6 +5,8 @@ #include "common.h" +#include + int main(int argc, char **argv) { diff --git a/src/dblib/unittests/t0006.c b/src/dblib/unittests/t0006.c index 5c07904ee3..dd583b6620 100644 --- a/src/dblib/unittests/t0006.c +++ b/src/dblib/unittests/t0006.c @@ -5,6 +5,8 @@ #include "common.h" +#include + static char teststr[1024]; static DBINT testint; diff --git a/src/dblib/unittests/t0007.c b/src/dblib/unittests/t0007.c index 9ca7092eea..7df593acc8 100644 --- a/src/dblib/unittests/t0007.c +++ b/src/dblib/unittests/t0007.c @@ -5,6 +5,8 @@ #include "common.h" +#include + static void create_tables(DBPROCESS * dbproc, int rows_to_add) { diff --git a/src/dblib/unittests/t0008.c b/src/dblib/unittests/t0008.c index 58968c363b..37c955b695 100644 --- a/src/dblib/unittests/t0008.c +++ b/src/dblib/unittests/t0008.c @@ -5,6 +5,8 @@ #include "common.h" +#include + int main(int argc, char **argv) { diff --git a/src/dblib/unittests/t0009.c b/src/dblib/unittests/t0009.c index d3b52e0977..74fa451477 100644 --- a/src/dblib/unittests/t0009.c +++ b/src/dblib/unittests/t0009.c @@ -5,6 +5,8 @@ #include "common.h" +#include + int main(int argc, char **argv) { diff --git a/src/dblib/unittests/t0011.c b/src/dblib/unittests/t0011.c index dc4d6fd73e..51867ea7a8 100644 --- a/src/dblib/unittests/t0011.c +++ b/src/dblib/unittests/t0011.c @@ -6,6 +6,8 @@ #include "common.h" +#include + static int failed = 0; static void insert_row(DBPROCESS * dbproc); diff --git a/src/dblib/unittests/t0012.c b/src/dblib/unittests/t0012.c index c3fabf5f9b..537c1476cb 100644 --- a/src/dblib/unittests/t0012.c +++ b/src/dblib/unittests/t0012.c @@ -5,6 +5,8 @@ #include "common.h" +#include + static int failed = 0; static void set_failed(int line) { diff --git a/src/dblib/unittests/t0013.c b/src/dblib/unittests/t0013.c index 69d9ed88e6..228e68fc9f 100644 --- a/src/dblib/unittests/t0013.c +++ b/src/dblib/unittests/t0013.c @@ -5,6 +5,8 @@ #include "common.h" +#include + #define BLOB_BLOCK_SIZE 4096 int failed = 0; diff --git a/src/dblib/unittests/t0014.c b/src/dblib/unittests/t0014.c index 0c494155df..11a5c724cc 100644 --- a/src/dblib/unittests/t0014.c +++ b/src/dblib/unittests/t0014.c @@ -5,6 +5,8 @@ #include "common.h" +#include + #define BLOB_BLOCK_SIZE 4096 char *testargs[] = { "", FREETDS_SRCDIR "/data.bin", "t0014.out" }; diff --git a/src/dblib/unittests/t0015.c b/src/dblib/unittests/t0015.c index 361df5f670..64c1565010 100644 --- a/src/dblib/unittests/t0015.c +++ b/src/dblib/unittests/t0015.c @@ -5,6 +5,8 @@ #include "common.h" +#include + int main(int argc, char **argv) { diff --git a/src/dblib/unittests/t0016.c b/src/dblib/unittests/t0016.c index 53bffcd903..03fd5f01ba 100644 --- a/src/dblib/unittests/t0016.c +++ b/src/dblib/unittests/t0016.c @@ -5,6 +5,8 @@ #include "common.h" +#include + static int failed = 0; static void diff --git a/src/dblib/unittests/t0017.c b/src/dblib/unittests/t0017.c index 4044c8c42b..1c26e77588 100644 --- a/src/dblib/unittests/t0017.c +++ b/src/dblib/unittests/t0017.c @@ -4,7 +4,8 @@ */ #include "common.h" -#include + +#include int main(int argc, char *argv[]) diff --git a/src/dblib/unittests/t0018.c b/src/dblib/unittests/t0018.c index 09ed121bc3..a9c75b7186 100644 --- a/src/dblib/unittests/t0018.c +++ b/src/dblib/unittests/t0018.c @@ -5,6 +5,8 @@ #include "common.h" +#include + int failed = 0; diff --git a/src/dblib/unittests/t0019.c b/src/dblib/unittests/t0019.c index 111266e67d..84ac6694d0 100644 --- a/src/dblib/unittests/t0019.c +++ b/src/dblib/unittests/t0019.c @@ -6,6 +6,8 @@ #include "common.h" #include +#include + static int failure = 0; static const char *cur_result = ""; diff --git a/src/dblib/unittests/t0020.c b/src/dblib/unittests/t0020.c index f2b721e430..124325602d 100644 --- a/src/dblib/unittests/t0020.c +++ b/src/dblib/unittests/t0020.c @@ -5,6 +5,8 @@ #include "common.h" +#include + int failed = 0; int err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr); diff --git a/src/dblib/unittests/t0022.c b/src/dblib/unittests/t0022.c index 9bd6824744..44cd43e7a4 100644 --- a/src/dblib/unittests/t0022.c +++ b/src/dblib/unittests/t0022.c @@ -4,7 +4,8 @@ */ #include "common.h" -#include + +#include int main(int argc, char **argv) diff --git a/src/dblib/unittests/t0023.c b/src/dblib/unittests/t0023.c index e62a7645fa..007a9ca981 100644 --- a/src/dblib/unittests/t0023.c +++ b/src/dblib/unittests/t0023.c @@ -4,7 +4,8 @@ */ #include "common.h" -#include + +#include static int got_error = 0; static int compute_supported = 1; diff --git a/src/dblib/unittests/text_buffer.c b/src/dblib/unittests/text_buffer.c index e9725ee642..1297dd1f70 100644 --- a/src/dblib/unittests/text_buffer.c +++ b/src/dblib/unittests/text_buffer.c @@ -5,6 +5,8 @@ #include "common.h" +#include + int main(int argc, char **argv) { diff --git a/src/dblib/unittests/thread.c b/src/dblib/unittests/thread.c index 33ca0072e7..e642a14fd0 100644 --- a/src/dblib/unittests/thread.c +++ b/src/dblib/unittests/thread.c @@ -13,6 +13,8 @@ #include +#include + #ifdef TDS_HAVE_MUTEX static tds_mutex mutex = TDS_MUTEX_INITIALIZER; diff --git a/src/dblib/unittests/timeout.c b/src/dblib/unittests/timeout.c index cc4b8ca4b7..efbb140e23 100644 --- a/src/dblib/unittests/timeout.c +++ b/src/dblib/unittests/timeout.c @@ -11,6 +11,8 @@ #include "common.h" #include +#include + static int ntimeouts = 0, ncancels = 0; static const int max_timeouts = 2, timeout_seconds = 2; static time_t start_time; diff --git a/src/odbc/unittests/all_types.c b/src/odbc/unittests/all_types.c index 5d74f22790..9ca90da1f0 100644 --- a/src/odbc/unittests/all_types.c +++ b/src/odbc/unittests/all_types.c @@ -1,10 +1,11 @@ #undef NDEBUG #include "common.h" -#include #define TDS_DONT_DEFINE_DEFAULT_FUNCTIONS #include "../../tds/unittests/common.h" #include +#include + /* Check we support any possible types from the server */ static int sql_c_types[100]; diff --git a/src/odbc/unittests/array.c b/src/odbc/unittests/array.c index 62cab3c41a..c7fa558820 100644 --- a/src/odbc/unittests/array.c +++ b/src/odbc/unittests/array.c @@ -1,5 +1,6 @@ #include "common.h" -#include + +#include /* Test using array binding */ diff --git a/src/odbc/unittests/array_error.c b/src/odbc/unittests/array_error.c index 644ef44f40..f08c08fb4e 100644 --- a/src/odbc/unittests/array_error.c +++ b/src/odbc/unittests/array_error.c @@ -1,6 +1,7 @@ #undef NDEBUG #include "common.h" -#include + +#include /* Test for a bug executing after a not successfully execute diff --git a/src/odbc/unittests/array_out.c b/src/odbc/unittests/array_out.c index ea03fb7627..4e351aa10a 100644 --- a/src/odbc/unittests/array_out.c +++ b/src/odbc/unittests/array_out.c @@ -1,5 +1,6 @@ #include "common.h" -#include + +#include /* Test using array binding */ diff --git a/src/odbc/unittests/attributes.c b/src/odbc/unittests/attributes.c index 9520a9fd2d..2712011770 100644 --- a/src/odbc/unittests/attributes.c +++ b/src/odbc/unittests/attributes.c @@ -1,6 +1,8 @@ #include "common.h" #include +#include + /* * SQLSetStmtAttr */ diff --git a/src/odbc/unittests/base.c b/src/odbc/unittests/base.c index 22b713fc25..6c1db661ea 100644 --- a/src/odbc/unittests/base.c +++ b/src/odbc/unittests/base.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* TODO place comment here */ int diff --git a/src/odbc/unittests/bcp.c b/src/odbc/unittests/bcp.c index fbc387a1d4..15e46c827c 100644 --- a/src/odbc/unittests/bcp.c +++ b/src/odbc/unittests/bcp.c @@ -1,7 +1,8 @@ #include "common.h" #define TDSODBC_BCP #include -#include + +#include #ifdef UNICODE typedef SQLWCHAR bcp_init_char_t; diff --git a/src/odbc/unittests/binary_test.c b/src/odbc/unittests/binary_test.c index 6fe6d5b55d..b880ab6d4f 100644 --- a/src/odbc/unittests/binary_test.c +++ b/src/odbc/unittests/binary_test.c @@ -5,7 +5,8 @@ */ #include "common.h" -#include + +#include #define ERR_BUF_SIZE 256 /* diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c index e9196f421b..967f517221 100644 --- a/src/odbc/unittests/blob1.c +++ b/src/odbc/unittests/blob1.c @@ -3,7 +3,8 @@ #include "common.h" #include -#include + +#include #define NBYTES 10000u diff --git a/src/odbc/unittests/c2string.c b/src/odbc/unittests/c2string.c index 6c11cf41fa..e557a7cfd8 100644 --- a/src/odbc/unittests/c2string.c +++ b/src/odbc/unittests/c2string.c @@ -1,5 +1,6 @@ #include "common.h" -#include + +#include static char * add_char(char *s, SQLWCHAR ch) diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c index b76d4e32e9..ab7e87d73a 100644 --- a/src/odbc/unittests/cancel.c +++ b/src/odbc/unittests/cancel.c @@ -2,7 +2,6 @@ #include "common.h" -#include #include #if HAVE_UNISTD_H @@ -14,6 +13,8 @@ #include #include +#include + #if TDS_HAVE_MUTEX #ifdef _WIN32 diff --git a/src/odbc/unittests/closestmt.c b/src/odbc/unittests/closestmt.c index 9b2afc3d22..d9bd1d1357 100644 --- a/src/odbc/unittests/closestmt.c +++ b/src/odbc/unittests/closestmt.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* * This test attempt to test if closing a statement with prepared query * success if there are a pending query on the same connection from diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c index 724553dd67..dc0aeb1640 100644 --- a/src/odbc/unittests/common.c +++ b/src/odbc/unittests/common.c @@ -1,7 +1,6 @@ #include "common.h" #include -#include #include #if HAVE_SYS_SOCKET_H @@ -28,6 +27,8 @@ struct odbc_buf{ void *buf; }; +#include + HENV odbc_env; HDBC odbc_conn; HSTMT odbc_stmt; diff --git a/src/odbc/unittests/compute.c b/src/odbc/unittests/compute.c index 4b3b1c8f29..5ad5eed03f 100644 --- a/src/odbc/unittests/compute.c +++ b/src/odbc/unittests/compute.c @@ -1,5 +1,6 @@ #include "common.h" -#include + +#include /* Test compute results */ diff --git a/src/odbc/unittests/connect.c b/src/odbc/unittests/connect.c index 0034353cd4..9d42fb5f2c 100644 --- a/src/odbc/unittests/connect.c +++ b/src/odbc/unittests/connect.c @@ -1,5 +1,7 @@ #include "common.h" +#include + static void init_connect(void); diff --git a/src/odbc/unittests/connect2.c b/src/odbc/unittests/connect2.c index 8befd72ca2..ed26b784de 100644 --- a/src/odbc/unittests/connect2.c +++ b/src/odbc/unittests/connect2.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* * Test setting current "catalog" before and after connection using * either SQLConnect and SQLDriverConnect diff --git a/src/odbc/unittests/connection_string_parse.c b/src/odbc/unittests/connection_string_parse.c index c7474a1fab..03fc81d495 100644 --- a/src/odbc/unittests/connection_string_parse.c +++ b/src/odbc/unittests/connection_string_parse.c @@ -1,7 +1,8 @@ #include "common.h" -#include #include "freetds/odbc.h" +#include + #ifdef _WIN32 HINSTANCE hinstFreeTDS; diff --git a/src/odbc/unittests/const_params.c b/src/odbc/unittests/const_params.c index 14cb6981c8..61a1fa4077 100644 --- a/src/odbc/unittests/const_params.c +++ b/src/odbc/unittests/const_params.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test for {?=call store(?,123,'foo')} syntax and run */ int diff --git a/src/odbc/unittests/convert_error.c b/src/odbc/unittests/convert_error.c index 117eafc5a6..9707a88946 100644 --- a/src/odbc/unittests/convert_error.c +++ b/src/odbc/unittests/convert_error.c @@ -4,6 +4,8 @@ */ #include "common.h" +#include + static int test_num = 0; static void diff --git a/src/odbc/unittests/copydesc.c b/src/odbc/unittests/copydesc.c index 89d0c2983f..08fed2b521 100644 --- a/src/odbc/unittests/copydesc.c +++ b/src/odbc/unittests/copydesc.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test SQLCopyDesc and SQLAllocHandle(SQL_HANDLE_DESC) */ static void diff --git a/src/odbc/unittests/cursor1.c b/src/odbc/unittests/cursor1.c index 3e8eb90a02..92b1160068 100644 --- a/src/odbc/unittests/cursor1.c +++ b/src/odbc/unittests/cursor1.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test cursors */ #define SWAP_STMT(b) do { SQLHSTMT xyz = odbc_stmt; odbc_stmt = b; b = xyz; } while(0) diff --git a/src/odbc/unittests/cursor2.c b/src/odbc/unittests/cursor2.c index 40ee848b1b..c0067bda81 100644 --- a/src/odbc/unittests/cursor2.c +++ b/src/odbc/unittests/cursor2.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* * 1) Test cursor do not give error for statement that do not return rows * 2) Test cursor returns results on language RPCs diff --git a/src/odbc/unittests/cursor3.c b/src/odbc/unittests/cursor3.c index 27327f2dfa..76bcba8f91 100644 --- a/src/odbc/unittests/cursor3.c +++ b/src/odbc/unittests/cursor3.c @@ -1,6 +1,8 @@ /* Tests 2 active statements */ #include "common.h" +#include + int main(void) { diff --git a/src/odbc/unittests/cursor4.c b/src/odbc/unittests/cursor4.c index a4f16f1fa7..6fb27751ed 100644 --- a/src/odbc/unittests/cursor4.c +++ b/src/odbc/unittests/cursor4.c @@ -5,6 +5,8 @@ #include "common.h" +#include + static void exec_direct(const char *stmt) { diff --git a/src/odbc/unittests/cursor5.c b/src/odbc/unittests/cursor5.c index d9337c653e..49b5b8f64d 100644 --- a/src/odbc/unittests/cursor5.c +++ b/src/odbc/unittests/cursor5.c @@ -1,5 +1,7 @@ #include "common.h" +#include + static SQLINTEGER v_int_3; static SQLLEN v_ind_3_1; diff --git a/src/odbc/unittests/cursor6.c b/src/odbc/unittests/cursor6.c index 033bb260c6..06fd5caaf7 100644 --- a/src/odbc/unittests/cursor6.c +++ b/src/odbc/unittests/cursor6.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test SQLFetchScroll with no bound columns */ static int bind_all = 0; diff --git a/src/odbc/unittests/cursor7.c b/src/odbc/unittests/cursor7.c index e3e7f4fa9e..2c95cbf0b0 100644 --- a/src/odbc/unittests/cursor7.c +++ b/src/odbc/unittests/cursor7.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test SQLFetchScroll with a non-unitary rowset, using bottom-up direction */ static void diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c index a2dd42f72b..bdf5f013b6 100644 --- a/src/odbc/unittests/data.c +++ b/src/odbc/unittests/data.c @@ -2,10 +2,11 @@ * Test reading data with SQLBindCol */ #include "common.h" -#include #include #include "parser.h" +#include + /* * This test is useful to test odbc_tds2sql function * odbc_tds2sql have some particular cases: diff --git a/src/odbc/unittests/date.c b/src/odbc/unittests/date.c index b0158a6dbf..a7c5d3cac3 100644 --- a/src/odbc/unittests/date.c +++ b/src/odbc/unittests/date.c @@ -1,5 +1,7 @@ #include "common.h" +#include + static void DoTest(int n) { diff --git a/src/odbc/unittests/descrec.c b/src/odbc/unittests/descrec.c index 612bf216f4..f3f1542d50 100644 --- a/src/odbc/unittests/descrec.c +++ b/src/odbc/unittests/descrec.c @@ -1,6 +1,8 @@ /* test SQLGetDescRec */ #include "common.h" +#include + static char software_version[] = "$Id: descrec.c,v 1.3 2011-07-12 10:16:59 freddy77 Exp $"; static void *no_unused_var_warn[] = { software_version, no_unused_var_warn }; diff --git a/src/odbc/unittests/describecol.c b/src/odbc/unittests/describecol.c index b602403e0d..eed4683f93 100644 --- a/src/odbc/unittests/describecol.c +++ b/src/odbc/unittests/describecol.c @@ -4,6 +4,8 @@ #include #include +#include + /* * SQLDescribeCol test for precision * test what say SQLDescribeCol about precision using some type diff --git a/src/odbc/unittests/describecol2.c b/src/odbc/unittests/describecol2.c index c9b3f884e8..8d827635d6 100644 --- a/src/odbc/unittests/describecol2.c +++ b/src/odbc/unittests/describecol2.c @@ -1,6 +1,8 @@ #include "common.h" #include +#include + /* * SQLDescribeCol test */ diff --git a/src/odbc/unittests/earlybind.c b/src/odbc/unittests/earlybind.c index 8584734694..8077bf90e2 100644 --- a/src/odbc/unittests/earlybind.c +++ b/src/odbc/unittests/earlybind.c @@ -1,5 +1,7 @@ #include "common.h" +#include + int main(void) { diff --git a/src/odbc/unittests/empty_query.c b/src/odbc/unittests/empty_query.c index 95cb5dba82..63cd6507a7 100644 --- a/src/odbc/unittests/empty_query.c +++ b/src/odbc/unittests/empty_query.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Check that on queries returning 0 rows and NOCOUNT active SQLExecDirect returns success. * Also SQLFetch should return NO_DATA for these queries. */ diff --git a/src/odbc/unittests/error.c b/src/odbc/unittests/error.c index a5bf10eb3d..18448b684a 100644 --- a/src/odbc/unittests/error.c +++ b/src/odbc/unittests/error.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* some tests on error reporting */ int diff --git a/src/odbc/unittests/freeclose.c b/src/odbc/unittests/freeclose.c index b60b2b9841..e1fcd9d150 100644 --- a/src/odbc/unittests/freeclose.c +++ b/src/odbc/unittests/freeclose.c @@ -37,6 +37,8 @@ #include #include +#include + /* this crazy test tests that we do not send too much prepare ... */ static tds_mutex mtx; diff --git a/src/odbc/unittests/funccall.c b/src/odbc/unittests/funccall.c index bb932a3a2f..8f1affb7d0 100644 --- a/src/odbc/unittests/funccall.c +++ b/src/odbc/unittests/funccall.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test for {?=call store(?)} syntax and run */ static void test_with_conversions(void); diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c index e6ab4ac088..5166ff3019 100644 --- a/src/odbc/unittests/genparams.c +++ b/src/odbc/unittests/genparams.c @@ -1,7 +1,8 @@ #include "common.h" -#include #include +#include + /* Test various type from odbc and to odbc */ /* diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c index d556651791..12fd8567ca 100644 --- a/src/odbc/unittests/getdata.c +++ b/src/odbc/unittests/getdata.c @@ -2,7 +2,8 @@ * Test reading data with SQLGetData */ #include "common.h" -#include + +#include static void test_err(const char *data, int c_type, const char *state) diff --git a/src/odbc/unittests/hidden.c b/src/odbc/unittests/hidden.c index fa2c4906f9..8344a900da 100644 --- a/src/odbc/unittests/hidden.c +++ b/src/odbc/unittests/hidden.c @@ -3,6 +3,8 @@ #include "common.h" +#include + int main(void) { diff --git a/src/odbc/unittests/insert_speed.c b/src/odbc/unittests/insert_speed.c index 0d71c50202..5da336772e 100644 --- a/src/odbc/unittests/insert_speed.c +++ b/src/odbc/unittests/insert_speed.c @@ -1,5 +1,6 @@ #include "common.h" -#include + +#include #define SQL_QUERY_LENGTH 80 diff --git a/src/odbc/unittests/lang_error.c b/src/odbc/unittests/lang_error.c index 644dce613a..26bcbc7463 100644 --- a/src/odbc/unittests/lang_error.c +++ b/src/odbc/unittests/lang_error.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test if SQLExecDirect return error if a error in row is returned */ int diff --git a/src/odbc/unittests/long_error.c b/src/odbc/unittests/long_error.c index 542295dab0..fc8f938ba2 100644 --- a/src/odbc/unittests/long_error.c +++ b/src/odbc/unittests/long_error.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Demonstration of triggered assert when invoking this stored procedure diff --git a/src/odbc/unittests/mars1.c b/src/odbc/unittests/mars1.c index 149fbd939c..c744754d3b 100644 --- a/src/odbc/unittests/mars1.c +++ b/src/odbc/unittests/mars1.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* first MARS test, test 2 concurrent recordset */ #define SET_STMT(n) do { \ diff --git a/src/odbc/unittests/moreandcount.c b/src/odbc/unittests/moreandcount.c index e7afbf140b..ea0d6e94b5 100644 --- a/src/odbc/unittests/moreandcount.c +++ b/src/odbc/unittests/moreandcount.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test for SQLMoreResults and SQLRowCount on batch */ static void diff --git a/src/odbc/unittests/moreresults.c b/src/odbc/unittests/moreresults.c index aad26e0a3c..7e9ca0a4ed 100644 --- a/src/odbc/unittests/moreresults.c +++ b/src/odbc/unittests/moreresults.c @@ -1,6 +1,8 @@ #include "common.h" #include +#include + /* Test for SQLMoreResults */ static void diff --git a/src/odbc/unittests/norowset.c b/src/odbc/unittests/norowset.c index e188deb973..24c8c29757 100644 --- a/src/odbc/unittests/norowset.c +++ b/src/odbc/unittests/norowset.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test that a select following a store procedure execution return results */ int diff --git a/src/odbc/unittests/oldpwd.c b/src/odbc/unittests/oldpwd.c index 18c8696273..87d0b70b10 100644 --- a/src/odbc/unittests/oldpwd.c +++ b/src/odbc/unittests/oldpwd.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* change password on server */ static void diff --git a/src/odbc/unittests/paramcore.c b/src/odbc/unittests/paramcore.c index a3c305492e..577b1c4011 100644 --- a/src/odbc/unittests/paramcore.c +++ b/src/odbc/unittests/paramcore.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* * Try to make core dump using SQLBindParameter */ diff --git a/src/odbc/unittests/params.c b/src/odbc/unittests/params.c index 8db70f2ea7..555cf4b49e 100644 --- a/src/odbc/unittests/params.c +++ b/src/odbc/unittests/params.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test for store procedure and params */ /* Test from Tom Rogers */ diff --git a/src/odbc/unittests/parser.c b/src/odbc/unittests/parser.c index 9a90869b40..a809ac5856 100644 --- a/src/odbc/unittests/parser.c +++ b/src/odbc/unittests/parser.c @@ -2,10 +2,11 @@ * Test reading data with SQLBindCol */ #include "common.h" -#include #include #include "parser.h" +#include + unsigned int odbc_line_num; void diff --git a/src/odbc/unittests/peter.c b/src/odbc/unittests/peter.c index 94aeb5b7ef..5f6f734296 100644 --- a/src/odbc/unittests/peter.c +++ b/src/odbc/unittests/peter.c @@ -1,6 +1,7 @@ #undef NDEBUG #include "common.h" -#include + +#include /* Test SQLNumResultCols after SQLFreeStmt diff --git a/src/odbc/unittests/prepare_results.c b/src/odbc/unittests/prepare_results.c index 54915257df..901972a2b3 100644 --- a/src/odbc/unittests/prepare_results.c +++ b/src/odbc/unittests/prepare_results.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test for data format returned from SQLPrepare */ static void diff --git a/src/odbc/unittests/prepare_warn.c b/src/odbc/unittests/prepare_warn.c index 3b7aa42237..a7c2a68b7a 100644 --- a/src/odbc/unittests/prepare_warn.c +++ b/src/odbc/unittests/prepare_warn.c @@ -8,6 +8,8 @@ #include "common.h" +#include + int main(void) { diff --git a/src/odbc/unittests/prepclose.c b/src/odbc/unittests/prepclose.c index 355bce90b1..f932777386 100644 --- a/src/odbc/unittests/prepclose.c +++ b/src/odbc/unittests/prepclose.c @@ -22,6 +22,8 @@ #include +#include + /* * test error on connection close * With a trick we simulate a connection close then we try to diff --git a/src/odbc/unittests/preperror.c b/src/odbc/unittests/preperror.c index 302050b867..04cff8e4a2 100644 --- a/src/odbc/unittests/preperror.c +++ b/src/odbc/unittests/preperror.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* test error on prepared statement, from Nathaniel Talbott test */ int diff --git a/src/odbc/unittests/print.c b/src/odbc/unittests/print.c index b874049108..327481fd9e 100644 --- a/src/odbc/unittests/print.c +++ b/src/odbc/unittests/print.c @@ -1,5 +1,7 @@ #include "common.h" +#include + static SQLCHAR output[256]; #ifdef TDS_NO_DM diff --git a/src/odbc/unittests/putdata.c b/src/odbc/unittests/putdata.c index 5bf128d1eb..b03e9ebbf7 100644 --- a/src/odbc/unittests/putdata.c +++ b/src/odbc/unittests/putdata.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test for SQLPutData */ static const char test_text[] = diff --git a/src/odbc/unittests/qn.c b/src/odbc/unittests/qn.c index 8249c07ae0..c6f5430423 100644 --- a/src/odbc/unittests/qn.c +++ b/src/odbc/unittests/qn.c @@ -1,10 +1,11 @@ #include "common.h" -#include #include "odbcss.h" #include #include +#include + /* test query notifications */ #ifdef TDS_HAVE_MUTEX diff --git a/src/odbc/unittests/raiserror.c b/src/odbc/unittests/raiserror.c index 7a4ffce94a..d8919f09ac 100644 --- a/src/odbc/unittests/raiserror.c +++ b/src/odbc/unittests/raiserror.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* test RAISERROR in a store procedure, from Tom Rogers tests */ /* TODO add support for Sybase */ diff --git a/src/odbc/unittests/rebindpar.c b/src/odbc/unittests/rebindpar.c index 8611a578a2..81270a8e30 100644 --- a/src/odbc/unittests/rebindpar.c +++ b/src/odbc/unittests/rebindpar.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test for executing SQLExecute and rebinding parameters */ #define SWAP_STMT(b) do { SQLHSTMT xyz = odbc_stmt; odbc_stmt = b; b = xyz; } while(0) diff --git a/src/odbc/unittests/rownumber.c b/src/odbc/unittests/rownumber.c index 65749f0a16..67cb20459c 100644 --- a/src/odbc/unittests/rownumber.c +++ b/src/odbc/unittests/rownumber.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test for SQL_ATTR_ROW_NUMBER */ /* diff --git a/src/odbc/unittests/rowset.c b/src/odbc/unittests/rowset.c index 692f3d29f0..14a61bc94d 100644 --- a/src/odbc/unittests/rowset.c +++ b/src/odbc/unittests/rowset.c @@ -1,5 +1,7 @@ #include "common.h" +#include + static void test_err(int n) { diff --git a/src/odbc/unittests/rpc.c b/src/odbc/unittests/rpc.c index 1f1a84b9fb..f095c7d601 100644 --- a/src/odbc/unittests/rpc.c +++ b/src/odbc/unittests/rpc.c @@ -4,7 +4,8 @@ */ #include "common.h" -#include + +#include static const char procedure_sql[] = "CREATE PROCEDURE %s \n" diff --git a/src/odbc/unittests/scroll.c b/src/odbc/unittests/scroll.c index 501a700f79..4003a61e45 100644 --- a/src/odbc/unittests/scroll.c +++ b/src/odbc/unittests/scroll.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test cursors */ int diff --git a/src/odbc/unittests/stats.c b/src/odbc/unittests/stats.c index 942536dc76..1d3d68c2ae 100644 --- a/src/odbc/unittests/stats.c +++ b/src/odbc/unittests/stats.c @@ -1,5 +1,7 @@ #include "common.h" +#include + static SQLLEN cnamesize; static char output[256]; diff --git a/src/odbc/unittests/t0001.c b/src/odbc/unittests/t0001.c index bda246e0e6..228fb8fc82 100644 --- a/src/odbc/unittests/t0001.c +++ b/src/odbc/unittests/t0001.c @@ -1,5 +1,7 @@ #include "common.h" +#include + int main(void) { diff --git a/src/odbc/unittests/t0002.c b/src/odbc/unittests/t0002.c index 7d4f703887..a54c27df66 100644 --- a/src/odbc/unittests/t0002.c +++ b/src/odbc/unittests/t0002.c @@ -1,5 +1,7 @@ #include "common.h" +#include + #define SWAP_STMT() do { SQLHSTMT xyz = odbc_stmt; \ odbc_stmt = old_odbc_stmt; old_odbc_stmt = xyz; } while(0) diff --git a/src/odbc/unittests/t0003.c b/src/odbc/unittests/t0003.c index 9fec662a86..a93dafdaba 100644 --- a/src/odbc/unittests/t0003.c +++ b/src/odbc/unittests/t0003.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test for SQLMoreResults */ static void diff --git a/src/odbc/unittests/tables.c b/src/odbc/unittests/tables.c index 647e576abc..cd7eccbc14 100644 --- a/src/odbc/unittests/tables.c +++ b/src/odbc/unittests/tables.c @@ -1,5 +1,7 @@ #include "common.h" +#include + #ifdef _WIN32 #undef strcasecmp #define strcasecmp stricmp diff --git a/src/odbc/unittests/test64.c b/src/odbc/unittests/test64.c index 79113c340d..7a0bb3b94a 100644 --- a/src/odbc/unittests/test64.c +++ b/src/odbc/unittests/test64.c @@ -1,6 +1,8 @@ /* test win64 consistency */ #include "common.h" +#include + /* set ipd processed_ptr with SQLParamOptions/SQLSetDescField/SQL_ATTR_PARAMS_PROCESSED_PTR diff --git a/src/odbc/unittests/testodbc.c b/src/odbc/unittests/testodbc.c index c16fb22994..9642080f03 100644 --- a/src/odbc/unittests/testodbc.c +++ b/src/odbc/unittests/testodbc.c @@ -10,6 +10,8 @@ #include "common.h" +#include + #ifdef DEBUG # define AB_FUNCT(x) do { printf x; printf("\n"); } while(0) # define AB_PRINT(x) do { printf x; printf("\n"); } while(0) diff --git a/src/odbc/unittests/timeout.c b/src/odbc/unittests/timeout.c index 45e3daa394..100241be8d 100644 --- a/src/odbc/unittests/timeout.c +++ b/src/odbc/unittests/timeout.c @@ -1,5 +1,6 @@ #include "common.h" -#include + +#include /* Test timeout of query */ diff --git a/src/odbc/unittests/timeout2.c b/src/odbc/unittests/timeout2.c index 5639c386e9..48131c2769 100644 --- a/src/odbc/unittests/timeout2.c +++ b/src/odbc/unittests/timeout2.c @@ -4,11 +4,11 @@ #include #endif -#include - #include #include +#include + /* * Test timeout on prepare * It execute a query wait for timeout and then try to issue a new prepare/execute diff --git a/src/odbc/unittests/timeout3.c b/src/odbc/unittests/timeout3.c index de7c0da55a..26cea6ba30 100644 --- a/src/odbc/unittests/timeout3.c +++ b/src/odbc/unittests/timeout3.c @@ -30,6 +30,8 @@ #include #include +#include + #if TDS_HAVE_MUTEX static void init_connect(void); diff --git a/src/odbc/unittests/timeout4.c b/src/odbc/unittests/timeout4.c index 1dcf6ee5c9..7374057ce1 100644 --- a/src/odbc/unittests/timeout4.c +++ b/src/odbc/unittests/timeout4.c @@ -24,6 +24,8 @@ #include +#include + /* * test error on connection close * With a trick we simulate a connection close then we try to diff --git a/src/odbc/unittests/transaction.c b/src/odbc/unittests/transaction.c index 00cf987e2b..db8350cfa5 100644 --- a/src/odbc/unittests/transaction.c +++ b/src/odbc/unittests/transaction.c @@ -1,6 +1,8 @@ #include "common.h" #include +#include + static int Test(bool discard_test) { diff --git a/src/odbc/unittests/transaction2.c b/src/odbc/unittests/transaction2.c index da3b13bdde..34ddddac1c 100644 --- a/src/odbc/unittests/transaction2.c +++ b/src/odbc/unittests/transaction2.c @@ -1,5 +1,6 @@ #include "common.h" -#include + +#include /* Test transaction types */ diff --git a/src/odbc/unittests/transaction3.c b/src/odbc/unittests/transaction3.c index 06369107e1..3503fe1a5e 100644 --- a/src/odbc/unittests/transaction3.c +++ b/src/odbc/unittests/transaction3.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* Test commit/rollback with auto commit set to on (the default) */ int main(void) diff --git a/src/odbc/unittests/transaction4.c b/src/odbc/unittests/transaction4.c index c3b057068f..211277528f 100644 --- a/src/odbc/unittests/transaction4.c +++ b/src/odbc/unittests/transaction4.c @@ -22,6 +22,8 @@ #include +#include + /* Test for SQLEndTran */ static void diff --git a/src/odbc/unittests/tvp.c b/src/odbc/unittests/tvp.c index ccf2b331ce..eb2c8954d1 100644 --- a/src/odbc/unittests/tvp.c +++ b/src/odbc/unittests/tvp.c @@ -1,7 +1,6 @@ /* Test binding and calling of TVPs */ #include "common.h" -#include #include #undef MEMORY_TESTS @@ -20,6 +19,8 @@ #include +#include + #define MAX_ROWS 5 #define MAX_STRING_LENGTH 20 diff --git a/src/odbc/unittests/type.c b/src/odbc/unittests/type.c index d0a46d83f2..72be54ff51 100644 --- a/src/odbc/unittests/type.c +++ b/src/odbc/unittests/type.c @@ -1,5 +1,6 @@ #include "common.h" -#include + +#include struct type { diff --git a/src/odbc/unittests/typeinfo.c b/src/odbc/unittests/typeinfo.c index 45b293678a..1fd5d07f76 100644 --- a/src/odbc/unittests/typeinfo.c +++ b/src/odbc/unittests/typeinfo.c @@ -1,5 +1,7 @@ #include "common.h" +#include + static void TestName(int index, const char *expected_name) { diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c index 71f75459bd..134eefec9f 100644 --- a/src/odbc/unittests/utf8.c +++ b/src/odbc/unittests/utf8.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* test binding with UTF-8 encoding */ #ifndef _WIN32 diff --git a/src/odbc/unittests/utf8_2.c b/src/odbc/unittests/utf8_2.c index cc740a0fa3..bba8003d99 100644 --- a/src/odbc/unittests/utf8_2.c +++ b/src/odbc/unittests/utf8_2.c @@ -1,6 +1,8 @@ #include "common.h" #include +#include + /* test conversion of Hebrew characters (which have shift sequences) */ static const char * const column_names[] = { diff --git a/src/odbc/unittests/utf8_3.c b/src/odbc/unittests/utf8_3.c index a37f49225f..a8000d5ea4 100644 --- a/src/odbc/unittests/utf8_3.c +++ b/src/odbc/unittests/utf8_3.c @@ -1,5 +1,6 @@ #include "common.h" -#include + +#include /* test conversion using SQLGetData */ diff --git a/src/odbc/unittests/utf8_4.c b/src/odbc/unittests/utf8_4.c index a55b10eb5d..376e0ed893 100644 --- a/src/odbc/unittests/utf8_4.c +++ b/src/odbc/unittests/utf8_4.c @@ -1,9 +1,10 @@ #undef NDEBUG #include "common.h" -#include #include #include +#include + /* test some internal funcions */ #ifdef _WIN32 diff --git a/src/odbc/unittests/warning.c b/src/odbc/unittests/warning.c index bf338bf9fe..633c73d753 100644 --- a/src/odbc/unittests/warning.c +++ b/src/odbc/unittests/warning.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* * Test originally written by John K. Hohm * (cfr "Warning return as copy of last result row (was: Warning: Null value diff --git a/src/odbc/unittests/wchar.c b/src/odbc/unittests/wchar.c index deb86508d5..5d548310fd 100644 --- a/src/odbc/unittests/wchar.c +++ b/src/odbc/unittests/wchar.c @@ -1,5 +1,7 @@ #include "common.h" +#include + /* test SQL_C_DEFAULT with NCHAR type */ int diff --git a/src/replacements/unittests/strings.c b/src/replacements/unittests/strings.c index 8d9f6364b8..c4f2fc2dbe 100644 --- a/src/replacements/unittests/strings.c +++ b/src/replacements/unittests/strings.c @@ -26,8 +26,6 @@ #include #endif /* HAVE_STDLIB_H */ -#include - #include /* If the system supplies these, we're going to simulate the situation @@ -43,6 +41,8 @@ size_t tds_strlcat(char *dest, const char *src, size_t len); #include "../strlcat.c" #endif +#include + int main(void) { char *buf = (char *) malloc(10); diff --git a/src/replacements/unittests/strsep.c b/src/replacements/unittests/strsep.c index d3d8ef15fc..c419ac9118 100644 --- a/src/replacements/unittests/strsep.c +++ b/src/replacements/unittests/strsep.c @@ -36,7 +36,8 @@ char *tds_strsep(char **stringp, const char *delim); #include #include -#include + +#include /* test strsep with same separators */ static void diff --git a/src/replacements/unittests/strtok_r.c b/src/replacements/unittests/strtok_r.c index f8a159026c..dad6c801ea 100644 --- a/src/replacements/unittests/strtok_r.c +++ b/src/replacements/unittests/strtok_r.c @@ -31,6 +31,8 @@ #include +#include + static void test(const char *s, const char *sep) { diff --git a/src/tds/unittests/allcolumns.c b/src/tds/unittests/allcolumns.c index abf9c00178..49d0f8b4f2 100644 --- a/src/tds/unittests/allcolumns.c +++ b/src/tds/unittests/allcolumns.c @@ -20,10 +20,11 @@ #define TDS_DONT_DEFINE_DEFAULT_FUNCTIONS #include "common.h" -#include #include #include +#include + static bool is_convert_pointer_type(int type) { diff --git a/src/tds/unittests/charconv.c b/src/tds/unittests/charconv.c index d8f901be26..3d85a1f7ae 100644 --- a/src/tds/unittests/charconv.c +++ b/src/tds/unittests/charconv.c @@ -44,7 +44,7 @@ #include #endif /* HAVE_STDLIB_H */ -#include +#include /* test tds_bcp_fread */ diff --git a/src/tds/unittests/collations.c b/src/tds/unittests/collations.c index 7566d5b20b..7326122383 100644 --- a/src/tds/unittests/collations.c +++ b/src/tds/unittests/collations.c @@ -23,7 +23,6 @@ #undef NDEBUG #include -#include #if HAVE_UNISTD_H #undef getpid @@ -34,6 +33,8 @@ # define isatty(fd) _isatty(fd) #endif /* HAVE_UNISTD_H */ +#include + static TDSSOCKET *tds; static void diff --git a/src/tds/unittests/common.c b/src/tds/unittests/common.c index 9239417fc2..bf29a7f9b7 100644 --- a/src/tds/unittests/common.c +++ b/src/tds/unittests/common.c @@ -2,6 +2,8 @@ #include "common.h" #include +#include + char USER[512]; char SERVER[512]; char PASSWORD[512]; diff --git a/src/tds/unittests/convert.c b/src/tds/unittests/convert.c index 6e8482706d..f63d0e319c 100644 --- a/src/tds/unittests/convert.c +++ b/src/tds/unittests/convert.c @@ -24,12 +24,13 @@ * $ make convert && ./convert 1 |grep iterations |grep 'varchar\.' |sort -n */ #include "common.h" -#include #include #include #include +#include + static int g_result = 0; static TDSCONTEXT *ctx; diff --git a/src/tds/unittests/convert_bounds.c b/src/tds/unittests/convert_bounds.c index 48bbb099ea..e68991beae 100644 --- a/src/tds/unittests/convert_bounds.c +++ b/src/tds/unittests/convert_bounds.c @@ -21,10 +21,11 @@ * Purpose: test conversion bounds of integers and floating points. */ #include "common.h" -#include #include #include +#include + static TDS_INT convert_and_free(int srctype, const void *src, TDS_UINT srclen, int desttype, CONV_RESULT *cr); static bool is_valid(const char *num, int type, CONV_RESULT *cr); static double convert_to_float(smp n, int type); diff --git a/src/tds/unittests/corrupt.c b/src/tds/unittests/corrupt.c index 317a5ce23d..03d325db66 100644 --- a/src/tds/unittests/corrupt.c +++ b/src/tds/unittests/corrupt.c @@ -26,6 +26,8 @@ #include "common.h" #include +#include + static const char select_query[] = "\nselect 'test'"; static void diff --git a/src/tds/unittests/dataread.c b/src/tds/unittests/dataread.c index b34622444a..a242dd68b2 100644 --- a/src/tds/unittests/dataread.c +++ b/src/tds/unittests/dataread.c @@ -23,9 +23,10 @@ */ #include "common.h" -#include #include +#include + static int g_result = 0; static TDSLOGIN *login; static TDSSOCKET *tds; diff --git a/src/tds/unittests/declarations.c b/src/tds/unittests/declarations.c index 7779c73e54..12a28a9e8c 100644 --- a/src/tds/unittests/declarations.c +++ b/src/tds/unittests/declarations.c @@ -21,7 +21,8 @@ * Purpose: test we can declare any possible column type. */ #include "common.h" -#include + +#include static void test_declaration(TDSSOCKET *tds, TDSCOLUMN *curcol) { diff --git a/src/tds/unittests/dynamic1.c b/src/tds/unittests/dynamic1.c index 0ca389ad86..76492f7d1b 100644 --- a/src/tds/unittests/dynamic1.c +++ b/src/tds/unittests/dynamic1.c @@ -18,6 +18,8 @@ */ #include "common.h" +#include + static int discard_result(TDSSOCKET * tds); static void diff --git a/src/tds/unittests/flags.c b/src/tds/unittests/flags.c index 57d5eee127..fe3fb8519a 100644 --- a/src/tds/unittests/flags.c +++ b/src/tds/unittests/flags.c @@ -21,6 +21,8 @@ #include +#include + static TDSLOGIN *login; static TDSSOCKET *tds; diff --git a/src/tds/unittests/freeze.c b/src/tds/unittests/freeze.c index db37072ce9..c8e7c50efa 100644 --- a/src/tds/unittests/freeze.c +++ b/src/tds/unittests/freeze.c @@ -21,7 +21,6 @@ * Purpose: test freeze functionality */ #include "common.h" -#include #include #if HAVE_UNISTD_H @@ -31,6 +30,8 @@ #include +#include + #ifdef TDS_HAVE_MUTEX #ifdef _WIN32 #define SHUT_WR SD_SEND diff --git a/src/tds/unittests/iconv_fread.c b/src/tds/unittests/iconv_fread.c index 4911dc63d6..f2374383b9 100644 --- a/src/tds/unittests/iconv_fread.c +++ b/src/tds/unittests/iconv_fread.c @@ -29,7 +29,7 @@ #include #endif /* HAVE_STDLIB_H */ -#include +#include /* test tds_bcp_fread */ diff --git a/src/tds/unittests/log_elision.c b/src/tds/unittests/log_elision.c index 4818f07131..66965e4127 100644 --- a/src/tds/unittests/log_elision.c +++ b/src/tds/unittests/log_elision.c @@ -21,7 +21,6 @@ * Check log elision implementation */ #include "common.h" -#include #include #if HAVE_UNISTD_H @@ -29,6 +28,8 @@ #include #endif /* HAVE_UNISTD_H */ +#include + #ifdef TDS_HAVE_MUTEX enum { LOOP = 100, diff --git a/src/tds/unittests/nulls.c b/src/tds/unittests/nulls.c index 98a72dbbcb..8de55f4452 100644 --- a/src/tds/unittests/nulls.c +++ b/src/tds/unittests/nulls.c @@ -18,6 +18,8 @@ */ #include "common.h" +#include + int main(void) { diff --git a/src/tds/unittests/numeric.c b/src/tds/unittests/numeric.c index c4d91b3b35..bc5db23b92 100644 --- a/src/tds/unittests/numeric.c +++ b/src/tds/unittests/numeric.c @@ -19,7 +19,8 @@ #include "common.h" #include -#include + +#include /* test numeric scale */ diff --git a/src/tds/unittests/parsing.c b/src/tds/unittests/parsing.c index 9d110b345a..a4166e7aa0 100644 --- a/src/tds/unittests/parsing.c +++ b/src/tds/unittests/parsing.c @@ -24,6 +24,8 @@ #include +#include + static void test_generic(const char *s, int expected_pos, bool comment, int line) { diff --git a/src/tds/unittests/portconf.c b/src/tds/unittests/portconf.c index be0456ed47..37e8cda904 100644 --- a/src/tds/unittests/portconf.c +++ b/src/tds/unittests/portconf.c @@ -19,6 +19,8 @@ #include "common.h" #include +#include + static void set_interface(void) { diff --git a/src/tds/unittests/readconf.c b/src/tds/unittests/readconf.c index b0a57b6a1a..25ea9a8af2 100644 --- a/src/tds/unittests/readconf.c +++ b/src/tds/unittests/readconf.c @@ -18,6 +18,8 @@ */ #include "common.h" +#include + static FILE *f = NULL; static char *return_value = NULL; diff --git a/src/tds/unittests/strftime.c b/src/tds/unittests/strftime.c index 93d3bc0244..ed318dc7c6 100644 --- a/src/tds/unittests/strftime.c +++ b/src/tds/unittests/strftime.c @@ -22,10 +22,11 @@ * This is a wrapper to strftime for portability and extension. */ #include "common.h" -#include #include #include +#include + static void test(const TDSDATEREC* dr, int prec, const char *fmt, const char *expected, int line) { diff --git a/src/tds/unittests/t0001.c b/src/tds/unittests/t0001.c index b3aee56a76..c8606314bd 100644 --- a/src/tds/unittests/t0001.c +++ b/src/tds/unittests/t0001.c @@ -22,6 +22,8 @@ */ #include "common.h" +#include + int main(void) { diff --git a/src/tds/unittests/t0002.c b/src/tds/unittests/t0002.c index dab41622e6..10897cf467 100644 --- a/src/tds/unittests/t0002.c +++ b/src/tds/unittests/t0002.c @@ -21,6 +21,8 @@ #include #include +#include + static char * value_as_string(TDSSOCKET * tds, int col_idx) { diff --git a/src/tds/unittests/t0003.c b/src/tds/unittests/t0003.c index 42b5aef51b..6c9872954d 100644 --- a/src/tds/unittests/t0003.c +++ b/src/tds/unittests/t0003.c @@ -18,6 +18,8 @@ */ #include "common.h" +#include + int main(void) { diff --git a/src/tds/unittests/t0004.c b/src/tds/unittests/t0004.c index 31e734f95a..addf8ff38a 100644 --- a/src/tds/unittests/t0004.c +++ b/src/tds/unittests/t0004.c @@ -19,6 +19,8 @@ #include "common.h" #include +#include + static char * varchar_as_string(TDSSOCKET * tds, int col_idx) { diff --git a/src/tds/unittests/t0005.c b/src/tds/unittests/t0005.c index 66629cd353..fa78bf8503 100644 --- a/src/tds/unittests/t0005.c +++ b/src/tds/unittests/t0005.c @@ -19,6 +19,8 @@ #include "common.h" #include +#include + static char *value_as_string(TDSSOCKET * tds, int col_idx); int diff --git a/src/tds/unittests/t0006.c b/src/tds/unittests/t0006.c index 59a1e6ab5f..1c26059810 100644 --- a/src/tds/unittests/t0006.c +++ b/src/tds/unittests/t0006.c @@ -19,6 +19,8 @@ #include "common.h" #include +#include + static TDSCONTEXT ctx; int diff --git a/src/tds/unittests/t0007.c b/src/tds/unittests/t0007.c index 3f25f24753..8902aa32e6 100644 --- a/src/tds/unittests/t0007.c +++ b/src/tds/unittests/t0007.c @@ -26,6 +26,8 @@ #include "common.h" #include +#include + static TDSCONTEXT ctx; static void diff --git a/src/tds/unittests/t0008.c b/src/tds/unittests/t0008.c index fe15d787c1..f326053b0f 100644 --- a/src/tds/unittests/t0008.c +++ b/src/tds/unittests/t0008.c @@ -21,6 +21,8 @@ #include "common.h" #include +#include + static int g_result = 0; static TDSCONTEXT ctx; diff --git a/src/tds/unittests/tls.c b/src/tds/unittests/tls.c index b2c52a3dd1..c41349a223 100644 --- a/src/tds/unittests/tls.c +++ b/src/tds/unittests/tls.c @@ -28,6 +28,8 @@ #include +#include + /* This certificate has common name as "www.abc.com" and alternate names as "xyz.org", "127.0.0.1", "::2:3:4:5:6" and "192.168.127.1". */ static const char certificate[] = diff --git a/src/tds/unittests/toodynamic.c b/src/tds/unittests/toodynamic.c index c5520c2d6e..aff2e0f850 100644 --- a/src/tds/unittests/toodynamic.c +++ b/src/tds/unittests/toodynamic.c @@ -18,6 +18,8 @@ */ #include "common.h" +#include + /* * Test creating a lot of dynamics. This can cause some problems cause * generated IDs are reused on a base of 2^16 diff --git a/src/tds/unittests/utf8.c b/src/tds/unittests/utf8.c index 540b69d830..08574a2df1 100644 --- a/src/tds/unittests/utf8.c +++ b/src/tds/unittests/utf8.c @@ -21,7 +21,8 @@ #include "common.h" #include -#include + +#include int utf8_max_len = 0; diff --git a/src/tds/unittests/utf8_1.c b/src/tds/unittests/utf8_1.c index 5a7bdd235f..da9bd0e0ce 100644 --- a/src/tds/unittests/utf8_1.c +++ b/src/tds/unittests/utf8_1.c @@ -20,7 +20,8 @@ #include "common.h" #include -#include + +#include static TDSSOCKET *tds; diff --git a/src/tds/unittests/utf8_2.c b/src/tds/unittests/utf8_2.c index 400ade0ed9..803928722b 100644 --- a/src/tds/unittests/utf8_2.c +++ b/src/tds/unittests/utf8_2.c @@ -19,7 +19,8 @@ #include "common.h" #include -#include + +#include /* try conversion from utf8 to iso8859-1 */ diff --git a/src/tds/unittests/utf8_3.c b/src/tds/unittests/utf8_3.c index 3bfa769707..48822769e4 100644 --- a/src/tds/unittests/utf8_3.c +++ b/src/tds/unittests/utf8_3.c @@ -22,7 +22,8 @@ #include #include #include -#include + +#include static TDSSOCKET *tds; diff --git a/src/utils/unittests/bytes.c b/src/utils/unittests/bytes.c index 0a51fa63be..fbf75b6703 100644 --- a/src/utils/unittests/bytes.c +++ b/src/utils/unittests/bytes.c @@ -24,7 +24,6 @@ #include #include -#include #ifdef HAVE_STRING_H #include @@ -33,6 +32,8 @@ #include "tds_sysdep_public.h" #include +#include + #define WRITE(buf, off, bytes, endian, val) do { \ if ((off % bytes) == 0) TDS_PUT_A ## bytes ## endian(buf+off, val); \ else TDS_PUT_UA ## bytes ## endian(buf+off, val); \ diff --git a/src/utils/unittests/challenge.c b/src/utils/unittests/challenge.c index 4607a8ada5..dea577a4fd 100644 --- a/src/utils/unittests/challenge.c +++ b/src/utils/unittests/challenge.c @@ -24,7 +24,6 @@ #include #include -#include #if HAVE_STDLIB_H #include @@ -41,6 +40,8 @@ #include #include +#include + static char long_string[512]; static char * diff --git a/src/utils/unittests/condition.c b/src/utils/unittests/condition.c index a8e7fe8372..e75f701f81 100644 --- a/src/utils/unittests/condition.c +++ b/src/utils/unittests/condition.c @@ -34,6 +34,8 @@ #include #include +#include + #if !defined(TDS_NO_THREADSAFE) static tds_mutex mtx = TDS_MUTEX_INITIALIZER; diff --git a/src/utils/unittests/dlist.c b/src/utils/unittests/dlist.c index 35fca0e46d..68e2a87ced 100644 --- a/src/utils/unittests/dlist.c +++ b/src/utils/unittests/dlist.c @@ -24,12 +24,13 @@ #include #include -#include #ifdef HAVE_STRING_H #include #endif +#include + #include typedef struct diff --git a/src/utils/unittests/mutex1.c b/src/utils/unittests/mutex1.c index 49bfd8a546..9efb626b60 100644 --- a/src/utils/unittests/mutex1.c +++ b/src/utils/unittests/mutex1.c @@ -28,6 +28,8 @@ #include #include +#include + #if !defined(TDS_NO_THREADSAFE) static tds_mutex mtx = TDS_MUTEX_INITIALIZER; diff --git a/src/utils/unittests/passarg.c b/src/utils/unittests/passarg.c index e254d0a9cb..be53adbd78 100644 --- a/src/utils/unittests/passarg.c +++ b/src/utils/unittests/passarg.c @@ -33,11 +33,11 @@ #include #endif /* HAVE_STRING_H */ -#include - #include #include +#include + int main(void) { FILE *f; diff --git a/src/utils/unittests/path.c b/src/utils/unittests/path.c index 15c02ca167..e812cebbb7 100644 --- a/src/utils/unittests/path.c +++ b/src/utils/unittests/path.c @@ -23,7 +23,6 @@ #undef NDEBUG #include -#include #include #include #include @@ -35,6 +34,8 @@ #include #include +#include + #ifdef _WIN32 enum { is_windows = 1 }; #else diff --git a/src/utils/unittests/smp.c b/src/utils/unittests/smp.c index e9efff8713..8e157adf67 100644 --- a/src/utils/unittests/smp.c +++ b/src/utils/unittests/smp.c @@ -23,7 +23,6 @@ #undef NDEBUG #include -#include #include #include #include @@ -31,6 +30,8 @@ #include #include +#include + static void same_smp(smp n, const char *s, int line) { From ac039551c8bafd44950d407e906abdef1d43c5bb Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Thu, 9 May 2024 14:23:58 -0400 Subject: [PATCH 07/49] tds_setup_connection: Skip nvc/uvc check under OpenServer. OpenServer instances may well report "Unknown language request" for it, resulting in outright login failures. --- src/tds/login.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tds/login.c b/src/tds/login.c index f754f63243..d63545470e 100644 --- a/src/tds/login.c +++ b/src/tds/login.c @@ -440,7 +440,9 @@ tds_setup_connection(TDSSOCKET *tds, TDSLOGIN *login, bool set_db, bool set_spid tds_quote_id(tds, strchr(str, 0), tds_dstr_cstr(&login->database), -1); strcat(str, "\n"); } - if (IS_TDS50(tds->conn)) { + if (IS_TDS50(tds->conn) + && (tds->conn->product_name == NULL + || strcasecmp(tds->conn->product_name, "OpenServer") != 0)) { strcat(str, "SELECT CONVERT(NVARCHAR(3), 'abc') nvc\n" "EXECUTE ('SELECT CONVERT(UNIVARCHAR(3), ''xyz'') uvc')\n"); parse_results = true; From 5ed7413f16f2a23799573e5a2ff18e84dc5adfad Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Thu, 9 May 2024 15:42:10 -0400 Subject: [PATCH 08/49] tds7_send_record: Reject invalid NULL data. When the user erroneously supplies NULL data for a column which does not use a nullable type and is not otherwise known to be nullable, cleanly fail. Pressing on anyway (in hopes that a server-side default would take effect?) was liable to trigger legitimate assertion failures in tds_checks.c. To that end, take the null_error callback and invoke it before bailing unless it is itself NULL. --- src/tds/bulk.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/tds/bulk.c b/src/tds/bulk.c index 12968d4f5c..454d235d22 100644 --- a/src/tds/bulk.c +++ b/src/tds/bulk.c @@ -328,7 +328,9 @@ tds_bcp_start_insert_stmt(TDSSOCKET * tds, TDSBCPINFO * bcpinfo) } static TDSRET -tds7_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, int offset) +tds7_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, + tds_bcp_get_col_data get_col_data, + tds_bcp_null_error null_error, int offset) { int i; @@ -366,6 +368,13 @@ tds7_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_c save_data = bindcol->column_data; assert(bindcol->column_data == NULL); if (bindcol->bcp_column_data->is_null) { + if ( !bindcol->column_nullable + && !is_nullable_type(bindcol->on_server + .column_type) ) { + if (null_error) + null_error(bcpinfo, i, offset); + return TDS_FAIL; + } bindcol->column_cur_size = -1; } else if (is_blob_col(bindcol)) { bindcol->column_cur_size = bindcol->bcp_column_data->datalen; @@ -478,7 +487,8 @@ tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, return TDS_FAIL; if (IS_TDS7_PLUS(tds->conn)) - rc = tds7_send_record(tds, bcpinfo, get_col_data, offset); + rc = tds7_send_record(tds, bcpinfo, get_col_data, null_error, + offset); else rc = tds5_send_record(tds, bcpinfo, get_col_data, null_error, offset); From f04bf65d34467eef593bb84e1747a6be62c52f13 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Thu, 9 May 2024 16:20:17 -0400 Subject: [PATCH 09/49] Improve type handling, at least for Sybase. * odbc_sql2tds: Treat SYB5INT8 like other numeric types. * tds_generic_get: Handle non-blob types with four-byte sizes (e.g., XSYBCHAR at least some of the time). * tds_generic_put_info: Send size 255 (0xff) for NULL short character types in output columns. --- src/odbc/sql2tds.c | 1 + src/tds/data.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c index 50db6e06b4..a1b7b709ae 100644 --- a/src/odbc/sql2tds.c +++ b/src/odbc/sql2tds.c @@ -571,6 +571,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ixd, const struct _dre case SYBINT2: case SYBINT4: case SYBINT8: + case SYB5INT8: case SYBFLT8: case SYBDATETIME: case SYBBIT: diff --git a/src/tds/data.c b/src/tds/data.c index aaab739db3..fe5ca4b8c8 100644 --- a/src/tds/data.c +++ b/src/tds/data.c @@ -723,6 +723,15 @@ tds_generic_get(TDSSOCKET * tds, TDSCOLUMN * curcol) tdsdump_log(TDS_DBG_INFO1, "tds_get_data: type %d, varint size %d\n", curcol->column_type, curcol->column_varint_size); switch (curcol->column_varint_size) { case 4: + if (!is_blob_type(curcol->column_type)) { + /* Any other non-BLOB type (e.g., XSYBCHAR) */ + colsize = tds_get_int(tds); + if (colsize == 0) { + colsize = -1; + } + break; + } + /* It's a BLOB... */ len = tds_get_byte(tds); blob = (TDSBLOB *) curcol->column_data; @@ -884,6 +893,10 @@ tds_generic_put_info(TDSSOCKET * tds, TDSCOLUMN * col) case 0: break; case 1: + if (col->column_output && col->column_size <= 0 + && is_char_type(col->column_type)) { + size = 255; + } tds_put_byte(tds, size); break; case 2: From 55c652204b3e066ee2e90b4a4159e02435a715ea Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Thu, 9 May 2024 16:36:31 -0400 Subject: [PATCH 10/49] Improve support for TDS 5 (Sybase) bulk transfers. * Read defaults, send them back explicitly as needed, and clean up their storage afterwards. * tds5_bcp_add_variable_columns: ** Send spaces in lieu of fully empty SYB(VAR)CHAR data. ** Send correct textpos values in all cases. ** When writing the adjustment table, avoid a potential Sybase "row format error" by eliding the (effective) column count when it would have repeated the largest adjustment table entry. * tds_deinit_bcpinfo: Free and reset current_row for transfers in. Avoid potentially trying to interpret fragments of outgoing TDS data as BLOB pointers. --- include/freetds/tds.h | 4 ++ src/tds/bulk.c | 122 +++++++++++++++++++++++++++++++++++++++--- src/tds/mem.c | 14 +++++ src/tds/token.c | 4 +- 4 files changed, 137 insertions(+), 7 deletions(-) diff --git a/include/freetds/tds.h b/include/freetds/tds.h index 7d5becb88a..378aa8beaa 100644 --- a/include/freetds/tds.h +++ b/include/freetds/tds.h @@ -1693,6 +1693,10 @@ typedef struct tds5_colinfo TDS_TINYINT status; TDS_SMALLINT offset; TDS_INT length; + TDS_TINYINT dflt; + + TDS_INT dflt_size; + TDS_UCHAR* dflt_value; } TDS5COLINFO; struct tds_bcpinfo diff --git a/src/tds/bulk.c b/src/tds/bulk.c index 454d235d22..786f6994c4 100644 --- a/src/tds/bulk.c +++ b/src/tds/bulk.c @@ -74,6 +74,9 @@ static int tds5_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_da int offset, TDS_UCHAR *rowbuffer, int start, int *pncols); static void tds_bcp_row_free(TDSRESULTINFO* result, unsigned char *row); static TDSRET tds5_process_insert_bulk_reply(TDSSOCKET * tds, TDSBCPINFO *bcpinfo); +static TDSRET tds5_get_col_data_or_dflt(tds_bcp_get_col_data get_col_data, + TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, + int offset, int colnum); /** * Initialize BCP information. @@ -444,7 +447,29 @@ tds5_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) { TDSCOLUMN *bindcol = bcpinfo->bindinfo->columns[i]; if (is_blob_type(bindcol->on_server.column_type)) { - TDSRET rc = get_col_data(bcpinfo, bindcol, offset); + TDSRET rc; + /* Elide trailing NULLs */ + if (bindcol->bcp_column_data->is_null) { + int j; + for (j = i + 1; + j < bcpinfo->bindinfo->num_cols; ++j) { + TDSCOLUMN *bindcol2 + = bcpinfo->bindinfo + ->columns[j]; + if (is_blob_type(bindcol2->column_type) + && !(bindcol2->bcp_column_data + ->is_null)) { + break; + } + } + if (j == bcpinfo->bindinfo->num_cols) { + i = j; + break; + } + } + + rc = tds5_get_col_data_or_dflt(get_col_data, bcpinfo, + bindcol, offset, i); if (TDS_FAILED(rc)) return rc; /* unknown but zero */ @@ -546,7 +571,8 @@ tds5_bcp_add_fixed_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_dat tdsdump_log(TDS_DBG_FUNC, "tds5_bcp_add_fixed_columns column %d (%s) is a fixed column\n", i + 1, tds_dstr_cstr(&bcpcol->column_name)); - if (TDS_FAILED(get_col_data(bcpinfo, bcpcol, offset))) { + if (TDS_FAILED(tds5_get_col_data_or_dflt(get_col_data, bcpinfo, + bcpcol, offset, i))) { tdsdump_log(TDS_DBG_INFO1, "get_col_data (column %d) failed\n", i + 1); return -1; } @@ -655,7 +681,8 @@ tds5_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_ tdsdump_log(TDS_DBG_FUNC, "%4d %8d %8d %8d\n", i, ncols, row_pos, cpbytes); - if (TDS_FAILED(get_col_data(bcpinfo, bcpcol, offset))) + if (TDS_FAILED(tds5_get_col_data_or_dflt(get_col_data, bcpinfo, + bcpcol, offset, i))) return -1; /* If it's a NOT NULL column, and we have no data, throw an error. @@ -676,12 +703,19 @@ tds5_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_ TDS_NUMERIC *num = (TDS_NUMERIC *) bcpcol->bcp_column_data->data; cpbytes = tds_numeric_bytes_per_prec[num->precision]; memcpy(&rowbuffer[row_pos], num->array, cpbytes); + } else if ((bcpcol->column_type == SYBVARCHAR + || bcpcol->column_type == SYBCHAR) + && bcpcol->bcp_column_data->datalen == 0) { + cpbytes = 1; + rowbuffer[row_pos] = ' '; } else { cpbytes = bcpcol->bcp_column_data->datalen > bcpcol->column_size ? bcpcol->column_size : bcpcol->bcp_column_data->datalen; memcpy(&rowbuffer[row_pos], bcpcol->bcp_column_data->data, cpbytes); tds5_swap_data(bcpcol, &rowbuffer[row_pos]); } + } else if (is_blob_type(bcpcol->column_type)) { + bcpcol->column_textpos = row_pos; } row_pos += cpbytes; @@ -718,7 +752,8 @@ tds5_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_ tdsdump_log(TDS_DBG_FUNC, "ncols=%u poff=%p [%u]\n", ncols, poff, offsets[ncols]); - *poff++ = ncols + 1; + if (offsets[ncols] / 256 == offsets[ncols-1] / 256) + *poff++ = ncols + 1; /* this is some kind of run-length-prefix encoding */ while (pfx_top) { unsigned int n_pfx = 1; @@ -927,6 +962,7 @@ enum { BULKCOL_length, BULKCOL_status, BULKCOL_offset, + BULKCOL_dflt, /* number of columns needed */ BULKCOL_COUNT, @@ -948,6 +984,9 @@ tds5_bulk_insert_column(const char *name) BULKCOL(colcnt); BULKCOL(colid); break; + case 'd': + BULKCOL(dflt); + break; case 't': BULKCOL(type); break; @@ -965,6 +1004,27 @@ tds5_bulk_insert_column(const char *name) return -1; } +static void +tds5_read_bulk_defaults(TDSRESULTINFO *res_info, TDSBCPINFO *bcpinfo) +{ + int i; + TDS5COLINFO *syb_info = bcpinfo->sybase_colinfo; + for (i = 0; i < res_info->num_cols; ++i, ++syb_info) { + TDSCOLUMN *col = res_info->columns[i]; + TDS_UCHAR* src = col->column_data; + TDS_INT len = col->column_cur_size; + if (is_blob_type(col->column_type)) { + src = (unsigned char*) ((TDSBLOB*)src)->textvalue; + } + while ( !syb_info->dflt ) { + ++syb_info; + } + syb_info->dflt_size = len; + tds_realloc((void**)&syb_info->dflt_value, len); + memcpy(syb_info->dflt_value, src, len); + } +} + static TDSRET tds5_process_insert_bulk_reply(TDSSOCKET * tds, TDSBCPINFO *bcpinfo) { @@ -980,6 +1040,7 @@ tds5_process_insert_bulk_reply(TDSSOCKET * tds, TDSBCPINFO *bcpinfo) int cols_pos[BULKCOL_COUNT]; int cols_values[BULKCOL_COUNT]; TDS5COLINFO *colinfo; + int num_defs = 0; CHECK_TDS_EXTRA(tds); @@ -1006,9 +1067,14 @@ tds5_process_insert_bulk_reply(TDSSOCKET * tds, TDSBCPINFO *bcpinfo) case TDS_ROW_RESULT: /* get the results */ col_flags = 0; - if (!row_match) - continue; res_info = tds->current_results; + if (!row_match) { +#if ENABLE_EXTRA_CHECKS + assert(res_info->num_cols == num_defs); +#endif + tds5_read_bulk_defaults(res_info, bcpinfo); + continue; + } if (!res_info) continue; for (icol = 0; icol < BULKCOL_COUNT; ++icol) { @@ -1050,6 +1116,10 @@ tds5_process_insert_bulk_reply(TDSSOCKET * tds, TDSBCPINFO *bcpinfo) colinfo->status = cols_values[BULKCOL_status]; colinfo->offset = cols_values[BULKCOL_offset]; colinfo->length = cols_values[BULKCOL_length]; + colinfo->dflt = cols_values[BULKCOL_dflt]; + if (colinfo->dflt) { + ++num_defs; + } tdsdump_log(TDS_DBG_INFO1, "gotten row information %d type %d length %d status %d offset %d\n", cols_values[BULKCOL_colid], colinfo->type, @@ -1072,6 +1142,46 @@ tds5_process_insert_bulk_reply(TDSSOCKET * tds, TDSBCPINFO *bcpinfo) return ret; } +static TDSRET tds5_get_col_data_or_dflt(tds_bcp_get_col_data get_col_data, + TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, + int offset, int colnum) +{ + TDSRET ret; + BCPCOLDATA *coldata; + if (bcpcol->column_lenbind == NULL) { + bcpcol->column_lenbind = (TDS_INT *)&bcpcol->column_bindlen; + } + ret = get_col_data(bulk, bcpcol, offset); + coldata = bcpcol->bcp_column_data; + if (bcpcol->column_varaddr == NULL && coldata->datalen == 0 + && bulk->sybase_colinfo != NULL + && ( !is_blob_type(bcpcol->column_type) + || bcpcol->column_lenbind == NULL + || bcpcol->column_lenbind[offset] == 0)) { + const TDS5COLINFO *syb_info = &bulk->sybase_colinfo[colnum]; + const TDS_SMALLINT *nullind = bcpcol->column_nullbind; + if ((nullind != NULL && nullind[offset] == -1) + || !syb_info->dflt) { + if ( !bcpcol->column_nullable ) { + return TDS_FAIL; + } + coldata->datalen = 0; + coldata->is_null = true; + } else { + if (syb_info->dflt_size > 4096) { + tds_realloc((void**)&coldata->data, + syb_info->dflt_size); + } + memcpy(coldata->data, syb_info->dflt_value, + syb_info->dflt_size); + coldata->datalen = syb_info->dflt_size; + coldata->is_null = false; + } + return TDS_SUCCESS; + } + return ret; +} + /** * Free row data allocated in the result set. */ diff --git a/src/tds/mem.c b/src/tds/mem.c index c487f7d087..227ff6dcb8 100644 --- a/src/tds/mem.c +++ b/src/tds/mem.c @@ -1864,10 +1864,24 @@ tds_alloc_bcpinfo(void) void tds_deinit_bcpinfo(TDSBCPINFO *bcpinfo) { + /* + * Historically done for all TDS 5.0 transfers, but the protocol + * version isn't available here, or even in blk_done anymore. + */ + if (bcpinfo->direction == TDS_BCP_IN && bcpinfo->bindinfo != NULL + && bcpinfo->bindinfo->current_row != NULL) { + TDS_ZERO_FREE(bcpinfo->bindinfo->current_row); + } tds_dstr_free(&bcpinfo->tablename); TDS_ZERO_FREE(bcpinfo->insert_stmt); tds_free_results(bcpinfo->bindinfo); bcpinfo->bindinfo = NULL; + if (bcpinfo->sybase_colinfo != NULL) { + int i; + for (i = 0; i < bcpinfo->sybase_count; ++i) { + free(bcpinfo->sybase_colinfo[i].dflt_value); + } + } TDS_ZERO_FREE(bcpinfo->sybase_colinfo); bcpinfo->sybase_count = 0; } diff --git a/src/tds/token.c b/src/tds/token.c index 1cafae71cc..9f8114d072 100644 --- a/src/tds/token.c +++ b/src/tds/token.c @@ -154,7 +154,9 @@ tds_process_default_tokens(TDSSOCKET * tds, int marker) case TDS_RETURNSTATUS_TOKEN: ret_status = tds_get_int(tds); marker = tds_peek(tds); - if (marker != TDS_PARAM_TOKEN && marker != TDS_DONEPROC_TOKEN && marker != TDS_DONE_TOKEN) + if (marker != TDS_PARAM_TOKEN && marker != TDS_DONEPROC_TOKEN + && marker != TDS_DONE_TOKEN + && marker != TDS5_PARAMFMT_TOKEN) break; tds->has_status = true; tds->ret_status = ret_status; From 535e289bd706966ca363424b9c9d535e70d3569b Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Thu, 9 May 2024 16:46:05 -0400 Subject: [PATCH 11/49] tds_generic_put: Correct BCP 7.x new blob type handling ... i.e., of VARCHAR(MAX) and the like. --- src/tds/data.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tds/data.c b/src/tds/data.c index fe5ca4b8c8..30abe431a2 100644 --- a/src/tds/data.c +++ b/src/tds/data.c @@ -1018,11 +1018,11 @@ tds_generic_put(TDSSOCKET * tds, TDSCOLUMN * curcol, int bcp7) switch (curcol->column_varint_size) { case 8: - /* this difference for BCP operation is due to - * a bug in different server version that does - * not accept a length here */ - tds_put_int8(tds, bcp7 ? (TDS_INT8) -2 : (TDS_INT8) colsize); - tds_put_int(tds, colsize); + tds_put_int8(tds, colsize); + /* TDS 7.x no longer expects (or accepts) a + * redundant PLP chunk length here. */ + if ( !bcp7 ) + TDS_PUT_INT(tds, colsize); break; case 4: /* It's a BLOB... */ colsize = MIN(colsize, size); From bc0019504b035c4c5b7438c9385fd6da7edb874c Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Fri, 10 May 2024 09:59:19 -0400 Subject: [PATCH 12/49] Improve TDS 5 (Sybase) LONGBINARY and LONGCHAR handling. * tds.h (is_blob_col): Consider column_type in addition to column_varint_size. * Retire 5 as a nominal column_varint_size value in favor of unified logic. --- include/freetds/tds.h | 5 ++++- misc/types.csv | 4 ++-- src/tds/data.c | 37 +++++++++++++++++++++---------------- src/tds/tds_checks.c | 3 ++- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/include/freetds/tds.h b/include/freetds/tds.h index 378aa8beaa..96f6911c03 100644 --- a/include/freetds/tds.h +++ b/include/freetds/tds.h @@ -384,7 +384,10 @@ extern const char *const tds_type_names[256]; #define is_blob_type(x) ((x)==SYBTEXT || (x)==SYBIMAGE || (x)==SYBNTEXT) -#define is_blob_col(x) ((x)->column_varint_size > 2) +#define is_blob_col(x) (is_blob_type((x)->column_type) \ + || ((x)->column_varint_size == 8) \ + || ((x)->column_type == SYBVARIANT \ + && (x)->column_varint_size == 4)) /* large type means it has a two byte size field */ /* define is_large_type(x) (x>128) */ #define is_numeric_type(x) ((x)==SYBNUMERIC || (x)==SYBDECIMAL) diff --git a/misc/types.csv b/misc/types.csv index afbba982a8..e2a3ac94c3 100644 --- a/misc/types.csv +++ b/misc/types.csv @@ -27,8 +27,8 @@ SYBINT4;ALL;0;1;0;0;0;0;0;0;0;0;4;SYBINTN;11;0;1; SYBINT8;MS;0;1;0;0;0;0;0;0;0;0;8;SYBINTN;20;0;1; SYBINTERVAL;SYB;0;1;0;0;0;0;0;0;0;0;8;0;;0;0; SYBINTN;ALL;1;0;1;0;0;0;0;0;0;0;-1;0;;0;1; -SYBLONGBINARY;SYB;5;0;1;1;1;0;0;Depend;Depend;0;-1;0;2*S;1;0; -SYBLONGCHAR;SYB;5;0;1;1;1;0;0;??;1;0;-1;0;S;0;0; +SYBLONGBINARY;SYB;4;0;1;1;1;0;0;Depend;Depend;0;-1;0;2*S;1;0; +SYBLONGCHAR;SYB;4;0;1;1;1;0;0;??;1;0;-1;0;S;0;0; SYBMONEY;ALL;0;1;0;0;0;0;0;0;0;0;8;SYBMONEYN;21;0;1; SYBMONEY4;ALL;0;1;0;0;0;0;0;0;0;0;4;SYBMONEYN;12;0;1; SYBMONEYN;ALL;1;0;1;0;0;0;0;0;0;0;-1;0;;0;1; diff --git a/src/tds/data.c b/src/tds/data.c index 30abe431a2..cb03d7fbd5 100644 --- a/src/tds/data.c +++ b/src/tds/data.c @@ -387,7 +387,6 @@ tds_generic_get_info(TDSSOCKET *tds, TDSCOLUMN *col) case 8: col->column_size = 0x7ffffffflu; break; - case 5: case 4: col->column_size = tds_get_int(tds); if (col->column_size < 0) @@ -730,6 +729,13 @@ tds_generic_get(TDSSOCKET * tds, TDSCOLUMN * curcol) colsize = -1; } break; + } else if (curcol->on_server.column_type == SYBLONGBINARY) { + blob = (TDSBLOB *) curcol->column_data; + colsize = tds_get_int(tds); + if (colsize == 0) { + colsize = -1; + } + break; } /* It's a BLOB... */ @@ -747,11 +753,6 @@ tds_generic_get(TDSSOCKET * tds, TDSCOLUMN * curcol) colsize = -1; } break; - case 5: - colsize = tds_get_int(tds); - if (colsize == 0) - colsize = -1; - break; case 8: return tds72_get_varmax(tds, curcol); case 2: @@ -902,7 +903,6 @@ tds_generic_put_info(TDSSOCKET * tds, TDSCOLUMN * col) case 2: tds_put_smallint(tds, size); break; - case 5: case 4: tds_put_int(tds, size); break; @@ -947,9 +947,6 @@ tds_generic_put(TDSSOCKET * tds, TDSCOLUMN * curcol, int bcp7) if (curcol->column_cur_size < 0) { tdsdump_log(TDS_DBG_INFO1, "tds_generic_put: null param\n"); switch (curcol->column_varint_size) { - case 5: - tds_put_int(tds, 0); - break; case 4: if ((bcp7 || !IS_TDS7_PLUS(tds->conn)) && is_blob_type(curcol->on_server.column_type)) tds_put_byte(tds, 0); @@ -1024,7 +1021,13 @@ tds_generic_put(TDSSOCKET * tds, TDSCOLUMN * curcol, int bcp7) if ( !bcp7 ) TDS_PUT_INT(tds, colsize); break; - case 4: /* It's a BLOB... */ + case 4: + if ( !is_blob_col(curcol) ) { + colsize = MAX(MIN(colsize, 0x7fffffff), 1); + TDS_PUT_INT(tds, colsize); + break; + } + /* It's a BLOB... */ colsize = MIN(colsize, size); /* mssql require only size */ if (bcp7 && is_blob_type(curcol->on_server.column_type)) { @@ -1080,11 +1083,13 @@ tds_generic_put(TDSSOCKET * tds, TDSCOLUMN * curcol, int bcp7) /* TODO ICONV handle charset conversions for data */ /* put size of data */ switch (curcol->column_varint_size) { - case 5: /* It's a LONGBINARY */ - colsize = MIN(colsize, 0x7fffffff); - tds_put_int(tds, colsize); - break; - case 4: /* It's a BLOB... */ + case 4: + if ( !is_blob_col(curcol) ) { + colsize = MAX(MIN(colsize, 0x7fffffff), 1); + tds_put_int(tds, colsize); + break; + } + /* It's a BLOB... */ tds_put_byte(tds, 16); tds_put_n(tds, blob->textptr, 16); tds_put_n(tds, blob->timestamp, 8); diff --git a/src/tds/tds_checks.c b/src/tds/tds_checks.c index c027666032..c1a609f38b 100644 --- a/src/tds/tds_checks.c +++ b/src/tds/tds_checks.c @@ -192,7 +192,8 @@ tds_check_column_extra(const TDSCOLUMN * column) column_varint_size = column->column_varint_size; /* 8 is for varchar(max) or similar */ - assert(column_varint_size == 8 || (column_varint_size <= 5 && column_varint_size != 3)); + assert(column_varint_size == 8 || + (column_varint_size < 5 && column_varint_size != 3)); assert(column->column_scale <= column->column_prec); assert(column->column_prec <= MAXPRECISION); From 802599900d04f8d7daffb53c7c93e49fb9745eae Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Fri, 10 May 2024 10:05:28 -0400 Subject: [PATCH 13/49] tds_select: Treat EAGAIN and EINPROGRESS like EINTR. Call the registered interrupt handler (if any) for all three. --- src/tds/net.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tds/net.c b/src/tds/net.c index 466776c0b3..e9b4ba7fe9 100644 --- a/src/tds/net.c +++ b/src/tds/net.c @@ -671,6 +671,8 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds) switch (sock_errno) { case TDSSOCK_EINTR: + case EAGAIN: + case TDSSOCK_EINPROGRESS: /* FIXME this should be global maximun, not loop one */ seconds += poll_seconds; break; /* let interrupt handler be called */ @@ -683,7 +685,10 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds) } } - assert(rc == 0 || (rc < 0 && sock_errno == TDSSOCK_EINTR)); + assert(rc == 0 || (rc < 0 && (sock_errno == TDSSOCK_EINTR || + sock_errno == EAGAIN || + sock_errno == TDSSOCK_EINPROGRESS + ))); if (tds_get_ctx(tds) && tds_get_ctx(tds)->int_handler) { /* interrupt handler installed */ /* From f3e1d4ba25040f27d68a0ca6d1deb271d80325e8 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Fri, 10 May 2024 10:09:07 -0400 Subject: [PATCH 14/49] tds_fix_column_size: Allow full size for output columns. If an output column of type VARCHAR(n) or the like has no current size, send the type's maximum size; otherwise, the server will fill in only the first character/byte. --- src/tds/query.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tds/query.c b/src/tds/query.c index 089750c773..b222ec44e4 100644 --- a/src/tds/query.c +++ b/src/tds/query.c @@ -1554,10 +1554,14 @@ tds_fix_column_size(TDSSOCKET * tds TDS_UNUSED, TDSCOLUMN * curcol) break; case 2: /* note that varchar(max)/varbinary(max) have a varint of 8 */ - if (curcol->on_server.column_type == XSYBNVARCHAR || curcol->on_server.column_type == XSYBNCHAR) + if (size == 0 && curcol->column_output) { + min = 8000; + } else if (curcol->on_server.column_type == XSYBNVARCHAR + || curcol->on_server.column_type == XSYBNCHAR) { min = 2; - else + } else { min = 1; + } size = MAX(MIN(size, 8000u), min); break; case 4: From c31700a8d9a1015fc5e5caa98ad673627cdad1b8 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Fri, 10 May 2024 10:19:42 -0400 Subject: [PATCH 15/49] 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. --- 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 9f8114d072..f72b460387 100644 --- a/src/tds/token.c +++ b/src/tds/token.c @@ -2689,6 +2689,7 @@ tds5_process_dyn_result2(TDSSOCKET * tds) unsigned int col, num_cols; TDSCOLUMN *curcol; TDSPARAMINFO *info; + TDSDYNAMIC *dyn = NULL; CHECK_TDS_EXTRA(tds); @@ -2699,7 +2700,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 { @@ -2742,6 +2743,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); From 2350bd3b477835c635f12d42a676e717377530de Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Fri, 10 May 2024 10:21:51 -0400 Subject: [PATCH 16/49] read.c (tds_get_n): Avoid potential hangs on short replies. Don't bother trying to receive data following a packet marked as last; rather, bail if still short. Whenever bailing, close the socket on the way out to contain the damage from having fallen out of sync. --- src/tds/read.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tds/read.c b/src/tds/read.c index 1403c63482..ed1da12ab7 100644 --- a/src/tds/read.c +++ b/src/tds/read.c @@ -240,8 +240,12 @@ tds_get_n(TDSSOCKET * tds, void *dest, size_t need) dest = (char *) dest + have; } need -= have; - if (TDS_UNLIKELY(tds_read_packet(tds) < 0)) + if (TDS_UNLIKELY(tds->recv_packet->capacity < 2 + || tds->in_buf[1] != 0 + || tds_read_packet(tds) < 0)) { + tds_close_socket(tds); /* evidently out of sync */ return false; + } } if (need > 0) { /* get the remainder if there is any */ From 1971b33ac5aaac0989542eb02589cf2bcffb6b53 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Fri, 10 May 2024 10:23:49 -0400 Subject: [PATCH 17/49] Fix DATE and DATETIME2 bulk insertion via TDS 7.0 and 7.1. Under these protocol versions, MS SQL Server describes these columns as having NVARCHAR(n) types rather than traditional DATETIME types, due to DATETIME's range limitations. (Likewise for TIME, which however still needs to come in as a preconverted UTF-16 string to compensate for combined API and protocol limitations.) - ctlib/blk.c: Perform character conversion on strings converted from fixed-width types such as CS_DATETIME_TYPE when a comparison of column-size limits appears to indicate an encoding difference. - tds/config.c: Adjust STD_DATETIME_FMT to match MS's (ISO-ish) tastes; in particular, ensure that the entire date portion fits within the first 10 characters. --- src/ctlib/blk.c | 17 +++++++++++++++++ src/tds/config.c | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c index 34aeaccdd4..b104a6bfc0 100644 --- a/src/ctlib/blk.c +++ b/src/ctlib/blk.c @@ -641,6 +641,7 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) CS_INT *datalen = NULL; CS_BLKDESC *blkdesc = (CS_BLKDESC *) bulk; CS_CONTEXT *ctx = CONN(blkdesc)->ctx; + BCPCOLDATA *coldata = bindcol->bcp_column_data; tdsdump_log(TDS_DBG_FUNC, "_blk_get_col_data(%p, %p, %d)\n", bulk, bindcol, offset); @@ -709,6 +710,7 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) CONV_RESULT convert_buffer; CS_DATAFMT_COMMON srcfmt, destfmt; CS_INT desttype; + TDSSOCKET * tds = CONN(blkdesc)->tds_socket; srcfmt.datatype = srctype; srcfmt.maxlength = srclen; @@ -730,6 +732,21 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) tdsdump_log(TDS_DBG_INFO1, "convert failed for %d \n", srctype); return CS_FAIL; } + if (destfmt.maxlength != bindcol->column_size + && destfmt.datatype == CS_CHAR_TYPE + && is_fixed_type(_ct_get_server_type(tds, srctype))) { + size_t out_len; + TDS_UCHAR *buf + = (TDS_UCHAR *) tds_convert_string + (tds, bindcol->char_conv, + (char *) coldata->data, destlen, + &out_len); + if (buf != NULL && buf != coldata->data) { + free(coldata->data); + coldata->data = buf; + destlen = (CS_INT) out_len; + } + } } bindcol->bcp_column_data->datalen = destlen; diff --git a/src/tds/config.c b/src/tds/config.c index 277795d019..30b96c5353 100644 --- a/src/tds/config.c +++ b/src/tds/config.c @@ -91,7 +91,7 @@ static tds_dir_char *interf_file = NULL; #define TDS_ISSPACE(c) isspace((unsigned char ) (c)) -const char STD_DATETIME_FMT[] = "%b %e %Y %I:%M%p"; +const char STD_DATETIME_FMT[] = "%Y-%m-%d %H:%M:%S.%z"; #if !defined(_WIN32) && !defined(DOS32X) static const char pid_config_logpath[] = "/tmp/tdsconfig.log.%d"; From b15105484ef784a68d6877045fc64b20b869353c Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Fri, 10 May 2024 10:29:56 -0400 Subject: [PATCH 18/49] tds_iconv: Accommodate FreeBSD/Citrus iconv. Accommodate iconv implementations (such as the Citrus one used by modern FreeBSD systems) that ever indicate invalid input by reporting a positive count of irreversible characters rather than by setting errno to EILSEQ. --- src/tds/iconv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tds/iconv.c b/src/tds/iconv.c index e1e34ebb1d..7eed405068 100644 --- a/src/tds/iconv.c +++ b/src/tds/iconv.c @@ -657,6 +657,9 @@ tds_iconv(TDSSOCKET * tds, TDSICONV * conv, TDS_ICONV_DIRECTION io, /* iconv success, return */ if (irreversible != (size_t) - 1) { + if (irreversible > 0) { + eilseq_raised = true; + } /* here we detect end of conversion and try to reset shift state */ if (inbuf) { /* @@ -675,7 +678,7 @@ tds_iconv(TDSSOCKET * tds, TDSICONV * conv, TDS_ICONV_DIRECTION io, if (conv_errno == EILSEQ) eilseq_raised = true; - if (conv_errno != EILSEQ || io != to_client || !inbuf) + if (!eilseq_raised || io != to_client || !inbuf) break; /* * Invalid input sequence encountered reading from server. From 4d4bf6252fc768bb9fe7e9d05089c3a25fce5ae9 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Fri, 10 May 2024 15:48:13 -0400 Subject: [PATCH 19/49] tds_check_column_extra: Skip size check for BLOBs. Let column_size exceed column_cur_size for BLOBs, whose reported maximum may have been merely nominal, and doesn't really matter because their storage is generally allocated separately, based on actual result sizes. --- src/tds/tds_checks.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tds/tds_checks.c b/src/tds/tds_checks.c index c1a609f38b..c53471c69e 100644 --- a/src/tds/tds_checks.c +++ b/src/tds/tds_checks.c @@ -236,7 +236,15 @@ tds_check_column_extra(const TDSCOLUMN * column) assert(varint_ok); assert(!is_numeric_type(column->column_type)); - assert(column->column_cur_size <= column->column_size); + if (!is_blob_type(column->column_type)) { + /* + * Skip for BLOBs, whose reported maximum may have + * been merely nominal, and doesn't really matter + * because their storage is generally allocated + * separately, based on actual result sizes. + */ + assert(column->column_cur_size <= column->column_size); + } /* check size of fixed type correct */ size = tds_get_size_by_type(column->column_type); From 0ceb04d4a0bef4e4a4eb69553b412843153d5a0c Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Fri, 10 May 2024 16:50:24 -0400 Subject: [PATCH 20/49] Report system errors' descriptions to ctlib clients. * tds.h (TDSMESSAGE): Add an osstr field. * ctutil.c (_ct_handle_client_message): Propagate it to osstring(len). * tds/login.c (tds_save): Clear osstr to avoid invalid reads when trying to connect to a dead server. * tds/ncbi_strerror.c: New. * tds/util.c: ** #include ncbi_strerror.c, whose definitions are all static. ** tdserror: Populate the osstr field; clean it when done. --- include/freetds/tds.h | 1 + src/ctlib/ctutil.c | 7 +- src/tds/login.c | 1 + src/tds/ncbi_strerror.c | 351 ++++++++++++++++++++++++++++++++++++++++ src/tds/util.c | 12 ++ 5 files changed, 370 insertions(+), 2 deletions(-) create mode 100644 src/tds/ncbi_strerror.c diff --git a/include/freetds/tds.h b/include/freetds/tds.h index 96f6911c03..0cb082d415 100644 --- a/include/freetds/tds.h +++ b/include/freetds/tds.h @@ -893,6 +893,7 @@ typedef struct tds_message TDS_TINYINT severity; /* for library-generated errors */ int oserr; + TDS_CHAR *osstr; } TDSMESSAGE; typedef struct tds_upd_col diff --git a/src/ctlib/ctutil.c b/src/ctlib/ctutil.c index bae42588d4..3853d0f7f1 100644 --- a/src/ctlib/ctutil.c +++ b/src/ctlib/ctutil.c @@ -126,8 +126,11 @@ _ct_handle_client_message(const TDSCONTEXT * ctx_tds, TDSSOCKET * tds, TDSMESSAG errmsg.severity = _ct_translate_severity(msg->severity); strlcpy(errmsg.msgstring, msg->message, sizeof(errmsg.msgstring)); errmsg.msgstringlen = strlen(errmsg.msgstring); - errmsg.osstring[0] = '\0'; - errmsg.osstringlen = 0; + if (msg->osstr) { + errmsg.osstringlen = (CS_INT) strlen(msg->osstr); + strlcpy(errmsg.osstring, msg->osstr, CS_MAX_MSG); + } + /* if there is no connection, attempt to call the context handler */ if (!con) { ctx = (CS_CONTEXT *) ctx_tds->parent; diff --git a/src/tds/login.c b/src/tds/login.c index d63545470e..8b5d9cd775 100644 --- a/src/tds/login.c +++ b/src/tds/login.c @@ -206,6 +206,7 @@ tds_save(TDSSAVECONTEXT *ctx, char type, TDSMESSAGE *msg) dest_msg = &ctx->msgs[ctx->num_msg]; dest_msg->type = type; dest_msg->msg = *msg; + dest_msg->msg.osstr = NULL; #define COPY(name) if (msg->name) dest_msg->msg.name = strdup(msg->name); COPY(server); COPY(message); diff --git a/src/tds/ncbi_strerror.c b/src/tds/ncbi_strerror.c new file mode 100644 index 0000000000..f36429bd64 --- /dev/null +++ b/src/tds/ncbi_strerror.c @@ -0,0 +1,351 @@ +/* $Id$ + * =========================================================================== + * + * PUBLIC DOMAIN NOTICE + * National Center for Biotechnology Information + * + * This software/database is a "United States Government Work" under the + * terms of the United States Copyright Act. It was written as part of + * the author's official duties as a United States Government employee and + * thus cannot be copyrighted. This software/database is freely available + * to the public for use. The National Library of Medicine and the U.S. + * Government have not placed any restriction on its use or reproduction. + * + * Although all reasonable efforts have been taken to ensure the accuracy + * and reliability of the software and data, the NLM and the U.S. + * Government do not and cannot warrant the performance or results that + * may be obtained by using this software or data. The NLM and the U.S. + * Government disclaim all warranties, express or implied, including + * warranties of performance, merchantability or fitness for any particular + * purpose. + * + * Please cite the author in any work or product based on this material. + * + * =========================================================================== + * + * Authors: Pavel Ivanov, Anton Lavrentiev, Denis Vakatov + * + * File Description: + * errno->text conversion helper + */ + + +#ifdef NCBI_INCLUDE_STRERROR_C + + +# ifdef _FREETDS_LIBRARY_SOURCE +# define s_StrError s_StrErrorInternal +# endif /*_FREETDS_LIBRARY_SOURCE*/ + + +# if defined(NCBI_OS_MSWIN) && defined(_UNICODE) + +static const char* s_WinStrdup(const char* str) +{ + size_t n = strlen(str); + char* s = (char*) LocalAlloc(LMEM_FIXED, ++n * sizeof(*s)); + return s ? (const char*) memcpy(s, str, n) : 0; +} +# define ERR_STRDUP(s) s_WinStrdup(s) + +extern const char* UTIL_TcharToUtf8(const TCHAR* str) +{ + char* s = NULL; + if (str) { + /* Note "-1" means to consume all input including the trailing NUL */ + int n = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL); + if (n > 0) { + s = (char*) LocalAlloc(LMEM_FIXED, n * sizeof(*s)); + if (s) + WideCharToMultiByte(CP_UTF8, 0, str, -1, s, n, NULL, NULL); + } + } + return s; +} + +# ifndef UTIL_ReleaseBuffer +# define UTIL_ReleaseBuffer(x) UTIL_ReleaseBufferOnHeap(x) +# endif + +# else /*NCBI_OS_MSWIN && _UNICODE*/ + +# define ERR_STRDUP(s) strdup(s) + +# ifdef UTIL_TcharToUtf8 +# undef UTIL_TcharToUtf8 +# endif +# define UTIL_TcharToUtf8(x) strdup(x) + +# ifdef UTIL_ReleaseBuffer +# undef UTIL_ReleaseBuffer +# endif +# define UTIL_ReleaseBuffer(x) free((void*)(x)) + +# endif /*NCBI_OS_MSWIN && _UNICODE*/ + + +# ifdef NCBI_OS_MSWIN + +extern void UTIL_ReleaseBufferOnHeap(const void* ptr) +{ + if (ptr) + LocalFree((HLOCAL) ptr); +} + +# endif /*NCBI_OS_MSWIN*/ + + +static const char* s_StrErrorInternal(int error) +{ + static const struct { + int errnum; + const char* errstr; + } errmap[] = { +# ifdef NCBI_OS_MSWIN + {WSAEINTR, "Interrupted system call"}, + {WSAEBADF, "Bad file number"}, + {WSAEACCES, "Access denied"}, + {WSAEFAULT, "Segmentation fault"}, + {WSAEINVAL, "Invalid agrument"}, + {WSAEMFILE, "Too many open files"}, + /* + * Windows Sockets definitions of regular Berkeley error constants + */ + {WSAEWOULDBLOCK, "Resource temporarily unavailable"}, + {WSAEINPROGRESS, "Operation now in progress"}, + {WSAEALREADY, "Operation already in progress"}, + {WSAENOTSOCK, "Not a socket"}, + {WSAEDESTADDRREQ, "Destination address required"}, + {WSAEMSGSIZE, "Invalid message size"}, + {WSAEPROTOTYPE, "Wrong protocol type"}, + {WSAENOPROTOOPT, "Bad protocol option"}, + {WSAEPROTONOSUPPORT, "Protocol not supported"}, + {WSAESOCKTNOSUPPORT, "Socket type not supported"}, + {WSAEOPNOTSUPP, "Operation not supported"}, + {WSAEPFNOSUPPORT, "Protocol family not supported"}, + {WSAEAFNOSUPPORT, "Address family not supported"}, + {WSAEADDRINUSE, "Address already in use"}, + {WSAEADDRNOTAVAIL, "Cannot assign requested address"}, + {WSAENETDOWN, "Network is down"}, + {WSAENETUNREACH, "Network is unreachable"}, + {WSAENETRESET, "Connection dropped on network reset"}, + {WSAECONNABORTED, "Software caused connection abort"}, + {WSAECONNRESET, "Connection reset by peer"}, + {WSAENOBUFS, "No buffer space available"}, + {WSAEISCONN, "Socket is already connected"}, + {WSAENOTCONN, "Socket is not connected"}, + {WSAESHUTDOWN, "Cannot send after socket shutdown"}, + {WSAETOOMANYREFS, "Too many references"}, + {WSAETIMEDOUT, "Operation timed out"}, + {WSAECONNREFUSED, "Connection refused"}, + {WSAELOOP, "Infinite loop"}, + {WSAENAMETOOLONG, "Name too long"}, + {WSAEHOSTDOWN, "Host is down"}, + {WSAEHOSTUNREACH, "Host unreachable"}, + {WSAENOTEMPTY, "Not empty"}, + {WSAEPROCLIM, "Too many processes"}, + {WSAEUSERS, "Too many users"}, + {WSAEDQUOT, "Quota exceeded"}, + {WSAESTALE, "Stale descriptor"}, + {WSAEREMOTE, "Remote error"}, + /* + * Extended Windows Sockets error constant definitions + */ + {WSASYSNOTREADY, "Network subsystem is unavailable"}, + {WSAVERNOTSUPPORTED, "Winsock.dll version out of range"}, + {WSANOTINITIALISED, "Not yet initialized"}, + {WSAEDISCON, "Graceful shutdown in progress"}, +# ifdef WSAENOMORE + /*NB: replaced with WSA_E_NO_MORE*/ + {WSAENOMORE, "No more data available"}, +# endif /*WSAENOMORE*/ +# ifdef WSA_E_NO_MORE + {WSA_E_NO_MORE, "No more data available"}, +# endif /*WSA_E_NO_MORE*/ +# ifdef WSAECANCELLED + /*NB: replaced with WSA_E_CANCELLED*/ + {WSAECANCELLED, "Call has been cancelled"}, +# endif /*WSAECANCELLED*/ +# ifdef WSA_E_CANCELLED + {WSA_E_CANCELLED, "Call has been cancelled"}, +# endif /*WSA_E_CANCELLED*/ + {WSAEINVALIDPROCTABLE, "Invalid procedure table"}, + {WSAEINVALIDPROVIDER, "Invalid provider version number"}, + {WSAEPROVIDERFAILEDINIT,"Cannot init provider"}, + {WSASYSCALLFAILURE, "System call failed"}, + {WSASERVICE_NOT_FOUND, "Service not found"}, + {WSATYPE_NOT_FOUND, "Class type not found"}, + {WSAEREFUSED, "Query refused"}, + /* + * WinSock 2 extension + */ +# ifdef WSA_IO_PENDING + {WSA_IO_PENDING, "Operation has been queued"}, +# endif /*WSA_IO_PENDING*/ +# ifdef WSA_IO_INCOMPLETE + {WSA_IO_INCOMPLETE, "Operation still in progress"}, +# endif /*WSA_IO_INCOMPLETE*/ +# ifdef WSA_INVALID_HANDLE + {WSA_INVALID_HANDLE, "Invalid handle"}, +# endif /*WSA_INVALID_HANDLE*/ +# ifdef WSA_INVALID_PARAMETER + {WSA_INVALID_PARAMETER, "Invalid parameter"}, +# endif /*WSA_INVALID_PARAMETER*/ +# ifdef WSA_NOT_ENOUGH_MEMORY + {WSA_NOT_ENOUGH_MEMORY, "Out of memory"}, +# endif /*WSA_NOT_ENOUGH_MEMORY*/ +# ifdef WSA_OPERATION_ABORTED + {WSA_OPERATION_ABORTED, "Operation aborted"}, +# endif /*WSA_OPERATION_ABORTED*/ +# endif /*NCBI_OS_MSWIN*/ +# ifdef NCBI_OS_MSWIN +# define EAI_BASE 0 +# else +# define EAI_BASE 100000 +# endif /*NCBI_OS_MSWIN*/ +# ifdef EAI_ADDRFAMILY + {EAI_ADDRFAMILY + EAI_BASE, + "Address family not supported"}, +# endif /*EAI_ADDRFAMILY*/ +# ifdef EAI_AGAIN + {EAI_AGAIN + EAI_BASE, + "Temporary failure in name resolution"}, +# endif /*EAI_AGAIN*/ +# ifdef EAI_BADFLAGS + {EAI_BADFLAGS + EAI_BASE, + "Invalid value for lookup flags"}, +# endif /*EAI_BADFLAGS*/ +# ifdef EAI_FAIL + {EAI_FAIL + EAI_BASE, + "Non-recoverable failure in name resolution"}, +# endif /*EAI_FAIL*/ +# ifdef EAI_FAMILY + {EAI_FAMILY + EAI_BASE, + "Address family not supported"}, +# endif /*EAI_FAMILY*/ +# ifdef EAI_MEMORY + {EAI_MEMORY + EAI_BASE, + "Memory allocation failure"}, +# endif /*EAI_MEMORY*/ +# ifdef EAI_NODATA +# if EAI_NODATA != EAI_NONAME + {EAI_NODATA + EAI_BASE, + "No address associated with nodename"}, +# endif /*EAI_NODATA!=EAI_NONAME*/ +# endif /*EAI_NODATA*/ +# ifdef EAI_NONAME + {EAI_NONAME + EAI_BASE, + "Host and/or service name unknown"}, +# endif /*EAI_NONAME*/ +# ifdef EAI_OVERFLOW + {EAI_OVERFLOW + EAI_BASE, + "Argument buffer overflow"}, +# endif /*EAI_OVERFLOW*/ +# ifdef EAI_SERVICE + {EAI_SERVICE + EAI_BASE, + "Service name not supported for socket type"}, +# endif /*EAI_SERVICE*/ +# ifdef EAI_SOCKTYPE + {EAI_SOCKTYPE + EAI_BASE, + "Socket type not supported"}, +# endif /*EAI_SOCKTYPE*/ + /* GNU extensions */ +# ifdef EAI_ALLDONE + {EAI_ALLDONE + EAI_BASE, + "All requests done"}, +# endif /*EAI_ALLDONE*/ +# ifdef EAI_CANCELED + {EAI_CANCELED + EAI_BASE, + "Request canceled"}, +# endif /*EAI_BADFLAGS*/ +# ifdef EAI_INPROGRESS + {EAI_INPROGRESS + EAI_BASE, + "Processing request in progress"}, +# endif /*EAI_INPROGRESS*/ +# ifdef EAI_INTR + {EAI_INTR + EAI_BASE, + "Interrupted by a signal"}, +# endif /*EAI_INTR*/ +# ifdef EAI_NOTCANCELED + {EAI_NOTCANCELED + EAI_BASE, + "Request not canceled"}, +# endif /*EAI_NOTCANCELED*/ +# ifdef EAI_IDN_ENCODE + {EAI_IDN_ENCODE + EAI_BASE, + "IDN encoding failed"}, +# endif /*EAI_IDN_ENCODE*/ +# ifdef NCBI_OS_MSWIN +# define DNS_BASE 0 +# else +# define DNS_BASE 200000 +# endif /*NCBI_OS_MSWIN*/ +# ifdef HOST_NOT_FOUND + {HOST_NOT_FOUND + DNS_BASE, + "Host not found"}, +# endif /*HOST_NOT_FOUND*/ +# ifdef TRY_AGAIN + {TRY_AGAIN + DNS_BASE, + "DNS server failure"}, +# endif /*TRY_AGAIN*/ +# ifdef NO_RECOVERY + {NO_RECOVERY + DNS_BASE, + "Unrecoverable DNS error"}, +# endif /*NO_RECOVERY*/ +# ifdef NO_ADDRESS + {NO_ADDRESS + DNS_BASE, + "No address record found in DNS"}, +# endif /*NO_ADDRESS*/ +# ifdef NO_DATA + {NO_DATA + DNS_BASE, + "No DNS data of requested type"}, +# endif /*NO_DATA*/ + + /* Last dummy entry - must be present */ + {0, 0} + }; +#if defined(NCBI_OS_LINUX) || defined(NCBI_OS_CYGWIN) + /* To work correctly, descending order of offsets is required here */ + static const struct { + int erroff; + const char* (*errfun)(int errnum); + } errsup[] = { +# ifdef __GLIBC__ + { DNS_BASE, hstrerror }, +# endif /*__GLIBC__*/ +# if defined(HAVE_GETADDRINFO) || defined(HAVE_GETNAMEINFO) + { EAI_BASE, gai_strerror }, +# endif /*HAVE_GETADDRINFO || HAVE_GETNAMEINFO*/ + /* Last dummy entry - must present */ + { 0, 0 } + }; +#endif /*NCBI_OS_LINUX || NCBI_OS_CYGWIN*/ + size_t i; + + if (!error) + return 0; + +#if defined(NCBI_OS_LINUX) || defined(NCBI_OS_CYGWIN) + for (i = 0; i < sizeof(errsup) / sizeof(errsup[0]) - 1/*dummy*/; ++i) { + if (errsup[i].erroff - 10000 < error + && error < errsup[i].erroff + 10000) { + const char* errstr = errsup[i].errfun(error - errsup[i].erroff); + if (errstr && *errstr && strncasecmp(errstr, "Unknown ", 8)!=0) + return ERR_STRDUP(errstr); + } + } +#endif /*NCBI_OS_LINUX || NCBI_OS_CYGWIN*/ + + for (i = 0; i < sizeof(errmap) / sizeof(errmap[0]) - 1/*dummy*/; ++i) { + if (errmap[i].errnum == error) + return ERR_STRDUP(errmap[i].errstr); + } + +# if defined(NCBI_OS_MSWIN) && defined(_UNICODE) + return UTIL_TcharToUtf8(_wcserror(error)); +# else + return ERR_STRDUP(strerror(error)); +# endif /*NCBI_OS_MSWIN && _UNICODE*/ +} + + +#endif /*NCBI_INCLUDE_STRERROR_C*/ diff --git a/src/tds/util.c b/src/tds/util.c index 5d26c7c548..2404a59fd0 100644 --- a/src/tds/util.c +++ b/src/tds/util.c @@ -40,6 +40,10 @@ #include #endif /* HAVE_UNISTD_H */ +#if HAVE_NETDB_H +#include +#endif /* HAVE_NETDB_H */ + #ifdef _WIN32 #include #endif @@ -48,6 +52,9 @@ #include #include +#define NCBI_INCLUDE_STRERROR_C +#include "ncbi_strerror.c" + /** * Set state of TDS connection, with logging and checking. * \param tds state information for the socket and the TDS protocol @@ -354,6 +361,7 @@ tdserror (const TDSCONTEXT * tds_ctx, TDSSOCKET * tds, int msgno, int errnum) msg.sql_state = tds_alloc_client_sqlstate(msgno); msg.oserr = errnum; + msg.osstr = errnum ? (char*) s_StrError(errnum) : NULL; /* * Call client library handler. @@ -363,6 +371,10 @@ tdserror (const TDSCONTEXT * tds_ctx, TDSSOCKET * tds, int msgno, int errnum) tdsdump_log(TDS_DBG_FUNC, "tdserror: client library returned %s(%d)\n", retname(rc), rc); TDS_ZERO_FREE(msg.sql_state); + if (errnum) { + UTIL_ReleaseBuffer(msg.osstr); + msg.osstr = NULL; + } } else { static const char msg[] = "tdserror: client library not called because either " "tds_ctx (%p) or tds_ctx->err_handler is NULL\n"; From 572a3c9781fd0c26f0744c2438266a65e574fc7a Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 10:11:13 -0400 Subject: [PATCH 21/49] ct_connect: Set client_charset in addition to server_charset. --- src/ctlib/ct.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c index 396048e849..1f4ce4b384 100644 --- a/src/ctlib/ct.c +++ b/src/ctlib/ct.c @@ -766,7 +766,10 @@ ct_connect(CS_CONNECTION * con, CS_CHAR * servername, CS_INT snamelen) /* override locale settings with CS_CONNECTION settings, if any */ if (con->locale) { if (con->locale->charset) { - if (!tds_dstr_copy(&login->server_charset, con->locale->charset)) + if (!tds_dstr_copy(&login->server_charset, + con->locale->charset) + || !tds_dstr_copy(&login->client_charset, + con->locale->charset)) goto Cleanup; } if (con->locale->language) { From e444c559c74d0dd14f30142fc011c13fe65c5c91 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 10:35:31 -0400 Subject: [PATCH 22/49] ct_data_info: Encode/decode CS_IODESC datatype field. --- src/ctlib/ct.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c index 1f4ce4b384..838ccbc1fc 100644 --- a/src/ctlib/ct.c +++ b/src/ctlib/ct.c @@ -3096,7 +3096,10 @@ ct_data_info(CS_COMMAND * cmd, CS_INT action, CS_INT colnum, CS_IODESC * iodesc) return CS_FAIL; cmd->iodesc->iotype = CS_IODATA; - cmd->iodesc->datatype = iodesc->datatype; + + cmd->iodesc->datatype + = _ct_get_server_type(tds, iodesc->datatype); + cmd->iodesc->locale = cmd->con->locale; cmd->iodesc->usertype = iodesc->usertype; cmd->iodesc->total_txtlen = iodesc->total_txtlen; @@ -3118,7 +3121,11 @@ ct_data_info(CS_COMMAND * cmd, CS_INT action, CS_INT colnum, CS_IODESC * iodesc) return CS_FAIL; iodesc->iotype = cmd->iodesc->iotype; - iodesc->datatype = cmd->iodesc->datatype; + + iodesc->datatype + = _ct_get_client_type(resinfo->columns[colnum-1], + true); + iodesc->locale = cmd->iodesc->locale; iodesc->usertype = cmd->iodesc->usertype; iodesc->total_txtlen = cmd->iodesc->total_txtlen; From 9f8e222da8d7a46e929ef79e113a1cf81b4fc8fe Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 11:14:23 -0400 Subject: [PATCH 23/49] ctlib: Implement full Unicode support for TDS 7+ (MSSQL). * Introduce CS_NLONGCHAR_TYPE and CS_NVARCHAR_TYPE, both corresponding to SYBNVARCHAR (along with CS_UNICHAR_TYPE); have ct_param automatically promote CS_{LONG,VAR}CHAR_TYPE to CS_N{LONG,VAR}CHAR_TYPE for TDS 7+ when non-ASCII characters appear in the data. (Unnecessary use of Unicode types can make parameterized queries against 8-bit text columns run very slowly.) * ctlib/cs.c (cs_convert): Formally support Unicode destination types (SYBNVARCHAR and SYBNTEXT). * ctlib/ct.c (paraminfoalloc): When setting maximum length automatically, account for possible conversion to UCS-2. * tds/convert.c (tds_convert), tds/tds_willconvert.*: Formally support Unicode types, giving type 103 (0x67) the benefit of the doubt as SYBNVARCHAR rather than SYBSENSITIVITY. * tds/data.c (tds_set_param_type): Map SYBNVARCHAR to XSYBNVARCHAR for TDS 7+. * tds/unittests/convert.c: Accommodate Unicode types, albeit with strings left narrow to match real-life usage, wherein encoding conversion occurs separately. --- include/cspublic.h | 4 +++- src/ctlib/cs.c | 12 +++++++++-- src/ctlib/ct.c | 41 +++++++++++++++++++++++++++++++++++-- src/tds/convert.c | 7 ++++--- src/tds/data.c | 3 +++ src/tds/tds_willconvert.pl | 31 +++++++++++++++------------- src/tds/unittests/convert.c | 9 ++++++++ 7 files changed, 85 insertions(+), 22 deletions(-) diff --git a/include/cspublic.h b/include/cspublic.h index 17ec3cb5f9..80917c969f 100644 --- a/include/cspublic.h +++ b/include/cspublic.h @@ -613,9 +613,11 @@ enum #define CS_IMAGELOCATOR_TYPE TDS_STATIC_CAST(CS_INT, 38) #define CS_UNITEXTLOCATOR_TYPE TDS_STATIC_CAST(CS_INT, 39) #define CS_UNIQUE_TYPE TDS_STATIC_CAST(CS_INT, 40) +#define CS_NVARCHAR_TYPE TDS_STATIC_CAST(CS_INT, 41) +#define CS_NLONGCHAR_TYPE TDS_STATIC_CAST(CS_INT, 42) #define CS_MIN_SYBTYPE CS_CHAR_TYPE -#define CS_MAX_SYBTYPE CS_UNIQUE_TYPE +#define CS_MAX_SYBTYPE CS_NLONGCHAR_TYPE #define CS_USER_TYPE TDS_STATIC_CAST(CS_INT, 100) /* cs_dt_info type values */ diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c index 8a29bbcba4..6a8dcbb499 100644 --- a/src/ctlib/cs.c +++ b/src/ctlib/cs.c @@ -547,7 +547,9 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdat return CS_FAIL; } src_len = srcfmt->maxlength; - if (datatype == CS_VARCHAR_TYPE || datatype == CS_VARBINARY_TYPE) { + if (datatype == CS_VARCHAR_TYPE || + datatype == CS_NVARCHAR_TYPE || + datatype == CS_VARBINARY_TYPE) { CS_VARCHAR *vc = (CS_VARCHAR *) srcdata; src_len = vc->len; srcdata = vc->str; @@ -560,7 +562,9 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdat return CS_FAIL; } destlen = destfmt->maxlength; - if (datatype == CS_VARCHAR_TYPE || datatype == CS_VARBINARY_TYPE) { + if (datatype == CS_VARCHAR_TYPE || + datatype == CS_NVARCHAR_TYPE || + datatype == CS_VARBINARY_TYPE) { destvc = (CS_VARCHAR *) destdata; destlen = sizeof(destvc->str); destdata = destvc->str; @@ -620,6 +624,8 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdat case SYBCHAR: case SYBVARCHAR: case SYBTEXT: + case SYBNVARCHAR: + case SYBNTEXT: tdsdump_log(TDS_DBG_FUNC, "cs_convert() desttype = character\n"); memcpy(dest, srcdata, minlen); @@ -822,6 +828,8 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdat case SYBCHAR: case SYBVARCHAR: case SYBTEXT: + case SYBNVARCHAR: + case SYBNTEXT: ret = CS_SUCCEED; if (len > destlen) { tdsdump_log(TDS_DBG_FUNC, "Data-conversion resulted in overflow\n"); diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c index 838ccbc1fc..2f08c86bce 100644 --- a/src/ctlib/ct.c +++ b/src/ctlib/ct.c @@ -2182,6 +2182,7 @@ _ct_get_server_type(TDSSOCKET *tds, int datatype) case CS_BIT_TYPE: return SYBBIT; case CS_CHAR_TYPE: return SYBCHAR; case CS_VARCHAR_TYPE: return SYBVARCHAR; + case CS_NVARCHAR_TYPE: return SYBNVARCHAR; case CS_LONG_TYPE: case CS_UBIGINT_TYPE: if (!tds || tds_capability_has_req(tds->conn, TDS_REQ_DATA_UINT8)) @@ -2211,11 +2212,12 @@ _ct_get_server_type(TDSSOCKET *tds, int datatype) case CS_TEXT_TYPE: return SYBTEXT; case CS_UNIQUE_TYPE: return SYBUNIQUE; case CS_LONGBINARY_TYPE: return SYBLONGBINARY; - case CS_UNICHAR_TYPE: return SYBVARCHAR; + case CS_UNICHAR_TYPE: return SYBNVARCHAR; case CS_LONGCHAR_TYPE: if (!tds || IS_TDS7_PLUS(tds->conn)) return SYBVARCHAR; return SYBLONGCHAR; + case CS_NLONGCHAR_TYPE: return SYBNVARCHAR; case CS_DATE_TYPE: if (!tds || tds_capability_has_req(tds->conn, TDS_REQ_DATA_DATE)) return SYBDATE; @@ -3393,6 +3395,8 @@ ct_param(CS_COMMAND * cmd, CS_DATAFMT * datafmt_arg, CS_VOID * data, CS_INT data CS_PARAM *param; const CS_DATAFMT_LARGE *datafmt; CS_DATAFMT_LARGE datafmt_buf; + bool promote = (datafmt_arg->datatype == CS_VARCHAR_TYPE || + datafmt_arg->datatype == CS_LONGCHAR_TYPE); tdsdump_log(TDS_DBG_FUNC, "ct_param(%p, %p, %p, %d, %hd)\n", cmd, datafmt_arg, data, datalen, indicator); @@ -3401,6 +3405,30 @@ ct_param(CS_COMMAND * cmd, CS_DATAFMT * datafmt_arg, CS_VOID * data, CS_INT data datafmt = _ct_datafmt_conv_in(cmd->con->ctx, datafmt_arg, &datafmt_buf); + if (promote && IS_TDS7_PLUS(cmd->con->tds_socket->conn)) { + /* Actually promote only if non-ASCII characters are present */ + CS_INT i; + + promote = 0; + for (i = 0; i < datalen; ++i) { + if (((const char*)data)[i] & 0x80) { + promote = 1; + break; + } + } + + if ( !promote ) { + /* pure ASCII, leave as is */ + } else if (datafmt->datatype == CS_VARCHAR_TYPE) { + datafmt_arg->datatype = CS_NVARCHAR_TYPE; + datafmt_buf.datatype = CS_NVARCHAR_TYPE; + } else if (datafmt->datatype == CS_LONGCHAR_TYPE) { + datafmt_arg->datatype = CS_NLONGCHAR_TYPE; + datafmt_buf.datatype = CS_NLONGCHAR_TYPE; + } + } + + switch (cmd->command_type) { case CS_RPC_CMD: if (!cmd->rpc) { @@ -4213,7 +4241,9 @@ paraminfoalloc(TDSSOCKET * tds, CS_PARAM * first_param) temp_datalen = *(p->datalen); } - if (temp_type == CS_VARCHAR_TYPE || temp_type == CS_VARBINARY_TYPE) { + if (temp_type == CS_VARCHAR_TYPE + || temp_type == CS_NVARCHAR_TYPE + || temp_type == CS_VARBINARY_TYPE) { CS_VARCHAR *vc = (CS_VARCHAR *) temp_value; if (vc) { @@ -4240,6 +4270,13 @@ paraminfoalloc(TDSSOCKET * tds, CS_PARAM * first_param) if (p->maxlen < 0) { tds_free_param_results(params); return NULL; + } else if (p->maxlen == 0 + && is_unicode_type(tds_type)) { + /* + * Auto-detect; account for possible + * conversion to UCS-2. + */ + p->maxlen = temp_datalen * 2; } pcol->on_server.column_size = pcol->column_size = p->maxlen; pcol->column_cur_size = temp_value ? temp_datalen : -1; diff --git a/src/tds/convert.c b/src/tds/convert.c index 320c5efdab..9ca8b42c5c 100644 --- a/src/tds/convert.c +++ b/src/tds/convert.c @@ -200,8 +200,11 @@ binary_to_result(int desttype, const void *data, size_t len, CONV_RESULT * cr) return (TDS_INT)len; } +/* "N" versions are safe to list due to iconv calls elsewhere. */ #define CASE_ALL_CHAR \ - SYBCHAR: case SYBVARCHAR: case SYBTEXT: case XSYBCHAR: case XSYBVARCHAR + SYBCHAR: case SYBVARCHAR: case SYBTEXT: case XSYBCHAR: \ + case XSYBVARCHAR: case SYBNVARCHAR: case SYBNTEXT: case XSYBNCHAR: \ + case XSYBNVARCHAR #define CASE_ALL_BINARY \ SYBBINARY: case SYBVARBINARY: case SYBIMAGE: case XSYBBINARY: case XSYBVARBINARY: \ case SYBLONGBINARY: case TDS_CONVERT_BINARY @@ -1986,8 +1989,6 @@ tds_convert(const TDSCONTEXT *tds_ctx, int srctype, const void *src, TDS_UINT sr case SYBUNIQUE: length = tds_convert_unique(src, desttype, cr); break; - case SYBNVARCHAR: - case SYBNTEXT: case SYBMSTABLE: default: return TDS_CONVERT_NOAVAIL; diff --git a/src/tds/data.c b/src/tds/data.c index cb03d7fbd5..4c4e2880e7 100644 --- a/src/tds/data.c +++ b/src/tds/data.c @@ -247,6 +247,9 @@ tds_set_param_type(TDSCONNECTION * conn, TDSCOLUMN * curcol, TDS_SERVER_TYPE typ { if (IS_TDS7_PLUS(conn)) { switch (type) { + case SYBNVARCHAR: + type = XSYBNVARCHAR; + break; case SYBVARCHAR: type = XSYBVARCHAR; break; diff --git a/src/tds/tds_willconvert.pl b/src/tds/tds_willconvert.pl index acf1299410..f29f212c11 100755 --- a/src/tds/tds_willconvert.pl +++ b/src/tds/tds_willconvert.pl @@ -36,7 +36,8 @@ ($) return qw(DATETIME DATETIME4 DATE TIME MSDATE MSTIME MSDATETIME2 MSDATETIMEOFFSET 5BIGDATETIME 5BIGTIME) if $_ eq 'DATETIMEx'; return qw(BIT BITN) if $_ eq 'BITx'; return qw(BINARY VARBINARY IMAGE LONGBINARY XBINARY XVARBINARY) if $_ eq 'BINARYx'; - return qw(CHAR VARCHAR XCHAR XVARCHAR) if $_ eq 'CHARx'; + return qw(CHAR VARCHAR XCHAR XNCHAR XNVARCHAR XVARCHAR) if $_ eq 'CHARx'; + return qw(TEXT NTEXT) if $_ eq 'TEXT'; return ($_); } @@ -129,21 +130,23 @@ ($) } print "};\n"; +# NB: SYBSENSITIVITY (Sybase) == 103 (0x67) == SYBNVARCHAR (MS) + __DATA__ To From CHARx TEXT BINARYx INTx FLTx NUMERIC DECIMAL BITx MONEYx DATETIMEx BOUNDARY UNIQUE SENSITIVITY MSTABLE -CHARx T T T T T T T T T T T T t F -TEXT T T T T T T T T T T T T t F -BINARYx T T T T T F F F T F F F F F -INTx T T T T T T T T T F F F F F -FLTx T T T T T T T T T F F F F F -NUMERIC T T T T T T T T T F F F F F -DECIMAL T T T T T T T T T F F F F F -BITx T T T T T T T T T F F F F F -MONEYx T T T T T T T T T F F F F F -DATETIMEx T T T F F F F F F T F F F F -BOUNDARY T T F F F F F F F F T F F F -UNIQUE T T T F F F F F F F F T F F -SENSITIVITY t t F F F F F F F F F F t F +CHARx T T T T T T T T T T T T T F +TEXT T T T T T T T T T T T T T F +BINARYx T T T T T F F F T F F F T F +INTx T T T T T T T T T F F F T F +FLTx T T T T T T T T T F F F T F +NUMERIC T T T T T T T T T F F F T F +DECIMAL T T T T T T T T T F F F T F +BITx T T T T T T T T T F F F T F +MONEYx T T T T T T T T T F F F T F +DATETIMEx T T T F F F F F F T F F T F +BOUNDARY T T F F F F F F F F T F T F +UNIQUE T T T F F F F F F F F T T F +SENSITIVITY T T T T T T T T T T T T T F MSTABLE F F F F F F F F F F F F F T diff --git a/src/tds/unittests/convert.c b/src/tds/unittests/convert.c index f63d0e319c..7f6c81d093 100644 --- a/src/tds/unittests/convert.c +++ b/src/tds/unittests/convert.c @@ -39,6 +39,7 @@ free_convert(int type, CONV_RESULT *cr) { switch (type) { case SYBCHAR: case SYBVARCHAR: case SYBTEXT: case XSYBCHAR: case XSYBVARCHAR: + case SYBNVARCHAR: case SYBNTEXT: case XSYBNCHAR: case XSYBNVARCHAR: case SYBBINARY: case SYBVARBINARY: case SYBIMAGE: case XSYBBINARY: case XSYBVARBINARY: case SYBLONGBINARY: free(cr->c); @@ -158,10 +159,18 @@ main(int argc, char **argv) case XSYBVARBINARY: case XSYBCHAR: case XSYBVARCHAR: + case SYBNTEXT: + case SYBNVARCHAR: + case XSYBNCHAR: + case XSYBNVARCHAR: switch (desttype) { case SYBCHAR: case SYBVARCHAR: case SYBTEXT: + case SYBNTEXT: + case SYBNVARCHAR: + case XSYBNCHAR: + case XSYBNVARCHAR: case SYBDATETIME: case SYBDATETIME4: src = "Jan 1, 1999"; From 4551722c3a3d3cf60a14c08e735d29e7ab5ab6a4 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 11:36:51 -0400 Subject: [PATCH 24/49] ctlib: Optimize blob conversion for bulk transfers in. * Extend _cs_convert to take an additional handle argument (allowed to be NULL) to provide for the possibility of replacing the caller's original output buffer with the one tdsconvert allocated itself (as it always does for blobs), rather than copying the blob data. * blk.c (_blk_get_col_data): Provide a non-NULL handle, both for efficiency's sake and because tds_alloc_bcp_column_data imposes a 4 KiB cap with the expectation that callers will take this approach. (dblib already does.) --- include/ctlib.h | 6 +++-- src/ctlib/blk.c | 5 +++- src/ctlib/cs.c | 61 +++++++++++++++++++++++++++++++++++++++++-------- src/ctlib/ct.c | 3 ++- 4 files changed, 61 insertions(+), 14 deletions(-) diff --git a/include/ctlib.h b/include/ctlib.h index 1009b4e342..e1573fd6bb 100644 --- a/include/ctlib.h +++ b/include/ctlib.h @@ -393,8 +393,10 @@ CS_INT _ct_get_string_length(const char *buf, CS_INT buflen); int _cs_convert_not_client(CS_CONTEXT *ctx, const TDSCOLUMN *curcol, CONV_RESULT *convert_buffer, unsigned char **p_src); -CS_RETCODE _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdata, - const CS_DATAFMT_COMMON * destfmt, CS_VOID * destdata, CS_INT * resultlen); +CS_RETCODE _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, + CS_VOID * srcdata, const CS_DATAFMT_COMMON * destfmt, + CS_VOID * destdata, CS_INT * resultlen, + CS_VOID ** handle); bool _ct_is_large_identifiers_version(CS_INT version); const CS_DATAFMT_COMMON * _ct_datafmt_common(CS_CONTEXT * ctx, const CS_DATAFMT * datafmt); const CS_DATAFMT_LARGE *_ct_datafmt_conv_in(CS_CONTEXT * ctx, const CS_DATAFMT * datafmt, CS_DATAFMT_LARGE * fmtbuf); diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c index b104a6bfc0..ffc4979687 100644 --- a/src/ctlib/blk.c +++ b/src/ctlib/blk.c @@ -728,7 +728,10 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) /* if convert return FAIL mark error but process other columns */ if ((result = _cs_convert(ctx, &srcfmt, (CS_VOID *) src, - &destfmt, (CS_VOID *) bindcol->bcp_column_data->data, &destlen)) != CS_SUCCEED) { + &destfmt, (CS_VOID *) coldata->data, + &destlen, + (CS_VOID **) &coldata->data)) + != CS_SUCCEED) { tdsdump_log(TDS_DBG_INFO1, "convert failed for %d \n", srctype); return CS_FAIL; } diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c index 6a8dcbb499..2a74551e81 100644 --- a/src/ctlib/cs.c +++ b/src/ctlib/cs.c @@ -502,8 +502,9 @@ cs_config(CS_CONTEXT * ctx, CS_INT action, CS_INT property, CS_VOID * buffer, CS } CS_RETCODE -_cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdata, - const CS_DATAFMT_COMMON * destfmt, CS_VOID * destdata, CS_INT * resultlen) +_cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, + CS_VOID * srcdata, const CS_DATAFMT_COMMON * destfmt, + CS_VOID * destdata, CS_INT * resultlen, CS_VOID ** handle) { TDS_SERVER_TYPE src_type, desttype; int src_len, destlen, len; @@ -586,6 +587,14 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdat if (src_type == desttype) { int minlen = src_len < destlen? src_len : destlen; + if (handle != NULL && destvc == NULL) { + int type_len = tds_get_size_by_type(src_type); + if (type_len > minlen) { + minlen = type_len; + } + tds_realloc(handle, minlen + 1); + dest = (unsigned char *) *handle; + } tdsdump_log(TDS_DBG_FUNC, "cs_convert() srctype == desttype\n"); switch (desttype) { @@ -781,8 +790,14 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdat ret = CS_FAIL; len = destlen; } - memcpy(dest, cres.ib, len); - free(cres.ib); + if (handle == NULL) { + memcpy(dest, cres.ib, len); + free(cres.ib); + } else { + free(*handle); + *handle = cres.ib; + destlen = len; + } *resultlen = len; if (destvc) { destvc->len = len; @@ -845,7 +860,13 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdat tdsdump_log(TDS_DBG_FUNC, "not enough room for data + a null terminator - error\n"); ret = CS_FAIL; /* not enough room for data + a null terminator - error */ } else { - memcpy(dest, cres.c, len); + if (handle == NULL) { + memcpy(dest, cres.c, len); + } else { + free(*handle); + *handle = cres.c; + dest = *handle; + } dest[len] = 0; *resultlen = len + 1; } @@ -854,7 +875,13 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdat case CS_FMT_PADBLANK: tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_PADBLANK\n"); /* strcpy here can lead to a small buffer overflow */ - memcpy(dest, cres.c, len); + if (handle == NULL) { + memcpy(dest, cres.c, len); + } else { + free(*handle); + *handle = cres.c; + destlen = len; + } memset(dest + len, ' ', destlen - len); *resultlen = destlen; break; @@ -862,13 +889,24 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdat case CS_FMT_PADNULL: tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_PADNULL\n"); /* strcpy here can lead to a small buffer overflow */ - memcpy(dest, cres.c, len); + if (handle == NULL) { + memcpy(dest, cres.c, len); + } else { + free(*handle); + *handle = cres.c; + destlen = len; + } memset(dest + len, '\0', destlen - len); *resultlen = destlen; break; case CS_FMT_UNUSED: tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_UNUSED\n"); - memcpy(dest, cres.c, len); + if (handle == NULL) { + memcpy(dest, cres.c, len); + } else { + free(*handle); + *handle = cres.c; + } *resultlen = len; break; default: @@ -879,7 +917,9 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdat destvc->len = len; *resultlen = sizeof(*destvc); } - free(cres.c); + if (handle == NULL || *handle != cres.c) { + free(cres.c); + } break; default: ret = CS_FAIL; @@ -893,7 +933,8 @@ CS_RETCODE cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT * destfmt, CS_VOID * destdata, CS_INT * resultlen) { return _cs_convert(ctx, _ct_datafmt_common(ctx, srcfmt), srcdata, - _ct_datafmt_common(ctx, destfmt), destdata, resultlen); + _ct_datafmt_common(ctx, destfmt), destdata, + resultlen, NULL); } CS_RETCODE diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c index 2f08c86bce..569f327f9d 100644 --- a/src/ctlib/ct.c +++ b/src/ctlib/ct.c @@ -1957,7 +1957,8 @@ _ct_bind_data(CS_CONTEXT *ctx, TDSRESULTINFO * resinfo, TDSRESULTINFO *bindinfo, destfmt.format = bindcol->column_bindfmt; /* if convert return FAIL mark error but process other columns */ - if ((ret = _cs_convert(ctx, &srcfmt, src, &destfmt, dest, pdatalen) != CS_SUCCEED)) { + if ((ret = _cs_convert(ctx, &srcfmt, src, &destfmt, dest, + pdatalen, NULL) != CS_SUCCEED)) { tdsdump_log(TDS_DBG_FUNC, "cs_convert-result = %d\n", ret); result = 1; tdsdump_log(TDS_DBG_INFO1, "error: converted only %d bytes for type %d \n", From 5178e943bc2b94efe2c5cee796409125b33ca46c Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 11:49:03 -0400 Subject: [PATCH 25/49] _blk_get_col_data: Consistently return TDS_FAIL on failure. Most failure scenarios accidentally returned CS_FAIL, which ironically corresponds to TDS_SUCCESS. --- src/ctlib/blk.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c index ffc4979687..4810f54d85 100644 --- a/src/ctlib/blk.c +++ b/src/ctlib/blk.c @@ -694,7 +694,7 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) default: tdsdump_log(TDS_DBG_ERROR, "Not fixed length type (%d) and datalen not specified\n", bindcol->column_bindtype); - return CS_FAIL; + return TDS_FAIL; } } else { @@ -719,7 +719,7 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) if (desttype == CS_ILLEGAL_TYPE) desttype = _ct_get_client_type(bindcol, false); if (desttype == CS_ILLEGAL_TYPE) - return CS_FAIL; + return TDS_FAIL; destfmt.datatype = desttype; destfmt.maxlength = bindcol->on_server.column_size; destfmt.precision = bindcol->column_prec; @@ -733,7 +733,7 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) (CS_VOID **) &coldata->data)) != CS_SUCCEED) { tdsdump_log(TDS_DBG_INFO1, "convert failed for %d \n", srctype); - return CS_FAIL; + return TDS_FAIL; } if (destfmt.maxlength != bindcol->column_size && destfmt.datatype == CS_CHAR_TYPE From 35d3c8918014c279aa37d6461085ce8ad87515bb Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 11:52:20 -0400 Subject: [PATCH 26/49] blk.c: Handle CS_BLK_CANCEL in blk_done. To that end, factor a static _blk_clean_desc function out of blk_done's CS_BLK_ALL case. --- src/ctlib/blk.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c index 4810f54d85..24972379ed 100644 --- a/src/ctlib/blk.c +++ b/src/ctlib/blk.c @@ -42,6 +42,7 @@ static void _blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset); static TDSRET _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset); static CS_RETCODE _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred); static CS_RETCODE _blk_rowxfer_out(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred); +static void _blk_clean_desc(CS_BLKDESC * blkdesc); #define CONN(bulk) ((CS_CONNECTION *) (bulk)->bcpinfo.parent) @@ -282,19 +283,43 @@ blk_done(CS_BLKDESC * blkdesc, CS_INT type, CS_INT * outrow) *outrow = rows_copied; /* free allocated storage in blkdesc & initialise flags, etc. */ - tds_deinit_bcpinfo(&blkdesc->bcpinfo); - - blkdesc->bcpinfo.direction = 0; - blkdesc->bcpinfo.bind_count = CS_UNUSED; - blkdesc->bcpinfo.xfer_init = 0; - + _blk_clean_desc(blkdesc); break; + case CS_BLK_CANCEL: + tds->out_pos = 8; /* discard staged query data */ + /* Can't transition directly from SENDING to PENDING. */ + tds_set_state(tds, TDS_WRITING); + tds_set_state(tds, TDS_PENDING); + + tds_send_cancel(tds); + + if (TDS_FAILED(tds_process_cancel(tds))) { + _ctclient_msg(NULL, CONN(blkdesc), "blk_done", + 2, 5, 1, 140, ""); + return CS_FAIL; + } + + if (outrow) + *outrow = 0; + + /* free allocated storage in blkdesc & initialise flags, etc. */ + _blk_clean_desc(blkdesc); + break; } return CS_SUCCEED; } +static void _blk_clean_desc (CS_BLKDESC * blkdesc) +{ + tds_deinit_bcpinfo(&blkdesc->bcpinfo); + + blkdesc->bcpinfo.direction = 0; + blkdesc->bcpinfo.bind_count = CS_UNUSED; + blkdesc->bcpinfo.xfer_init = 0; +} + CS_RETCODE blk_drop(CS_BLKDESC * blkdesc) { From 949038e5aa9d6924970b930447700a94078079a2 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 14:24:07 -0400 Subject: [PATCH 27/49] Implement blk_textxfer, adjusting libtds as needed. * tds.h (struct tds_bcpinfo): Add more fields to enable the necessary bookkeeping. * ctlib/blk.c: Implement blk_textfer; adjust other functions accordingly. * tds/{bulk,data}.c: Allow for deferred, and possibly piecemeal, blob submission; in particular, make tds_bcp_send_record resumable. --- include/freetds/tds.h | 3 ++ src/ctlib/blk.c | 80 +++++++++++++++++++++------ src/tds/bulk.c | 122 +++++++++++++++++++++++++++++++++++------- src/tds/data.c | 7 ++- 4 files changed, 174 insertions(+), 38 deletions(-) diff --git a/include/freetds/tds.h b/include/freetds/tds.h index 0cb082d415..7df0714ea2 100644 --- a/include/freetds/tds.h +++ b/include/freetds/tds.h @@ -1716,6 +1716,9 @@ struct tds_bcpinfo TDSRESULTINFO *bindinfo; TDS5COLINFO *sybase_colinfo; TDS_INT sybase_count; + TDS_INT text_sent; + TDS_INT next_col; + TDS_INT blob_cols; }; TDSRET tds_bcp_init(TDSSOCKET *tds, TDSBCPINFO *bcpinfo); diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c index 24972379ed..60d25d398a 100644 --- a/src/ctlib/blk.c +++ b/src/ctlib/blk.c @@ -318,6 +318,9 @@ static void _blk_clean_desc (CS_BLKDESC * blkdesc) blkdesc->bcpinfo.direction = 0; blkdesc->bcpinfo.bind_count = CS_UNUSED; blkdesc->bcpinfo.xfer_init = 0; + blkdesc->bcpinfo.text_sent = 0; + blkdesc->bcpinfo.next_col = 0; + blkdesc->bcpinfo.blob_cols = 0; } CS_RETCODE @@ -519,10 +522,36 @@ blk_srvinit(SRV_PROC * srvproc, CS_BLKDESC * blkdescp) CS_RETCODE blk_textxfer(CS_BLKDESC * blkdesc, CS_BYTE * buffer, CS_INT buflen, CS_INT * outlen) { - tdsdump_log(TDS_DBG_FUNC, "blk_textxfer(%p, %p, %d, %p)\n", blkdesc, buffer, buflen, outlen); + TDSSOCKET *tds; + TDSCOLUMN *bindcol; - tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_textxfer()\n"); - return CS_FAIL; + if (blkdesc == NULL || buffer == NULL) { + return CS_FAIL; + } + + tds = CONN(blkdesc)->tds_socket; + + bindcol = blkdesc->bcpinfo.bindinfo->columns + [blkdesc->bcpinfo.next_col-1]; + + if (bindcol->column_varaddr != NULL) { + return CS_FAIL; + } + + bindcol->column_cur_size = buflen; + bindcol->column_lenbind = &bindcol->column_cur_size; + bindcol->column_varaddr = (TDS_CHAR*) buffer; + + if (TDS_FAILED(tds_bcp_send_record(tds, &blkdesc->bcpinfo, + _blk_get_col_data, _blk_null_error, + 0))) { + return CS_FAIL; + } else if (blkdesc->bcpinfo.next_col == 0) { + return CS_END_DATA; /* all done */ + } else { + bindcol->column_varaddr = NULL; + return CS_SUCCEED; /* still need more data */ + } } static CS_RETCODE @@ -619,6 +648,8 @@ _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred if (blkdesc->bcpinfo.xfer_init == 0) { + blkdesc->bcpinfo.xfer_init = 1; + /* * first call the start_copy function, which will * retrieve details of the database table columns @@ -626,16 +657,19 @@ _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred if (TDS_FAILED(tds_bcp_start_copy_in(tds, &blkdesc->bcpinfo))) { _ctclient_msg(NULL, CONN(blkdesc), "blk_rowxfer", 2, 5, 1, 140, ""); + + blkdesc->bcpinfo.xfer_init = 0; return CS_FAIL; } - - blkdesc->bcpinfo.xfer_init = 1; } for (each_row = 0; each_row < rows_to_xfer; each_row++ ) { if (tds_bcp_send_record(tds, &blkdesc->bcpinfo, _blk_get_col_data, _blk_null_error, each_row) == TDS_SUCCESS) { - /* FIXME */ + if (blkdesc->bcpinfo.next_col > 0) + return CS_BLK_HAS_TEXT; + } else { + return CS_FAIL; } } @@ -670,6 +704,15 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) tdsdump_log(TDS_DBG_FUNC, "_blk_get_col_data(%p, %p, %d)\n", bulk, bindcol, offset); + if (bindcol->column_nullbind) { + nullind = bindcol->column_nullbind; + nullind += offset; + } + if (bindcol->column_lenbind) { + datalen = bindcol->column_lenbind; + datalen += offset; + } + /* * Retrieve the initial bound column_varaddress * and increment it if offset specified @@ -677,21 +720,24 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) src = (unsigned char *) bindcol->column_varaddr; if (!src) { + if (nullind && *nullind == -1) { + null_column = true; + } + + bindcol->bcp_column_data->datalen = *datalen; + bindcol->bcp_column_data->is_null = null_column; + + if (is_blob_col(bindcol) + && bindcol->column_varaddr == NULL) { + /* Data will come piecemeal, via blk_textxfer. */ + return TDS_NO_MORE_RESULTS; + } + tdsdump_log(TDS_DBG_ERROR, "error source field not addressable\n"); return TDS_FAIL; } src += offset * bindcol->column_bindlen; - - if (bindcol->column_nullbind) { - nullind = bindcol->column_nullbind; - nullind += offset; - } - if (bindcol->column_lenbind) { - datalen = bindcol->column_lenbind; - datalen += offset; - } - srctype = bindcol->column_bindtype; /* passes to cs_convert */ tdsdump_log(TDS_DBG_INFO1, "blk_get_col_data srctype = %d\n", srctype); @@ -731,7 +777,7 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) null_column = true; } - if (!null_column) { + if (!null_column && !is_blob_type(bindcol->column_type)) { CONV_RESULT convert_buffer; CS_DATAFMT_COMMON srcfmt, destfmt; CS_INT desttype; diff --git a/src/tds/bulk.c b/src/tds/bulk.c index 786f6994c4..447ed3329d 100644 --- a/src/tds/bulk.c +++ b/src/tds/bulk.c @@ -51,6 +51,10 @@ #ifndef MAX #define MAX(a,b) ( (a) > (b) ? (a) : (b) ) #endif + +#ifndef MIN +#define MIN(a,b) ( (a) < (b) ? (a) : (b) ) +#endif /** \endcond */ /** @@ -77,6 +81,7 @@ static TDSRET tds5_process_insert_bulk_reply(TDSSOCKET * tds, TDSBCPINFO *bcpinf static TDSRET tds5_get_col_data_or_dflt(tds_bcp_get_col_data get_col_data, TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset, int colnum); +static int tds_bcp_is_bound(TDSBCPINFO *bcpinfo, TDSCOLUMN *colinfo); /** * Initialize BCP information. @@ -171,6 +176,9 @@ tds_bcp_init(TDSSOCKET *tds, TDSBCPINFO *bcpinfo) curcol->bcp_column_data = tds_alloc_bcp_column_data(sizeof(TDS_NUMERIC)); ((TDS_NUMERIC *) curcol->bcp_column_data->data)->precision = curcol->column_prec; ((TDS_NUMERIC *) curcol->bcp_column_data->data)->scale = curcol->column_scale; + } else if (bcpinfo->bind_count != 0 /* ctlib */ + && is_blob_col(curcol)) { + curcol->bcp_column_data = tds_alloc_bcp_column_data(0); } else { curcol->bcp_column_data = tds_alloc_bcp_column_data(MAX(curcol->column_size,curcol->on_server.column_size)); @@ -288,7 +296,8 @@ tds_bcp_start_insert_stmt(TDSSOCKET * tds, TDSBCPINFO * bcpinfo) for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) { bcpcol = bcpinfo->bindinfo->columns[i]; - if (bcpcol->column_timestamp) + if (bcpcol->column_timestamp + || !tds_bcp_is_bound(bcpinfo, bcpcol)) continue; if (!bcpinfo->identity_insert_on && bcpcol->column_identity) continue; @@ -333,18 +342,20 @@ tds_bcp_start_insert_stmt(TDSSOCKET * tds, TDSBCPINFO * bcpinfo) static TDSRET tds7_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, - tds_bcp_null_error null_error, int offset) + tds_bcp_null_error null_error, int offset, int start_col) { int i; - tds_put_byte(tds, TDS_ROW_TOKEN); /* 0xd1 */ - for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) { + if (start_col == 0) + tds_put_byte(tds, TDS_ROW_TOKEN); /* 0xd1 */ + for (i = start_col; i < bcpinfo->bindinfo->num_cols; i++) { TDS_INT save_size; unsigned char *save_data; TDSBLOB blob; TDSCOLUMN *bindcol; TDSRET rc; + bool has_text = false; bindcol = bcpinfo->bindinfo->columns[i]; @@ -355,7 +366,8 @@ tds7_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, if ((!bcpinfo->identity_insert_on && bindcol->column_identity) || bindcol->column_timestamp || - bindcol->column_computed) { + bindcol->column_computed || + !tds_bcp_is_bound(bcpinfo, bindcol)) { continue; } @@ -363,6 +375,8 @@ tds7_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, if (TDS_FAILED(rc)) { tdsdump_log(TDS_DBG_INFO1, "get_col_data (column %d) failed\n", i + 1); return rc; + } else if (rc == TDS_NO_MORE_RESULTS) { + has_text = true; } tdsdump_log(TDS_DBG_INFO1, "gotten column %d length %d null %d\n", i + 1, bindcol->bcp_column_data->datalen, bindcol->bcp_column_data->is_null); @@ -379,6 +393,9 @@ tds7_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, return TDS_FAIL; } bindcol->column_cur_size = -1; + } else if (has_text) { + bindcol->column_cur_size + = bindcol->bcp_column_data->datalen; } else if (is_blob_col(bindcol)) { bindcol->column_cur_size = bindcol->bcp_column_data->datalen; memset(&blob, 0, sizeof(blob)); @@ -394,21 +411,25 @@ tds7_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, if (TDS_FAILED(rc)) return rc; + else if (has_text) { + bcpinfo->next_col = i + 1; + /* bcpinfo->text_sent = 0; */ + return TDS_NO_MORE_RESULTS; + } } return TDS_SUCCESS; } static TDSRET -tds5_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, - tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset) +tds5_send_non_blobs(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, + tds_bcp_get_col_data get_col_data, + tds_bcp_null_error null_error, int offset) { int row_pos; int row_sz_pos; - int blob_cols = 0; int var_cols_written = 0; TDS_INT old_record_size = bcpinfo->bindinfo->row_size; unsigned char *record = bcpinfo->bindinfo->current_row; - int i; memset(record, '\0', old_record_size); /* zero the rowbuffer */ @@ -439,12 +460,24 @@ tds5_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_put_smallint(tds, row_pos); tds_put_n(tds, record, row_pos); + return TDS_SUCCESS; +} +static TDSRET +tds5_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, + tds_bcp_get_col_data get_col_data, + tds_bcp_null_error null_error, int offset, int start_col) +{ + int i; + if (start_col == 0) { + TDS_PROPAGATE(tds5_send_non_blobs(tds, bcpinfo, get_col_data, + null_error, offset)); + } /* row is done, now handle any text/image data */ - blob_cols = 0; + bcpinfo->blob_cols = 0; - for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) { + for (i = start_col; i < bcpinfo->bindinfo->num_cols; i++) { TDSCOLUMN *bindcol = bcpinfo->bindinfo->columns[i]; if (is_blob_type(bindcol->on_server.column_type)) { TDSRET rc; @@ -475,15 +508,20 @@ tds5_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, /* unknown but zero */ tds_put_smallint(tds, 0); tds_put_byte(tds, bindcol->on_server.column_type); - tds_put_byte(tds, 0xff - blob_cols); + tds_put_byte(tds, 0xff - bcpinfo->blob_cols); /* * offset of txptr we stashed during variable * column processing */ tds_put_smallint(tds, bindcol->column_textpos); tds_put_int(tds, bindcol->bcp_column_data->datalen); + if (rc == TDS_NO_MORE_RESULTS) { + bcpinfo->next_col = i + 1; + /* bcpinfo->text_sent = 0; */ + return rc; + } tds_put_n(tds, bindcol->bcp_column_data->data, bindcol->bcp_column_data->datalen); - blob_cols++; + bcpinfo->blob_cols++; } } @@ -504,6 +542,7 @@ tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset) { TDSRET rc; + int start_col = bcpinfo->next_col; tdsdump_log(TDS_DBG_FUNC, "tds_bcp_send_bcp_record(%p, %p, %p, %p, %d)\n", tds, bcpinfo, get_col_data, null_error, offset); @@ -511,13 +550,35 @@ tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, if (tds->out_flag != TDS_BULK || tds_set_state(tds, TDS_WRITING) != TDS_WRITING) return TDS_FAIL; + if (start_col > 0) { + TDSCOLUMN *bindcol = bcpinfo->bindinfo->columns[start_col - 1]; + *bindcol->column_lenbind + = MIN((TDS_INT) bindcol->column_bindlen + - bcpinfo->text_sent, + *bindcol->column_lenbind); + tds_put_n(tds, bindcol->column_varaddr, + *bindcol->column_lenbind); + bcpinfo->text_sent += *bindcol->column_lenbind; + if ((TDS_UINT) bcpinfo->text_sent < bindcol->column_bindlen) { + return TDS_SUCCESS; /* That's all for now. */ + } else if (!IS_TDS7_PLUS(tds->conn)) { + bcpinfo->blob_cols++; + } + bcpinfo->next_col = 0; + bcpinfo->text_sent = 0; + } + if (IS_TDS7_PLUS(tds->conn)) rc = tds7_send_record(tds, bcpinfo, get_col_data, null_error, - offset); + offset, start_col); else - rc = tds5_send_record(tds, bcpinfo, get_col_data, null_error, offset); + rc = tds5_send_record(tds, bcpinfo, get_col_data, null_error, + offset, start_col); + if (rc == TDS_NO_MORE_RESULTS) + return TDS_SUCCESS; tds_set_state(tds, TDS_SENDING); + bcpinfo->next_col = 0; return rc; } @@ -663,9 +724,10 @@ tds5_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_ tdsdump_log(TDS_DBG_FUNC, "%4s %8s %8s %8s\n", "col", "ncols", "row_pos", "cpbytes"); - for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) { + for (i = bcpinfo->next_col; i < bcpinfo->bindinfo->num_cols; i++) { unsigned int cpbytes = 0; TDSCOLUMN *bcpcol = bcpinfo->bindinfo->columns[i]; + TDSRET rc; /* * Is this column of "variable" type, i.e. NULLable @@ -681,9 +743,13 @@ tds5_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_ tdsdump_log(TDS_DBG_FUNC, "%4d %8d %8d %8d\n", i, ncols, row_pos, cpbytes); - if (TDS_FAILED(tds5_get_col_data_or_dflt(get_col_data, bcpinfo, - bcpcol, offset, i))) + rc = tds5_get_col_data_or_dflt(get_col_data, bcpinfo, bcpcol, + offset, i); + if (TDS_FAILED(rc)) { return -1; + } else if (rc == TDS_NO_MORE_RESULTS) { + bcpinfo->next_col = i + 1; + } /* If it's a NOT NULL column, and we have no data, throw an error. * This is the behavior for Sybase, this function is only used for Sybase */ @@ -809,7 +875,8 @@ tds7_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo) bcpcol = bcpinfo->bindinfo->columns[i]; if ((!bcpinfo->identity_insert_on && bcpcol->column_identity) || bcpcol->column_timestamp || - bcpcol->column_computed) { + bcpcol->column_computed || + !tds_bcp_is_bound(bcpinfo, bcpcol)) { continue; } num_cols++; @@ -830,7 +897,8 @@ tds7_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo) if ((!bcpinfo->identity_insert_on && bcpcol->column_identity) || bcpcol->column_timestamp || - bcpcol->column_computed) { + bcpcol->column_computed || + !tds_bcp_is_bound(bcpinfo, bcpcol)) { continue; } @@ -1493,3 +1561,17 @@ tds_writetext_end(TDSSOCKET *tds) tds_set_state(tds, TDS_PENDING); return TDS_SUCCESS; } + + +static int tds_bcp_is_bound(TDSBCPINFO *bcpinfo, TDSCOLUMN *colinfo) +{ + return (bcpinfo && colinfo && + /* Don't interfere with dblib bulk insertion from files. */ + (bcpinfo->xfer_init == 0 + || colinfo->column_varaddr != NULL + || (colinfo->column_lenbind != NULL + && (*colinfo->column_lenbind != 0 + || (colinfo->column_nullbind != NULL + /* null-value for blk_textxfer ... */ + /* && *colinfo->column_nullbind == -1 */))))); +} diff --git a/src/tds/data.c b/src/tds/data.c index 4c4e2880e7..7239ff4558 100644 --- a/src/tds/data.c +++ b/src/tds/data.c @@ -975,7 +975,7 @@ tds_generic_put(TDSSOCKET * tds, TDSCOLUMN * curcol, int bcp7) size = tds_fix_column_size(tds, curcol); src = curcol->column_data; - if (is_blob_col(curcol)) { + if (is_blob_col(curcol) && src != NULL) { blob = (TDSBLOB *) src; src = (unsigned char *) blob->textvalue; } @@ -1065,6 +1065,8 @@ tds_generic_put(TDSSOCKET * tds, TDSCOLUMN * curcol, int bcp7) /* put real data */ if (blob) { tds_put_n(tds, s, colsize); + } else if (is_blob_col(curcol)) { + return TDS_SUCCESS; /* anticipate ctlib blk_textxfer */ } else { #ifdef WORDS_BIGENDIAN unsigned char buf[64]; @@ -1130,6 +1132,9 @@ tds_generic_put(TDSSOCKET * tds, TDSCOLUMN * curcol, int bcp7) /* put real data */ if (blob) { tds_put_n(tds, s, colsize); + } else if (is_blob_col(curcol)) { + /* accommodate ctlib blk_textxfer */ + return TDS_SUCCESS; } else { #ifdef WORDS_BIGENDIAN unsigned char buf[64]; From 4e8f8411104c87af54d785e7cbf6ccb8610564f9 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 14:33:50 -0400 Subject: [PATCH 28/49] cs_convert, dbconvert: Truncate data as needed. * Automatically truncate strings that would overflow their destinations, mainly for the sake of bulk insertions. * Fully honor *BINARY and IMAGE data buffer size limits in cs_convert. * Update unit tests (ctlib cs_convert, dblib t0019) accordingly. --- src/ctlib/cs.c | 9 ++++----- src/ctlib/unittests/cs_convert.c | 6 ++++-- src/dblib/dblib.c | 12 ++++++++++-- src/dblib/unittests/t0019.c | 6 ++++-- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c index 2a74551e81..b5037e3c96 100644 --- a/src/ctlib/cs.c +++ b/src/ctlib/cs.c @@ -603,14 +603,14 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, case SYBBINARY: case SYBVARBINARY: case SYBIMAGE: - memcpy(dest, srcdata, src_len); - *resultlen = src_len; + memcpy(dest, srcdata, minlen); + *resultlen = minlen; if (src_len > destlen) { tdsdump_log(TDS_DBG_FUNC, "error: src_len > destlen\n"); _csclient_msg(ctx, "cs_convert", 2, 4, 1, 36, ""); - ret = CS_FAIL; - } else { + src_len = destlen; + } /* else */ { switch (destfmt->format) { case CS_FMT_PADNULL: memset(dest + src_len, '\0', destlen - src_len); @@ -850,7 +850,6 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, tdsdump_log(TDS_DBG_FUNC, "Data-conversion resulted in overflow\n"); _csclient_msg(ctx, "cs_convert", 2, 4, 1, 36, ""); len = destlen; - ret = CS_FAIL; } switch (destfmt->format) { diff --git a/src/ctlib/unittests/cs_convert.c b/src/ctlib/unittests/cs_convert.c index 3d67ad78e3..cc32c949b1 100644 --- a/src/ctlib/unittests/cs_convert.c +++ b/src/ctlib/unittests/cs_convert.c @@ -297,11 +297,13 @@ main(void) DO_TEST(CS_INT test = 1234567; CS_CHAR test2[] = "1234567", CS_INT_TYPE, &test, sizeof(test), CS_CHAR_TYPE, 7, CS_SUCCEED, test2, 7); DO_TEST(CS_CHAR test[] = "abc"; - CS_CHAR test2[] = "ab", CS_CHAR_TYPE, test, 3, CS_CHAR_TYPE, 2, CS_FAIL, test2, 2); + CS_CHAR test2[] = "ab", CS_CHAR_TYPE, test, 3, CS_CHAR_TYPE, 2, + CS_SUCCEED /* CS_FAIL */, test2, 2); DO_TEST(CS_CHAR test[] = "abc"; CS_CHAR test2[] = "616263", CS_BINARY_TYPE, test, 3, CS_CHAR_TYPE, 6, CS_SUCCEED, test2, 6); DO_TEST(CS_CHAR test[] = "abcdef"; - CS_CHAR test2[] = "616263", CS_BINARY_TYPE, test, 6, CS_CHAR_TYPE, 6, CS_FAIL, test2, 6); + CS_CHAR test2[] = "616263", CS_BINARY_TYPE, test, 6, + CS_CHAR_TYPE, 6, CS_SUCCEED /* CS_FAIL */, test2, 6); /* conversion to various binaries */ DO_TEST(CS_CHAR test[] = "616263646566"; diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c index 966cb0acd9..0e45631889 100644 --- a/src/dblib/dblib.c +++ b/src/dblib/dblib.c @@ -2422,10 +2422,14 @@ dbconvert_ps(DBPROCESS * dbproc, int db_srctype, const BYTE * src, DBINT srclen, break; default: assert(destlen > 0); - if (destlen < 0 || srclen > destlen) { + if (destlen < 0) { dbperror(dbproc, SYBECOFL, 0); ret = -1; } else { + if (srclen > destlen) { + dbperror(dbproc, 50000, 0); + srclen = destlen; + } memcpy(dest, src, srclen); if (srclen < destlen) memset(dest + srclen, ' ', destlen - srclen); @@ -2560,13 +2564,17 @@ dbconvert_ps(DBPROCESS * dbproc, int db_srctype, const BYTE * src, DBINT srclen, break; default: assert(destlen > 0); - if (destlen < 0 || len > destlen) { + if (destlen < 0) { dbperror(dbproc, SYBECOFL, 0); ret = -1; tdsdump_log(TDS_DBG_INFO1, "%d bytes type %d -> %d, destlen %d < %d required\n", srclen, srctype, desttype, destlen, len); break; } + if (len > destlen) { + dbperror(dbproc, 50000, 0); + len = destlen; + } /* else pad with blanks */ memcpy(dest, dres.c, len); if (len < destlen) diff --git a/src/dblib/unittests/t0019.c b/src/dblib/unittests/t0019.c index 84ac6694d0..63284241c0 100644 --- a/src/dblib/unittests/t0019.c +++ b/src/dblib/unittests/t0019.c @@ -93,8 +93,10 @@ main(void) TEST((SYBCHAR, "ciao\0\0", 6, SYBCHAR, -1), "len=6 63 69 61 6F 00 00 00 2A 2A 2A"); TEST((SYBCHAR, "ciao ", 6, SYBCHAR, 8), "len=6 63 69 61 6F 20 20 20 20 2A 2A"); TEST((SYBCHAR, "ciao\0\0", 6, SYBCHAR, 8), "len=6 63 69 61 6F 00 00 20 20 2A 2A"); - TEST((SYBCHAR, "ciao ", 6, SYBCHAR, 4), "error"); - TEST((SYBCHAR, "ciao\0\0", 6, SYBCHAR, 4), "error"); + TEST((SYBCHAR, "ciao ", 6, SYBCHAR, 4), + "len=4 63 69 61 6F 2A 2A 2A 2A 2A 2A" /* "error" */); + TEST((SYBCHAR, "ciao\0\0", 6, SYBCHAR, 4), + "len=4 63 69 61 6F 2A 2A 2A 2A 2A 2A" /* "error" */); TEST((SYBCHAR, "ciao ", 6, SYBCHAR, 6), "len=6 63 69 61 6F 20 20 2A 2A 2A 2A"); TEST((SYBCHAR, "ciao\0\0", 6, SYBCHAR, 6), "len=6 63 69 61 6F 00 00 2A 2A 2A 2A"); From cae3130ec699f067bf61eb8f8beda3fb8e43682c Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 14:39:14 -0400 Subject: [PATCH 29/49] ct_get_data: Distinguish NULL and empty strings via *outlen. Negative if NULL, 0 if merely empty. --- src/ctlib/ct.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c index 569f327f9d..7c3ce225b0 100644 --- a/src/ctlib/ct.c +++ b/src/ctlib/ct.c @@ -2985,8 +2985,15 @@ ct_get_data(CS_COMMAND * cmd, CS_INT item, CS_VOID * buffer, CS_INT buflen, CS_I */ srclen = curcol->column_cur_size; - if (srclen < 0) - srclen = 0; + if (srclen < 0) { + /* this is NULL */ + if (outlen) + *outlen = srclen; + if (item < resinfo->num_cols) + return CS_END_ITEM; + return CS_END_DATA; + } + src += cmd->get_data_bytes_returned; srclen -= cmd->get_data_bytes_returned; From c58d6711e817f5f91b1d8c87a1f1ad632a451b5d Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 14:50:25 -0400 Subject: [PATCH 30/49] ctlib: Better support new date/time types (DATETIME2, etc.) * Allow _cs_convert to accept an explicit TDS destination type; direct it to copy cres.dta if that destination type is SYBMS{DATE,TIME}*. * _blk_get_col_data: Don't give _cs_convert_not_client any data to convert (blindly in the wrong direction!); rather, if it indicates that the column holds a new MS type, supply an explicit TDS destination type to _cs_convert. * _cs_dt_crack_v2: Formally populate datetzone from dr.timezone (still always 0 in practice). --- include/ctlib.h | 2 +- src/ctlib/blk.c | 11 +++++++---- src/ctlib/cs.c | 26 +++++++++++++++++++------- src/ctlib/ct.c | 3 ++- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/include/ctlib.h b/include/ctlib.h index e1573fd6bb..72c05a8ae7 100644 --- a/include/ctlib.h +++ b/include/ctlib.h @@ -396,7 +396,7 @@ int _cs_convert_not_client(CS_CONTEXT *ctx, const TDSCOLUMN *curcol, CONV_RESULT CS_RETCODE _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdata, const CS_DATAFMT_COMMON * destfmt, CS_VOID * destdata, CS_INT * resultlen, - CS_VOID ** handle); + TDS_SERVER_TYPE desttype, CS_VOID ** handle); bool _ct_is_large_identifiers_version(CS_INT version); const CS_DATAFMT_COMMON * _ct_datafmt_common(CS_CONTEXT * ctx, const CS_DATAFMT * datafmt); const CS_DATAFMT_LARGE *_ct_datafmt_conv_in(CS_CONTEXT * ctx, const CS_DATAFMT * datafmt, CS_DATAFMT_LARGE * fmtbuf); diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c index 60d25d398a..c311f3d3bc 100644 --- a/src/ctlib/blk.c +++ b/src/ctlib/blk.c @@ -778,17 +778,20 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) } if (!null_column && !is_blob_type(bindcol->column_type)) { - CONV_RESULT convert_buffer; CS_DATAFMT_COMMON srcfmt, destfmt; CS_INT desttype; + TDS_SERVER_TYPE tds_desttype = TDS_INVALID_TYPE; TDSSOCKET * tds = CONN(blkdesc)->tds_socket; srcfmt.datatype = srctype; srcfmt.maxlength = srclen; - desttype = _cs_convert_not_client(ctx, bindcol, &convert_buffer, &src); - if (desttype == CS_ILLEGAL_TYPE) + desttype = _cs_convert_not_client(NULL, bindcol, NULL, NULL); + if (desttype == CS_ILLEGAL_TYPE) { desttype = _ct_get_client_type(bindcol, false); + } else { + tds_desttype = bindcol->column_type; + } if (desttype == CS_ILLEGAL_TYPE) return TDS_FAIL; destfmt.datatype = desttype; @@ -800,7 +803,7 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) /* if convert return FAIL mark error but process other columns */ if ((result = _cs_convert(ctx, &srcfmt, (CS_VOID *) src, &destfmt, (CS_VOID *) coldata->data, - &destlen, + &destlen, tds_desttype, (CS_VOID **) &coldata->data)) != CS_SUCCEED) { tdsdump_log(TDS_DBG_INFO1, "convert failed for %d \n", srctype); diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c index b5037e3c96..52c54af86c 100644 --- a/src/ctlib/cs.c +++ b/src/ctlib/cs.c @@ -504,9 +504,10 @@ cs_config(CS_CONTEXT * ctx, CS_INT action, CS_INT property, CS_VOID * buffer, CS CS_RETCODE _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdata, const CS_DATAFMT_COMMON * destfmt, - CS_VOID * destdata, CS_INT * resultlen, CS_VOID ** handle) + CS_VOID * destdata, CS_INT * resultlen, + TDS_SERVER_TYPE desttype, CS_VOID ** handle) { - TDS_SERVER_TYPE src_type, desttype; + TDS_SERVER_TYPE src_type; int src_len, destlen, len; CONV_RESULT cres; unsigned char *dest; @@ -557,10 +558,13 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, } datatype = destfmt->datatype; - desttype = _ct_get_server_type(NULL, datatype); if (desttype == TDS_INVALID_TYPE) { - _csclient_msg(ctx, "cs_convert", 2, 1, 1, 16, "%d, %d", srcfmt->datatype, destfmt->datatype); - return CS_FAIL; + desttype = _ct_get_server_type(NULL, datatype); + if (desttype == TDS_INVALID_TYPE) { + _csclient_msg(ctx, "cs_convert", 2, 1, 1, 16, "%d, %d", + srcfmt->datatype, destfmt->datatype); + return CS_FAIL; + } } destlen = destfmt->maxlength; if (datatype == CS_VARCHAR_TYPE || @@ -840,6 +844,14 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, *resultlen = src_len; ret = CS_SUCCEED; break; + case SYBMSTIME: + case SYBMSDATE: + case SYBMSDATETIME2: + case SYBMSDATETIMEOFFSET: + *resultlen = sizeof(TDS_DATETIMEALL); + memcpy(dest, &(cres.dta), *resultlen); + ret = CS_SUCCEED; + break; case SYBCHAR: case SYBVARCHAR: case SYBTEXT: @@ -933,7 +945,7 @@ cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT { return _cs_convert(ctx, _ct_datafmt_common(ctx, srcfmt), srcdata, _ct_datafmt_common(ctx, destfmt), destdata, - resultlen, NULL); + resultlen, TDS_INVALID_TYPE, NULL); } CS_RETCODE @@ -983,7 +995,7 @@ cs_dt_crack_v2(CS_CONTEXT * ctx, CS_INT datetype, CS_VOID * dateval, CS_DATEREC daterec->dateminute = dr.minute; daterec->datesecond = dr.second; daterec->datemsecond = dr.decimicrosecond / 10000u; - daterec->datetzone = 0; + daterec->datetzone = dr.timezone; if (extended) { daterec->datesecfrac = dr.decimicrosecond / 10u; daterec->datesecprec = 1000000; diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c index 7c3ce225b0..32a6374ea4 100644 --- a/src/ctlib/ct.c +++ b/src/ctlib/ct.c @@ -1958,7 +1958,8 @@ _ct_bind_data(CS_CONTEXT *ctx, TDSRESULTINFO * resinfo, TDSRESULTINFO *bindinfo, /* if convert return FAIL mark error but process other columns */ if ((ret = _cs_convert(ctx, &srcfmt, src, &destfmt, dest, - pdatalen, NULL) != CS_SUCCEED)) { + pdatalen, TDS_INVALID_TYPE, NULL) + != CS_SUCCEED)) { tdsdump_log(TDS_DBG_FUNC, "cs_convert-result = %d\n", ret); result = 1; tdsdump_log(TDS_DBG_INFO1, "error: converted only %d bytes for type %d \n", From 4c28686ac4a697a0297f6f705a0a548a561dd58f Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 14:53:55 -0400 Subject: [PATCH 31/49] _blk_get_col_data: Bail (successfully) on null columns. --- src/ctlib/blk.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c index c311f3d3bc..5e30508872 100644 --- a/src/ctlib/blk.c +++ b/src/ctlib/blk.c @@ -727,8 +727,10 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) bindcol->bcp_column_data->datalen = *datalen; bindcol->bcp_column_data->is_null = null_column; - if (is_blob_col(bindcol) - && bindcol->column_varaddr == NULL) { + if (null_column) { + return TDS_SUCCESS; + } else if (is_blob_col(bindcol) + && bindcol->column_varaddr == NULL) { /* Data will come piecemeal, via blk_textxfer. */ return TDS_NO_MORE_RESULTS; } From d5ba54a4f55cd05685ec4650ff2112f30daddce0 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 14:59:25 -0400 Subject: [PATCH 32/49] Declare and implement blk_sethints. Store a copy of the hints; clean it up in _blk_clean_desc. --- include/bkpublic.h | 1 + src/ctlib/blk.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/include/bkpublic.h b/include/bkpublic.h index d43c60c3db..7ac3754e58 100644 --- a/include/bkpublic.h +++ b/include/bkpublic.h @@ -56,6 +56,7 @@ CS_RETCODE blk_rowxfer(CS_BLKDESC * blkdesc); CS_RETCODE blk_rowxfer_mult(CS_BLKDESC * blkdesc, CS_INT * row_count); CS_RETCODE blk_sendrow(CS_BLKDESC * blkdesc, CS_BLK_ROW * row); CS_RETCODE blk_sendtext(CS_BLKDESC * blkdesc, CS_BLK_ROW * row, CS_BYTE * buffer, CS_INT buflen); +CS_RETCODE blk_sethints(CS_BLKDESC* blkdesc, CS_CHAR* hints, CS_INT hintslen); CS_RETCODE blk_srvinit(SRV_PROC * srvproc, CS_BLKDESC * blkdescp); CS_RETCODE blk_textxfer(CS_BLKDESC * blkdesc, CS_BYTE * buffer, CS_INT buflen, CS_INT * outlen); diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c index 5e30508872..2ec1e794ce 100644 --- a/src/ctlib/blk.c +++ b/src/ctlib/blk.c @@ -313,6 +313,15 @@ blk_done(CS_BLKDESC * blkdesc, CS_INT type, CS_INT * outrow) static void _blk_clean_desc (CS_BLKDESC * blkdesc) { + if (blkdesc->bcpinfo.hint) { + /* + * hint is formally const, so TDS_ZERO_FREE would yield + * a warning. + */ + free((char*)blkdesc->bcpinfo.hint); + blkdesc->bcpinfo.hint = NULL; + } + tds_deinit_bcpinfo(&blkdesc->bcpinfo); blkdesc->bcpinfo.direction = 0; @@ -510,6 +519,21 @@ blk_sendtext(CS_BLKDESC * blkdesc, CS_BLK_ROW * row, CS_BYTE * buffer, CS_INT bu return CS_FAIL; } +CS_RETCODE +blk_sethints(CS_BLKDESC* blkdesc, CS_CHAR* hints, CS_INT hintslen) +{ + char * h; + + if (blkdesc == NULL || (h = tds_new(char, hintslen + 1)) == NULL) { + return CS_FAIL; + } + + strlcpy(h, hints, hintslen + 1); + blkdesc->bcpinfo.hint = h; + + return CS_SUCCEED; +} + CS_RETCODE blk_srvinit(SRV_PROC * srvproc, CS_BLKDESC * blkdescp) { From fbe170699a978dc1fc6b6c60fdc451f7821e1f9d Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 15:02:54 -0400 Subject: [PATCH 33/49] _ct_get_client_type: Handle SYBUINTN. --- src/ctlib/ct.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c index 32a6374ea4..5f279007b8 100644 --- a/src/ctlib/ct.c +++ b/src/ctlib/ct.c @@ -2147,6 +2147,20 @@ _ct_get_client_type(const TDSCOLUMN *col, bool describe) case SYBUINT8: return CS_UBIGINT_TYPE; break; + case SYBUINTN: + switch (col->column_size) { + case 8: + return CS_UBIGINT_TYPE; + case 4: + return CS_UINT_TYPE; + case 2: + return CS_USMALLINT_TYPE; + case 1: + return CS_TINYINT_TYPE; + default: + break; + } + break; case SYBDATE: return CS_DATE_TYPE; break; From b32da94afbfb8692cf038b8c647dab4a1490bb4a Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 15:06:24 -0400 Subject: [PATCH 34/49] ct_cursor: Predict cursor type for CS_CURSOR_DECLARE. Request forward-only cursors for updates, keyset-driven cursors otherwise. Regardless, specify optimistic cursors, which check timestamps and, when they're not available, values. --- src/ctlib/ct.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c index 5f279007b8..a269735a82 100644 --- a/src/ctlib/ct.c +++ b/src/ctlib/ct.c @@ -3961,6 +3961,29 @@ ct_poll(CS_CONTEXT * ctx, CS_CONNECTION * connection, CS_INT milliseconds, CS_CO return CS_FAIL; } +static +char* get_next_tok(char* str, char* delimiter, char **endptr) +{ + char* result = NULL; + *endptr = NULL; + + if (str && delimiter) { + size_t str_len = strlen(str); + size_t pos = strspn(str, delimiter); + + if (pos == 0) { + *endptr = strpbrk(str, delimiter); + return str; + } else if (pos != str_len) { + result = str + pos; + *endptr = strpbrk(result, delimiter); + } + } + + return result; +} + + CS_RETCODE ct_cursor(CS_COMMAND * cmd, CS_INT type, CS_CHAR * name, CS_INT namelen, CS_CHAR * text, CS_INT tlen, CS_INT option) { @@ -4003,6 +4026,52 @@ ct_cursor(CS_COMMAND * cmd, CS_INT type, CS_CHAR * name, CS_INT namelen, CS_CHAR cursor->status.close = TDS_CURSOR_STATE_UNACTIONED; cursor->status.dealloc = TDS_CURSOR_STATE_UNACTIONED; + if (option == CS_UNUSED || (option & CS_END) != 0) { + /* Try to figure out type of the cursor. */ + char delimiter[] = "\n\t,.[]() "; + enum { + eBaseline, + eFor, + eForUpdate + } state = eBaseline; + char* savept = NULL; + char* s = text; + + char* tok = get_next_tok(s, delimiter, &savept); + while (tok != NULL) { + s = savept; + + if (strcasecmp(tok, "FOR") == 0) { + state = eFor; + } else if (state == eFor + && strcasecmp(tok, "UPDATE") == 0) + { + state = eForUpdate; + break; + } else { + state = eBaseline; + } + + tok = get_next_tok(s, delimiter, &savept); + } + + if (state == eForUpdate) { + cursor->type = 0x4; /* Forward-only cursor. */ + } else { + /* readonly */ + cursor->type = 0x1; + /* Keyset-driven cursor. Default value. */ + } + } else if ((option & CS_FOR_UPDATE) != 0) { + cursor->type = 0x4; /* Forward-only cursor. */ + } else { + cursor->type = 0x1; + /* Keyset-driven cursor. Default value. */ + } + + cursor->concurrency = 0x2004; + /* Optimistic. Checks timestamps if available, else values. */ + tds_release_cursor(&cmd->cursor); cmd->cursor = cursor; ct_set_command_state(cmd, _CS_COMMAND_READY); From f9066c0182dba82a5db15284363ee256b89f31f3 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 15:09:06 -0400 Subject: [PATCH 35/49] ct_get_data: Populate cmd->iodesc->name more efficiently. Explicitly build cmd->iodesc->name and update ...->namelen along the way rather than calling sprintf and strlen (which can be slow). --- src/ctlib/ct.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c index a269735a82..033f596ae0 100644 --- a/src/ctlib/ct.c +++ b/src/ctlib/ct.c @@ -2973,11 +2973,26 @@ ct_get_data(CS_COMMAND * cmd, CS_INT item, CS_VOID * buffer, CS_INT buflen, CS_I if (table_namelen + column_namelen + 2 > sizeof(cmd->iodesc->name)) column_namelen = sizeof(cmd->iodesc->name) - 2 - table_namelen; - sprintf(cmd->iodesc->name, "%*.*s.%*.*s", - (int) table_namelen, (int) table_namelen, tds_dstr_cstr(&curcol->table_name), - (int) column_namelen, (int) column_namelen, tds_dstr_cstr(&curcol->column_name)); + if (table_namelen) { + memcpy(cmd->iodesc->name, + tds_dstr_cstr(&curcol->table_name), + table_namelen); + cmd->iodesc->namelen = (CS_INT) table_namelen; + } else { + cmd->iodesc->namelen = 0; + } + + cmd->iodesc->name[cmd->iodesc->namelen] = '.'; + ++cmd->iodesc->namelen; + + if (column_namelen) { + memcpy(cmd->iodesc->name + cmd->iodesc->namelen, + tds_dstr_cstr(&curcol->column_name), + column_namelen); + cmd->iodesc->namelen += (CS_INT) column_namelen; + } - cmd->iodesc->namelen = strlen(cmd->iodesc->name); + cmd->iodesc->name[cmd->iodesc->namelen] = '\0'; if (blob && blob->valid_ptr) { memcpy(cmd->iodesc->timestamp, blob->timestamp, CS_TS_SIZE); From b4a55669032c46c045bae54dcc1831fdd5c19d50 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 15:43:17 -0400 Subject: [PATCH 36/49] ct.c (paraminfoalloc): Report long variable-width values. Report (anticipated) truncation when given data for a variable-width type whose maximum width is less than the supplied data length. (The actual truncation will occur in libtds code that cannot readily complain about it.) To that end, copy error code 36's description from cs.c. --- src/ctlib/ct.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c index 033f596ae0..d3b33f0a40 100644 --- a/src/ctlib/ct.c +++ b/src/ctlib/ct.c @@ -154,6 +154,10 @@ _ct_get_user_api_layer_error(int error) case 15: return "Use direction CS_BLK_IN or CS_BLK_OUT for a bulk copy operation."; break; + case 36: + return "The result is truncated because the" + " conversion/operation resulted in overflow."; + break; case 51: return "Exactly one of context and connection must be non-NULL."; break; @@ -2993,7 +2997,6 @@ ct_get_data(CS_COMMAND * cmd, CS_INT item, CS_VOID * buffer, CS_INT buflen, CS_I } cmd->iodesc->name[cmd->iodesc->namelen] = '\0'; - if (blob && blob->valid_ptr) { memcpy(cmd->iodesc->timestamp, blob->timestamp, CS_TS_SIZE); cmd->iodesc->timestamplen = CS_TS_SIZE; @@ -4374,6 +4377,14 @@ paraminfoalloc(TDSSOCKET * tds, CS_PARAM * first_param) pcol->column_prec = p->precision; pcol->column_scale = p->scale; if (pcol->column_varint_size) { + if ((pcol->column_varint_size == 2 + && *(p->datalen) > 8000) + || (pcol->column_varint_size == 1 + && *(p->datalen) > 255)) { + _ctclient_msg(NULL, + (CS_CONNECTION*) tds_get_parent(tds), + "paraminfoalloc", 1, 1, 10, 36, ""); + } if (p->maxlen < 0) { tds_free_param_results(params); return NULL; From a2ad0c55eb0442753ef40a1a76c29fbde99a8b72 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 15:53:23 -0400 Subject: [PATCH 37/49] ct_describe: Issue an error for unsupported server types. --- src/ctlib/ct.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c index d3b33f0a40..71184f8f8c 100644 --- a/src/ctlib/ct.c +++ b/src/ctlib/ct.c @@ -2523,8 +2523,12 @@ ct_describe(CS_COMMAND * cmd, CS_INT item, CS_DATAFMT * datafmt_arg) datafmt->namelen = strlen(datafmt->name); /* need to turn the SYBxxx into a CS_xxx_TYPE */ datafmt->datatype = _ct_get_client_type(curcol, true); - if (datafmt->datatype == CS_ILLEGAL_TYPE) + if (datafmt->datatype == CS_ILLEGAL_TYPE) { + _ctclient_msg(NULL, cmd->con, "ct_describe", 1, 1, 1, 4, + "%s, %s", "column type", + tds_prtype(curcol->column_type)); return CS_FAIL; + } tdsdump_log(TDS_DBG_INFO1, "ct_describe() datafmt->datatype = %d server type %d\n", datafmt->datatype, curcol->column_type); if (is_numeric_type(curcol->column_type)) From d183a18a41841268e48bd9073f252a4e719449c0 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 15:56:14 -0400 Subject: [PATCH 38/49] cspublic.h: Formally define BLK_VERSION_{155,157,160} ... at least in the absence of CS_NO_LARGE_IDENTIFIERS; the corresponding CS_VERSION_* identifiers will otherwise be undefined anyway. --- include/cspublic.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/cspublic.h b/include/cspublic.h index 80917c969f..82068fe654 100644 --- a/include/cspublic.h +++ b/include/cspublic.h @@ -479,6 +479,11 @@ enum #define BLK_VERSION_120 CS_VERSION_120 #define BLK_VERSION_125 CS_VERSION_125 #define BLK_VERSION_150 CS_VERSION_150 +#ifndef CS_NO_LARGE_IDENTIFIERS +#define BLK_VERSION_155 CS_VERSION_155 +#define BLK_VERSION_157 CS_VERSION_157 +#define BLK_VERSION_160 CS_VERSION_160 +#endif #define CS_FORCE_EXIT 300 #define CS_FORCE_CLOSE 301 From a72be42af436f4ef4470a0ac41b2941596e1d8bc Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 16:29:12 -0400 Subject: [PATCH 39/49] dbwritetext: Fail if dbconvert does. --- src/dblib/dblib.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c index 0e45631889..6f2fcb0e4e 100644 --- a/src/dblib/dblib.c +++ b/src/dblib/dblib.c @@ -6642,6 +6642,7 @@ RETCODE dbwritetext(DBPROCESS * dbproc, char *objname, DBBINARY * textptr, DBTINYINT textptrlen, DBBINARY * timestamp, DBBOOL log, DBINT size, BYTE * text) { + DBINT len = 0; char textptr_string[35]; /* 16 * 2 + 2 (0x) + 1 */ char timestamp_string[19]; /* 8 * 2 + 2 (0x) + 1 */ TDS_INT result_type; @@ -6660,8 +6661,14 @@ dbwritetext(DBPROCESS * dbproc, char *objname, DBBINARY * textptr, DBTINYINT tex if (textptrlen > DBTXPLEN) return FAIL; - dbconvert(dbproc, SYBBINARY, (BYTE *) textptr, textptrlen, SYBCHAR, (BYTE *) textptr_string, -1); - dbconvert(dbproc, SYBBINARY, (BYTE *) timestamp, 8, SYBCHAR, (BYTE *) timestamp_string, -1); + len = dbconvert(dbproc, SYBBINARY, (BYTE *) textptr, textptrlen, + SYBCHAR, (BYTE *) textptr_string, -1); + if (len < 0) + return FAIL; + len = dbconvert(dbproc, SYBBINARY, (BYTE *) timestamp, 8, SYBCHAR, + (BYTE *) timestamp_string, -1); + if (len < 0) + return FAIL; dbproc->dbresults_state = _DB_RES_INIT; From 498af55c31733ba43b876d8438724a3cca273f50 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 16:30:47 -0400 Subject: [PATCH 40/49] SQLCancel: Lock DBC mutex around extracting tds. --- src/odbc/odbc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c index c9369df192..1ac9ccd4b2 100644 --- a/src/odbc/odbc.c +++ b/src/odbc/odbc.c @@ -1997,7 +1997,9 @@ SQLCancel(SQLHSTMT hstmt) tdsdump_log(TDS_DBG_FUNC, "SQLCancel(%p)\n", hstmt); + tds_mutex_lock(&stmt->dbc->mtx); tds = stmt->tds; + tds_mutex_unlock(&stmt->dbc->mtx); /* cancelling an inactive statement ?? */ if (!tds) { From 9c6517e7cd950501ba63d4fe64c074d4446548f0 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 16:39:57 -0400 Subject: [PATCH 41/49] tds/unittests/freeze.c: Suppress SIGPIPE (helpful on macOS). --- src/tds/unittests/freeze.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tds/unittests/freeze.c b/src/tds/unittests/freeze.c index c8e7c50efa..7d7d80a691 100644 --- a/src/tds/unittests/freeze.c +++ b/src/tds/unittests/freeze.c @@ -29,6 +29,7 @@ #endif /* HAVE_UNISTD_H */ #include +#include #include @@ -420,6 +421,7 @@ test(int mars, void (*real_test)(void)) /* provide connection to a fake remove server */ assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) >= 0); + tds_socket_set_nosigpipe(sockets[0], 1); was_shutdown = false; tds->state = TDS_IDLE; tds_set_s(tds, sockets[0]); From 6e4efae1ed3176fbe84d3394de6e5e50081cf4d4 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 16:41:58 -0400 Subject: [PATCH 42/49] odbc stats.c: Stick fully with the designated database. Continue to run against it when explicitly specifying a catalog (in ODBC parlance), rather than attempting to create(!) (if absent) and use freetds_test. --- src/odbc/unittests/stats.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/odbc/unittests/stats.c b/src/odbc/unittests/stats.c index 1d3d68c2ae..d8f97cc248 100644 --- a/src/odbc/unittests/stats.c +++ b/src/odbc/unittests/stats.c @@ -99,13 +99,9 @@ main(void) odbc_use_version3 = 0; odbc_connect(); - /* try to create test database if not existing */ - odbc_command("IF DB_ID('freetds_test') IS NULL " - "CREATE DATABASE freetds_test"); - TestProc(NULL, "DATETIME", STR(SQL_TIMESTAMP)); TestTable(NULL, "DATETIME", STR(SQL_TIMESTAMP)); - TestTable("freetds_test", "DATETIME", STR(SQL_TIMESTAMP)); + TestTable(odbc_database, "DATETIME", STR(SQL_TIMESTAMP)); odbc_disconnect(); @@ -115,7 +111,7 @@ main(void) TestProc(NULL, "DATETIME", STR(SQL_TYPE_TIMESTAMP)); TestTable(NULL, "DATETIME", STR(SQL_TYPE_TIMESTAMP)); - TestTable("freetds_test", "DATETIME", STR(SQL_TYPE_TIMESTAMP)); + TestTable(odbc_database, "DATETIME", STR(SQL_TYPE_TIMESTAMP)); odbc_disconnect(); From 3d000c509d261629783dd5d0316ba9ca54830ae1 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 16:53:02 -0400 Subject: [PATCH 43/49] Address "declared with greater visibility" warnings. Ensure that members of types that should be unhidden have unhidden forward declarations; likewise for their members, recursively. To that end, give CS_SERVERMSG_*'s underlying struct/union types explicit names (cs_servermsg_*). --- include/ctlib.h | 20 ++++++++++++++++---- include/freetds/tds.h | 17 +++++++++++++++++ include/freetds/utils/string.h | 4 ++-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/include/ctlib.h b/include/ctlib.h index 72c05a8ae7..10afc033f1 100644 --- a/include/ctlib.h +++ b/include/ctlib.h @@ -29,6 +29,18 @@ * Internal (not part of the exposed API) prototypes and such. */ +/* Forward declarations to fix "declared with greater visibility" warnings */ +struct _cs_dynamic; +struct _cs_param; +struct _csremote_proc; +struct cs_diag_msg; +struct cs_diag_msg_client; +struct cs_diag_msg_svr; +struct cs_servermsg_common1; +struct cs_servermsg_large; +struct cs_servermsg_small; +union cs_servermsg_internal; + #include #ifdef __cplusplus @@ -61,7 +73,7 @@ struct cs_diag_msg_client CS_CLIENTMSG clientmsg; }; -typedef struct { +typedef struct cs_servermsg_small { CS_MSGNUM msgnumber; CS_INT state; CS_INT severity; @@ -77,7 +89,7 @@ typedef struct { CS_INT sqlstatelen; } CS_SERVERMSG_SMALL; -typedef struct { +typedef struct cs_servermsg_large { CS_MSGNUM msgnumber; CS_INT state; CS_INT severity; @@ -93,7 +105,7 @@ typedef struct { CS_INT sqlstatelen; } CS_SERVERMSG_LARGE; -typedef struct { +typedef struct cs_servermsg_common1 { CS_MSGNUM msgnumber; CS_INT state; CS_INT severity; @@ -108,7 +120,7 @@ typedef struct { CS_INT sqlstatelen; } CS_SERVERMSG_COMMON2; -typedef union +typedef union cs_servermsg_internal { CS_SERVERMSG_SMALL small; CS_SERVERMSG_LARGE large; diff --git a/include/freetds/tds.h b/include/freetds/tds.h index 7df0714ea2..00f43748a3 100644 --- a/include/freetds/tds.h +++ b/include/freetds/tds.h @@ -54,6 +54,23 @@ typedef struct tds_connection TDSCONNECTION; typedef struct tds_socket TDSSOCKET; typedef struct tds_column TDSCOLUMN; typedef struct tds_bcpinfo TDSBCPINFO; +/* More, to address "declared with greater visibility" warnings. */ +struct tds5_colinfo; +struct tds_authentication; +struct tds_bcpcoldata; +struct tds_capabilities; +struct tds_capability_type; +struct tds_column_funcs; +struct tds_context; +struct tds_cursor; +struct tds_cursor_status; +struct tds_dynamic; +struct tds_env; +struct tds_locale; +struct tds_login; +struct tds_packet; +struct tds_poll_wakeup; +struct tds_result_info; #include #include diff --git a/include/freetds/utils/string.h b/include/freetds/utils/string.h index c69cd7a0be..8a1dbb65c6 100644 --- a/include/freetds/utils/string.h +++ b/include/freetds/utils/string.h @@ -22,8 +22,6 @@ #include -#include - /** \addtogroup dstring * @{ */ @@ -38,6 +36,8 @@ typedef struct tds_dstr { char dstr_s[1]; } *DSTR; +#include + /** Internal representation for an empty string */ extern const struct tds_dstr tds_str_empty; From 13da54efd985b620c3490fc8af362e8e007df5dc Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Mon, 13 May 2024 17:18:25 -0400 Subject: [PATCH 44/49] Regroup pointer comparisons to avoid subtraction. The compiler always insists on treating the difference between two pointers as potentially negative, yielding warnings when comparing it to an integer that has (or will soon have) a pointer-width unsigned type. Equivalent pointer-to-pointer comparisons yield no such warnings and are still clear. --- src/odbc/odbc.c | 4 ++-- src/odbc/odbc_util.c | 4 ++-- src/tds/unittests/freeze.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c index 1ac9ccd4b2..5efa1c24f9 100644 --- a/src/odbc/odbc.c +++ b/src/odbc/odbc.c @@ -3170,7 +3170,7 @@ odbc_unquote(char *buf, size_t buf_len, const char *start, const char *end) /* not quoted */ if (*start != '[' && *start != '\"') { --buf_len; - if (end - start < buf_len) + if (end < start + buf_len) buf_len = end - start; memcpy(buf, start, buf_len); buf[buf_len] = 0; @@ -7534,7 +7534,7 @@ odbc_stat_execute(TDS_STMT * stmt _WIDE, const char *begin, int nparams, ...) strcpy(p, begin); p += strlen(begin); tds_dstr_setlen(&stmt->query, p - proc); - assert(p - proc + 1 <= len); + assert(p + 1 <= proc + len); /* execute it */ retcode = _SQLExecute(stmt); diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c index 5153a459a1..ea620734c6 100644 --- a/src/odbc/odbc_util.c +++ b/src/odbc/odbc_util.c @@ -128,7 +128,7 @@ odbc_iso2utf(DSTR *res, const char *s, unsigned int len) *p++ = u; } } - assert(p+1-out <= o_len); + assert(p + 1 <= out + o_len); return tds_dstr_setlen(res, p - out); } @@ -211,7 +211,7 @@ odbc_wide2utf(DSTR *res, const SQLWCHAR *s, unsigned int len) } *p++ = 0x80 | (0x3f & u); } - assert(p+1-out <= o_len); + assert(p + 1 <= out + o_len); return tds_dstr_setlen(res, p - out); } diff --git a/src/tds/unittests/freeze.c b/src/tds/unittests/freeze.c index 7d7d80a691..56fd4bbbd3 100644 --- a/src/tds/unittests/freeze.c +++ b/src/tds/unittests/freeze.c @@ -131,7 +131,7 @@ strip_headers(buffer *buf) assert(end - p >= 8); /* to read SMP part */ len = TDS_GET_UA4LE(p+4); assert(len >= 16); - assert(end - p >= len); + assert(p + len <= end); p += 16; len -= 16; assert(end - p >= 4); /* to read TDS header part */ @@ -141,7 +141,7 @@ strip_headers(buffer *buf) len = TDS_GET_UA2BE(p+2); } assert(len > 8); - assert(end - p >= len); + assert(p + len <= end); final = p[1]; memmove(dst, p + 8, len - 8); dst += len - 8; From 1512645bcceba1f58127bf98242ebfc2af5fda7b Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Thu, 16 May 2024 17:02:57 -0400 Subject: [PATCH 45/49] Address most implicit conversion warnings. - Harmonize variable, parameter, etc. data types more fully. - Adjust system API usage accordingly: -- For some string constants, use sizeof() - 1 in lieu of strlen, taking care to ensure they come from array variables. -- Keep format specifiers for printf et al. in sync with argument types. -- dbprrow: Account for the fact that printf always uses int for dynamic widths by substituting memchr + fwrite. -- odbc/prepare_query.c (prepared_rpc): Substitute atoi for strtol (already used with no endptr) when populating TDSINT4. - Cast away some remaining discrepancies where safe, in some cases by taking advantage of TDS_PUT_* macros. - ctlib.h: Explicitly define _CS_CURS_TYPE_* in terms of TDS_CURSOR_STATE_* rather than duplicating their values. - tds_parse_conf_section: To legitimize a cast, tighten debug_flags' range check on systems where int is narrower than long. - odbc_util.c: #include for ptrdiff_t (now used in odbc_set_string_flag). --- include/ctlib.h | 6 +- include/dblib.h | 2 +- include/freetds/convert.h | 3 +- include/freetds/odbc.h | 26 ++++-- include/freetds/tds.h | 30 ++++--- include/freetds/utils/des.h | 3 +- src/ctlib/blk.c | 2 +- src/ctlib/cs.c | 17 ++-- src/ctlib/ct.c | 16 ++-- src/ctlib/ctutil.c | 14 ++-- src/ctlib/unittests/common.h | 2 +- src/ctlib/unittests/cs_convert.c | 4 +- src/ctlib/unittests/lang_ct_param.c | 10 ++- src/ctlib/unittests/rpc_ct_param.c | 4 +- src/ctlib/unittests/rpc_ct_setparam.c | 4 +- src/ctlib/unittests/variant.c | 2 +- src/dblib/bcp.c | 5 +- src/dblib/dblib.c | 51 +++++++----- src/dblib/dbpivot.c | 46 +++++++---- src/dblib/unittests/bcp.c | 3 +- src/dblib/unittests/dbsafestr.c | 4 +- src/dblib/unittests/setnull.c | 3 +- src/dblib/unittests/string_bind.c | 2 +- src/dblib/unittests/t0013.c | 7 +- src/dblib/unittests/t0014.c | 9 ++- src/dblib/unittests/timeout.c | 3 +- src/odbc/bcp.c | 17 ++-- src/odbc/connectparams.c | 4 +- src/odbc/convert_tds2sql.c | 28 ++++--- src/odbc/descriptor.c | 4 +- src/odbc/odbc.c | 109 ++++++++++++++------------ src/odbc/odbc_checks.c | 2 +- src/odbc/odbc_util.c | 51 ++++++------ src/odbc/prepare_query.c | 20 +++-- src/odbc/sql2tds.c | 22 +++--- src/odbc/unittests/bcp.c | 5 +- src/odbc/unittests/blob1.c | 10 +-- src/odbc/unittests/c2string.c | 6 +- src/odbc/unittests/cancel.c | 2 +- src/odbc/unittests/common.c | 16 ++-- src/odbc/unittests/common.h | 4 +- src/odbc/unittests/connect2.c | 6 +- src/odbc/unittests/convert_error.c | 2 +- src/odbc/unittests/cursor7.c | 2 +- src/odbc/unittests/describecol.c | 4 +- src/odbc/unittests/freeclose.c | 2 +- src/odbc/unittests/getdata.c | 2 +- src/odbc/unittests/long_error.c | 2 +- src/odbc/unittests/params.c | 6 +- src/odbc/unittests/putdata.c | 6 +- src/odbc/unittests/raiserror.c | 3 +- src/odbc/unittests/rebindpar.c | 2 +- src/odbc/unittests/rpc.c | 2 +- src/odbc/unittests/stats.c | 2 +- src/odbc/unittests/tables.c | 6 +- src/odbc/unittests/tvp.c | 7 +- src/odbc/unittests/utf8.c | 7 +- src/odbc/winsetup.c | 2 +- src/replacements/iconv.c | 6 +- src/tds/bulk.c | 6 +- src/tds/config.c | 5 +- src/tds/convert.c | 18 +++-- src/tds/data.c | 28 +++---- src/tds/gssapi.c | 2 +- src/tds/login.c | 12 +-- src/tds/mem.c | 5 +- src/tds/net.c | 46 ++++++----- src/tds/packet.c | 10 +-- src/tds/query.c | 49 +++++++----- src/tds/read.c | 6 +- src/tds/sspi.c | 6 +- src/tds/tds_checks.c | 2 +- src/tds/token.c | 3 +- src/tds/unittests/allcolumns.c | 2 +- src/tds/unittests/charconv.c | 4 +- src/tds/unittests/convert.c | 2 +- src/tds/unittests/convert_bounds.c | 3 +- src/tds/unittests/corrupt.c | 2 +- src/tds/unittests/freeze.c | 3 +- src/tds/unittests/iconv_fread.c | 4 +- src/tds/unittests/t0007.c | 8 +- src/tds/unittests/t0008.c | 4 +- src/tds/unittests/utf8_1.c | 2 +- src/tds/vstrbuild.c | 2 +- src/tds/write.c | 2 +- src/utils/des.c | 5 +- 86 files changed, 510 insertions(+), 378 deletions(-) diff --git a/include/ctlib.h b/include/ctlib.h index 10afc033f1..e466ca5533 100644 --- a/include/ctlib.h +++ b/include/ctlib.h @@ -335,9 +335,9 @@ struct _cs_locale /* internal defines for cursor processing */ -#define _CS_CURS_TYPE_UNACTIONED 0 -#define _CS_CURS_TYPE_REQUESTED 1 -#define _CS_CURS_TYPE_SENT 2 +#define _CS_CURS_TYPE_UNACTIONED TDS_CURSOR_STATE_UNACTIONED +#define _CS_CURS_TYPE_REQUESTED TDS_CURSOR_STATE_REQUESTED +#define _CS_CURS_TYPE_SENT TDS_CURSOR_STATE_SENT typedef struct { CS_CHAR name[132]; diff --git a/include/dblib.h b/include/dblib.h index 60c66bbd3b..ef860d9fa1 100644 --- a/include/dblib.h +++ b/include/dblib.h @@ -116,7 +116,7 @@ typedef struct dboption typedef struct { const BYTE *bindval; - size_t len; + unsigned int len; } NULLREP; struct tds_dblib_dbprocess diff --git a/include/freetds/convert.h b/include/freetds/convert.h index 28ac488c69..8b7f18950d 100644 --- a/include/freetds/convert.h +++ b/include/freetds/convert.h @@ -86,7 +86,8 @@ CONV_RESULT; unsigned char tds_willconvert(int srctype, int desttype); TDS_SERVER_TYPE tds_get_null_type(TDS_SERVER_TYPE srctype); -TDS_INT tds_char2hex(TDS_CHAR *dest, TDS_UINT destlen, const TDS_CHAR * src, TDS_UINT srclen); +ssize_t tds_char2hex(TDS_CHAR *dest, size_t destlen, + const TDS_CHAR * src, size_t srclen); TDS_INT tds_convert(const TDSCONTEXT *context, int srctype, const void *src, TDS_UINT srclen, int desttype, CONV_RESULT *cr); size_t tds_strftime(char *buf, size_t maxsize, const char *format, const TDSDATEREC * timeptr, int prec); diff --git a/include/freetds/odbc.h b/include/freetds/odbc.h index b17dd80cdf..f7e49786e1 100644 --- a/include/freetds/odbc.h +++ b/include/freetds/odbc.h @@ -152,7 +152,7 @@ struct _dheader { SQLSMALLINT sql_desc_alloc_type; /* TODO SQLLEN ?? see http://support.microsoft.com/default.aspx?scid=kb;en-us;298678 */ - SQLSMALLINT sql_desc_count; + SQLUSMALLINT sql_desc_count; SQLINTEGER sql_desc_bind_type; SQLULEN sql_desc_array_size; SQLUSMALLINT *sql_desc_array_status_ptr; @@ -632,7 +632,8 @@ typedef union { # define _WIDE # define ODBC_CHAR SQLCHAR #endif -int odbc_set_stmt_query(struct _hstmt *stmt, const ODBC_CHAR *sql, int sql_len _WIDE); +int odbc_set_stmt_query(struct _hstmt *stmt, const ODBC_CHAR *sql, + ssize_t sql_len _WIDE); void odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row); void odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row); @@ -642,23 +643,29 @@ int odbc_sql_to_c_type_default(int sql_type); TDS_SERVER_TYPE odbc_sql_to_server_type(TDSCONNECTION * conn, int sql_type, int sql_unsigned); TDS_SERVER_TYPE odbc_c_to_server_type(int c_type); -unsigned int odbc_get_string_size(int size, const ODBC_CHAR * str _WIDE); +size_t odbc_get_string_size(ssize_t size, const ODBC_CHAR * str _WIDE); void odbc_rdbms_version(TDSSOCKET * tds_socket, char *pversion_string); -SQLINTEGER odbc_get_param_len(const struct _drecord *drec_axd, const struct _drecord *drec_ixd, const TDS_DESC* axd, unsigned int n_row); +SQLLEN odbc_get_param_len(const struct _drecord *drec_axd, + const struct _drecord *drec_ixd, + const TDS_DESC* axd, SQLSETPOSIROW n_row); #ifdef ENABLE_ODBC_WIDE -DSTR* odbc_dstr_copy_flag(TDS_DBC *dbc, DSTR *s, int size, const ODBC_CHAR * str, int flag); +DSTR* odbc_dstr_copy_flag(TDS_DBC *dbc, DSTR *s, ssize_t size, + const ODBC_CHAR * str, int flag); #define odbc_dstr_copy(dbc, s, len, out) \ odbc_dstr_copy_flag(dbc, s, len, sizeof((out)->mb) ? (out) : (out), wide) #define odbc_dstr_copy_oct(dbc, s, len, out) \ odbc_dstr_copy_flag(dbc, s, len, out, wide|0x20) #else -DSTR* odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, int size, const ODBC_CHAR * str); +DSTR* odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, ssize_t size, + const ODBC_CHAR * str); #define odbc_dstr_copy_oct odbc_dstr_copy #endif -SQLRETURN odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void FAR * pcbBuffer, const char *s, int len, int flag); +SQLRETURN odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, + SQLINTEGER cbBuffer, void FAR * pcbBuffer, + const char *s, ssize_t len, int flag); #ifdef ENABLE_ODBC_WIDE #define odbc_set_string(dbc, buf, buf_len, out_len, s, s_len) \ odbc_set_string_flag(dbc, sizeof((buf)->mb) ? (buf) : (buf), buf_len, out_len, s, s_len, (wide) | (sizeof(*(out_len)) == sizeof(SQLSMALLINT)?0:0x10)) @@ -696,7 +703,10 @@ const char *odbc_skip_rpc_name(const char *s); /* * sql2tds.c */ -SQLRETURN odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ixd, const struct _drecord *drec_axd, TDSCOLUMN *curcol, bool compute_row, const TDS_DESC* axd, unsigned int n_row); +SQLRETURN odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ixd, + const struct _drecord *drec_axd, TDSCOLUMN *curcol, + bool compute_row, const TDS_DESC* axd, + SQLSETPOSIROW n_row); TDS_INT convert_datetime2server(int bindtype, const void *src, TDS_DATETIMEALL * dta); /* diff --git a/include/freetds/tds.h b/include/freetds/tds.h index 00f43748a3..df0b73c840 100644 --- a/include/freetds/tds.h +++ b/include/freetds/tds.h @@ -1386,7 +1386,7 @@ tds_release_cur_dyn(TDSSOCKET * tds) } void tds_dynamic_deallocated(TDSCONNECTION *conn, TDSDYNAMIC *dyn); void tds_set_cur_dyn(TDSSOCKET *tds, TDSDYNAMIC *dyn); -TDSSOCKET *tds_realloc_socket(TDSSOCKET * tds, size_t bufsize); +TDSSOCKET *tds_realloc_socket(TDSSOCKET * tds, unsigned int bufsize); char *tds_alloc_client_sqlstate(int msgno); char *tds_alloc_lookup_sqlstate(TDSSOCKET * tds, int msgno); TDSLOGIN *tds_alloc_login(int use_environment); @@ -1396,7 +1396,8 @@ TDSLOGIN *tds_init_login(TDSLOGIN * login, TDSLOCALE * locale); TDSLOCALE *tds_alloc_locale(void); void *tds_alloc_param_data(TDSCOLUMN * curparam); void tds_free_locale(TDSLOCALE * locale); -TDSCURSOR * tds_alloc_cursor(TDSSOCKET * tds, const char *name, TDS_INT namelen, const char *query, TDS_INT querylen); +TDSCURSOR * tds_alloc_cursor(TDSSOCKET * tds, const char *name, size_t namelen, + const char *query, size_t querylen); void tds_free_row(TDSRESULTINFO * res_info, unsigned char *row); TDSSOCKET *tds_alloc_socket(TDSCONTEXT * context, unsigned int bufsize); TDSSOCKET *tds_alloc_additional_socket(TDSCONNECTION *conn); @@ -1453,13 +1454,17 @@ TDSRET tds_submit_begin_tran(TDSSOCKET *tds); TDSRET tds_submit_rollback(TDSSOCKET *tds, bool cont); TDSRET tds_submit_commit(TDSSOCKET *tds, bool cont); TDSRET tds_disconnect(TDSSOCKET * tds); -size_t tds_quote_id(TDSSOCKET * tds, char *buffer, const char *id, int idlen); -size_t tds_quote_id_rpc(TDSSOCKET * tds, char *buffer, const char *id, int idlen); -size_t tds_quote_string(TDSSOCKET * tds, char *buffer, const char *str, int len); +size_t tds_quote_id(TDSSOCKET * tds, char *buffer, const char *id, + ssize_t idlen); +size_t tds_quote_id_rpc(TDSSOCKET * tds, char *buffer, const char *id, + ssize_t idlen); +size_t tds_quote_string(TDSSOCKET * tds, char *buffer, const char *str, + ssize_t len); const char *tds_skip_comment(const char *s); const char *tds_skip_quoted(const char *s); size_t tds_fix_column_size(TDSSOCKET * tds, TDSCOLUMN * curcol); -const char *tds_convert_string(TDSSOCKET * tds, TDSICONV * char_conv, const char *s, int len, size_t *out_len); +const char *tds_convert_string(TDSSOCKET * tds, TDSICONV * char_conv, + const char *s, ssize_t len, size_t *out_len); void tds_convert_string_free(const char *original, const char *converted); #if !ENABLE_EXTRA_CHECKS #define tds_convert_string_free(original, converted) \ @@ -1588,14 +1593,17 @@ int tds7_get_instance_ports(FILE *output, struct addrinfo *addr); int tds7_get_instance_port(struct addrinfo *addr, const char *instance); char *tds_prwsaerror(int erc); void tds_prwsaerror_free(char *s); -int tds_connection_read(TDSSOCKET * tds, unsigned char *buf, int buflen); -int tds_connection_write(TDSSOCKET *tds, const unsigned char *buf, int buflen, int final); +ssize_t tds_connection_read(TDSSOCKET * tds, unsigned char *buf, + size_t buflen); +ssize_t tds_connection_write(TDSSOCKET *tds, const unsigned char *buf, + size_t buflen, int final); #define TDSSELREAD POLLIN #define TDSSELWRITE POLLOUT int tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds); void tds_connection_close(TDSCONNECTION *conn); -int tds_goodread(TDSSOCKET * tds, unsigned char *buf, int buflen); -int tds_goodwrite(TDSSOCKET * tds, const unsigned char *buffer, size_t buflen); +ssize_t tds_goodread(TDSSOCKET * tds, unsigned char *buf, size_t buflen); +ssize_t tds_goodwrite(TDSSOCKET * tds, const unsigned char *buffer, + size_t buflen); void tds_socket_flush(TDS_SYS_SOCKET sock); int tds_socket_set_nonblocking(TDS_SYS_SOCKET sock); int tds_wakeup_init(TDSPOLLWAKEUP *wakeup); @@ -1631,7 +1639,7 @@ typedef struct tds_freeze { } TDSFREEZE; void tds_freeze(TDSSOCKET *tds, TDSFREEZE *freeze, unsigned size_len); -size_t tds_freeze_written(TDSFREEZE *freeze); +unsigned int tds_freeze_written(TDSFREEZE *freeze); TDSRET tds_freeze_abort(TDSFREEZE *freeze); TDSRET tds_freeze_close(TDSFREEZE *freeze); TDSRET tds_freeze_close_len(TDSFREEZE *freeze, int32_t size); diff --git a/include/freetds/utils/des.h b/include/freetds/utils/des.h index cf63ae6b82..a90315a9ff 100644 --- a/include/freetds/utils/des.h +++ b/include/freetds/utils/des.h @@ -27,7 +27,8 @@ void tds_des_encrypt(const DES_KEY * key, des_cblock block); #endif void tds_des_set_odd_parity(des_cblock key); -int tds_des_ecb_encrypt(const void *plaintext, int len, DES_KEY * akey, uint8_t *output); +int tds_des_ecb_encrypt(const void *plaintext, size_t len, DES_KEY * akey, + uint8_t *output); #include diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c index 2ec1e794ce..fffeb50ac0 100644 --- a/src/ctlib/blk.c +++ b/src/ctlib/blk.c @@ -215,7 +215,7 @@ blk_describe(CS_BLKDESC * blkdesc, CS_INT item, CS_DATAFMT * datafmt_arg) curcol = blkdesc->bcpinfo.bindinfo->columns[item - 1]; /* name is always null terminated */ strlcpy(datafmt->name, tds_dstr_cstr(&curcol->column_name), sizeof(datafmt->name)); - datafmt->namelen = strlen(datafmt->name); + datafmt->namelen = (CS_INT) strlen(datafmt->name); /* need to turn the SYBxxx into a CS_xxx_TYPE */ datatype = _ct_get_client_type(curcol, true); if (datatype == CS_ILLEGAL_TYPE) diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c index 52c54af86c..c3abfa6eab 100644 --- a/src/ctlib/cs.c +++ b/src/ctlib/cs.c @@ -1174,7 +1174,8 @@ cs_locale(CS_CONTEXT * ctx, CS_INT action, CS_LOCALE * locale, CS_INT type, CS_V switch (type) { case CS_SYB_CHARSET: - tlen = (locale->charset ? strlen(locale->charset) : 0) + 1; + tlen = (locale->charset ? (int) strlen(locale->charset) + : 0) + 1; if (buflen < tlen) { if (outlen) @@ -1189,7 +1190,8 @@ cs_locale(CS_CONTEXT * ctx, CS_INT action, CS_LOCALE * locale, CS_INT type, CS_V break; case CS_SYB_LANG: - tlen = (locale->language ? strlen(locale->language) : 0) + 1; + tlen = (locale->language ? + (int) strlen(locale->language) : 0) + 1; if (buflen < tlen) { if (outlen) @@ -1207,8 +1209,10 @@ cs_locale(CS_CONTEXT * ctx, CS_INT action, CS_LOCALE * locale, CS_INT type, CS_V { int clen; - tlen = (locale->language ? strlen(locale->language) : 0) + 1; - clen = (locale->charset ? strlen(locale->charset) : 0) + 1; + tlen = (locale->language ? + (int) strlen(locale->language) : 0) + 1; + clen = (locale->charset ? + (int) strlen(locale->charset) : 0) + 1; if (buflen < (tlen + clen)) { @@ -1222,7 +1226,7 @@ cs_locale(CS_CONTEXT * ctx, CS_INT action, CS_LOCALE * locale, CS_INT type, CS_V ((char *)buffer)[0] = '\0'; strcat((char *)buffer, "."); if (locale->charset) { - tlen = strlen((char *)buffer); + tlen = (int) strlen((char *)buffer); strcpy((char *)buffer + tlen, locale->charset); } code = CS_SUCCEED; @@ -1230,7 +1234,8 @@ cs_locale(CS_CONTEXT * ctx, CS_INT action, CS_LOCALE * locale, CS_INT type, CS_V } case CS_SYB_SORTORDER: - tlen = (locale->collate ? strlen(locale->collate) : 0) + 1; + tlen = (locale->collate ? (int) strlen(locale->collate) + : 0) + 1; if (buflen < tlen) { if (outlen) diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c index 71184f8f8c..658926209c 100644 --- a/src/ctlib/ct.c +++ b/src/ctlib/ct.c @@ -613,7 +613,7 @@ ct_con_props(CS_CONNECTION * con, CS_INT action, CS_INT property, CS_VOID * buff s = &tds_login->database; str_copy: if (out_len) - *out_len = tds_dstr_len(s); + *out_len = (CS_INT) tds_dstr_len(s); strlcpy((char *) buffer, tds_dstr_cstr(s), buflen); break; case CS_LOC_PROP: @@ -850,7 +850,7 @@ ct_cmd_alloc(CS_CONNECTION * con, CS_COMMAND ** pcmd) CS_RETCODE ct_command(CS_COMMAND * cmd, CS_INT type, const CS_VOID * buffer, CS_INT buflen, CS_INT option) { - int query_len, current_query_len; + ssize_t query_len, current_query_len; tdsdump_log(TDS_DBG_FUNC, "ct_command(%p, %d, %p, %d, %d)\n", cmd, type, buffer, buflen, option); @@ -2520,7 +2520,7 @@ ct_describe(CS_COMMAND * cmd, CS_INT item, CS_DATAFMT * datafmt_arg) curcol = resinfo->columns[item - 1]; /* name is always null terminated */ strlcpy(datafmt->name, tds_dstr_cstr(&curcol->column_name), sizeof(datafmt->name)); - datafmt->namelen = strlen(datafmt->name); + datafmt->namelen = (TDS_INT) strlen(datafmt->name); /* need to turn the SYBxxx into a CS_xxx_TYPE */ datafmt->datatype = _ct_get_client_type(curcol, true); if (datafmt->datatype == CS_ILLEGAL_TYPE) { @@ -2665,7 +2665,8 @@ ct_config(CS_CONTEXT * ctx, CS_INT action, CS_INT property, CS_VOID * buffer, CS ); ((char*)buffer)[buflen - 1]= 0; if (*outlen < 0) - *outlen = strlen((char*) buffer); + *outlen = (CS_INT) + strlen((char*) buffer); ret = CS_SUCCEED; } break; @@ -2685,7 +2686,8 @@ ct_config(CS_CONTEXT * ctx, CS_INT action, CS_INT property, CS_VOID * buffer, CS *outlen= snprintf((char*) buffer, buflen, "%s", settings->freetds_version); ((char*)buffer)[buflen - 1]= 0; if (*outlen < 0) - *outlen = strlen((char*) buffer); + *outlen = (CS_INT) + strlen((char*) buffer); ret = CS_SUCCEED; } break; @@ -2800,7 +2802,7 @@ ct_cmd_props(CS_COMMAND * cmd, CS_INT action, CS_INT property, CS_VOID * buffer, if ((CS_INT) len >= buflen) return CS_FAIL; strcpy((char*) buffer, cursor->cursor_name); - if (outlen) *outlen = len; + if (outlen) *outlen = (CS_INT) len; } if (property == CS_CUR_ROWCOUNT) { *(CS_INT *)buffer = cursor->cursor_rows; @@ -3369,7 +3371,7 @@ ct_capability(CS_CONNECTION * con, CS_INT action, CS_INT type, CS_INT capability CS_RETCODE ct_dynamic(CS_COMMAND * cmd, CS_INT type, CS_CHAR * id, CS_INT idlen, CS_CHAR * buffer, CS_INT buflen) { - int query_len; + size_t query_len; CS_CONNECTION *con; CS_DYNAMIC *dyn; diff --git a/src/ctlib/ctutil.c b/src/ctlib/ctutil.c index 3853d0f7f1..f0adde041b 100644 --- a/src/ctlib/ctutil.c +++ b/src/ctlib/ctutil.c @@ -125,7 +125,7 @@ _ct_handle_client_message(const TDSCONTEXT * ctx_tds, TDSSOCKET * tds, TDSMESSAG errmsg.msgnumber = msg->msgno; errmsg.severity = _ct_translate_severity(msg->severity); strlcpy(errmsg.msgstring, msg->message, sizeof(errmsg.msgstring)); - errmsg.msgstringlen = strlen(errmsg.msgstring); + errmsg.msgstringlen = (CS_INT) strlen(errmsg.msgstring); if (msg->osstr) { errmsg.osstringlen = (CS_INT) strlen(msg->osstr); strlcpy(errmsg.osstring, msg->osstr, CS_MAX_MSG); @@ -184,18 +184,18 @@ _ct_handle_server_message(const TDSCONTEXT * ctx_tds, TDSSOCKET * tds, TDSMESSAG memset(&errmsg, '\0', sizeof(errmsg)); errmsg.common.msgnumber = msg->msgno; strlcpy(errmsg.common.text, msg->message, sizeof(errmsg.common.text)); - errmsg.common.textlen = strlen(errmsg.common.text); + errmsg.common.textlen = (CS_INT) strlen(errmsg.common.text); errmsg.common.state = msg->state; errmsg.common.severity = msg->severity; #define MIDDLE_PART(part) do { \ common2 = (CS_SERVERMSG_COMMON2 *) &(errmsg.part.line); \ if (msg->server) { \ - errmsg.part.svrnlen = strlen(msg->server); \ + errmsg.part.svrnlen = (CS_INT) strlen(msg->server); \ strlcpy(errmsg.part.svrname, msg->server, sizeof(errmsg.part.svrname)); \ } \ if (msg->proc_name) { \ - errmsg.part.proclen = strlen(msg->proc_name); \ + errmsg.part.proclen = (CS_INT) strlen(msg->proc_name); \ strlcpy(errmsg.part.proc, msg->proc_name, sizeof(errmsg.part.proc)); \ } \ } while(0) @@ -209,7 +209,7 @@ _ct_handle_server_message(const TDSCONTEXT * ctx_tds, TDSSOCKET * tds, TDSMESSAG common2->sqlstate[0] = 0; if (msg->sql_state) strlcpy((char *) common2->sqlstate, msg->sql_state, sizeof(common2->sqlstate)); - common2->sqlstatelen = strlen((char *) common2->sqlstate); + common2->sqlstatelen = (CS_INT) strlen((char *) common2->sqlstate); common2->line = msg->line_number; /* if there is no connection, attempt to call the context handler */ @@ -273,7 +273,7 @@ _ct_datafmt_conv_in(CS_CONTEXT * ctx, const CS_DATAFMT * datafmt, CS_DATAFMT_LAR small = (const CS_DATAFMT_SMALL *) datafmt; strlcpy(fmtbuf->name, small->name, sizeof(fmtbuf->name)); - fmtbuf->namelen = strlen(fmtbuf->name); + fmtbuf->namelen = (CS_INT) strlen(fmtbuf->name); *((CS_DATAFMT_COMMON *) &fmtbuf->datatype) = *((CS_DATAFMT_COMMON *) &small->datatype); return fmtbuf; } @@ -317,7 +317,7 @@ _ct_datafmt_conv_back(CS_DATAFMT * datafmt, CS_DATAFMT_LARGE *fmtbuf) small = (CS_DATAFMT_SMALL *) datafmt; strlcpy(small->name, fmtbuf->name, sizeof(small->name)); - small->namelen = strlen(small->name); + small->namelen = (CS_INT) strlen(small->name); *((CS_DATAFMT_COMMON *) &small->datatype) = *((CS_DATAFMT_COMMON *) &fmtbuf->datatype); } diff --git a/src/ctlib/unittests/common.h b/src/ctlib/unittests/common.h index 9f6a72cb52..22dffe10e8 100644 --- a/src/ctlib/unittests/common.h +++ b/src/ctlib/unittests/common.h @@ -17,7 +17,7 @@ typedef struct char USER[512]; char PASSWORD[512]; char fverbose; - int maxlength; + long maxlength; } COMMON_PWD; extern COMMON_PWD common_pwd; diff --git a/src/ctlib/unittests/cs_convert.c b/src/ctlib/unittests/cs_convert.c index cc32c949b1..5c24925f1a 100644 --- a/src/ctlib/unittests/cs_convert.c +++ b/src/ctlib/unittests/cs_convert.c @@ -20,7 +20,7 @@ static CS_INT dest_format = CS_FMT_UNUSED; static int DoTest( /* source information */ - CS_INT fromtype, void *fromdata, CS_INT fromlen, + CS_INT fromtype, void *fromdata, size_t fromlen, /* to information */ CS_INT totype, CS_INT tomaxlen, /* expected result */ @@ -47,7 +47,7 @@ DoTest( memset(&srcfmt, 0, sizeof(srcfmt)); srcfmt.datatype = fromtype; - srcfmt.maxlength = fromlen; + srcfmt.maxlength = (CS_INT) fromlen; /* * FIXME this fix some thing but if error cs_convert should return diff --git a/src/ctlib/unittests/lang_ct_param.c b/src/ctlib/unittests/lang_ct_param.c index e16596e71f..6fc7356c81 100644 --- a/src/ctlib/unittests/lang_ct_param.c +++ b/src/ctlib/unittests/lang_ct_param.c @@ -110,7 +110,7 @@ insert_test(CS_CONNECTION *conn, CS_COMMAND *cmd, int useNames) memset(&srcfmt, 0, sizeof(CS_DATAFMT)); srcfmt.datatype = CS_CHAR_TYPE; - srcfmt.maxlength = strlen(moneystring); + srcfmt.maxlength = (CS_INT) strlen(moneystring); srcfmt.precision = 5; srcfmt.scale = 2; srcfmt.locale = NULL; @@ -144,7 +144,7 @@ insert_test(CS_CONNECTION *conn, CS_COMMAND *cmd, int useNames) /* * create the command */ - if ((ret = ct_command(cmd, CS_LANG_CMD, query, strlen(query), + if ((ret = ct_command(cmd, CS_LANG_CMD, query, (CS_INT) strlen(query), CS_UNUSED)) != CS_SUCCEED) { fprintf(stderr, "ct_command(CS_LANG_CMD) failed\n"); @@ -169,7 +169,8 @@ insert_test(CS_CONNECTION *conn, CS_COMMAND *cmd, int useNames) * The character string variable is filled in by the RPC so pass NULL * for the data 0 for data length, and -1 for the indicator arguments. */ - ret = ct_param(cmd, &datafmt, dummy_name, strlen(dummy_name), 0); + ret = ct_param(cmd, &datafmt, dummy_name, (CS_INT) strlen(dummy_name), + 0); if (CS_SUCCEED != ret) { fprintf(stderr, "ct_param(char) failed\n"); return 1; @@ -184,7 +185,8 @@ insert_test(CS_CONNECTION *conn, CS_COMMAND *cmd, int useNames) datafmt.datatype = CS_CHAR_TYPE; datafmt.status = CS_INPUTVALUE; - ret = ct_param(cmd, &datafmt, dummy_name2, strlen(dummy_name2), 0); + ret = ct_param(cmd, &datafmt, dummy_name2, + (CS_INT) strlen(dummy_name2), 0); if (CS_SUCCEED != ret) { fprintf(stderr, "ct_param(char) failed\n"); return 1; diff --git a/src/ctlib/unittests/rpc_ct_param.c b/src/ctlib/unittests/rpc_ct_param.c index c27e12bbf1..786ee0a0c0 100644 --- a/src/ctlib/unittests/rpc_ct_param.c +++ b/src/ctlib/unittests/rpc_ct_param.c @@ -114,7 +114,7 @@ main(void) memset(&srcfmt, 0, sizeof(CS_DATAFMT)); srcfmt.datatype = CS_CHAR_TYPE; - srcfmt.maxlength = strlen(moneystring); + srcfmt.maxlength = (CS_INT) strlen(moneystring); srcfmt.precision = 5; srcfmt.scale = 2; srcfmt.locale = NULL; @@ -554,7 +554,7 @@ CS_INT disp_len; disp_len = ex_display_dlen(&columns[i]); printf("%s", columns[i].name); fflush(stdout); - l = disp_len - strlen(columns[i].name); + l = disp_len - (CS_INT) strlen(columns[i].name); for (j = 0; j < l; j++) { fputc(' ', stdout); fflush(stdout); diff --git a/src/ctlib/unittests/rpc_ct_setparam.c b/src/ctlib/unittests/rpc_ct_setparam.c index e2b05fc796..23d7415dd5 100644 --- a/src/ctlib/unittests/rpc_ct_setparam.c +++ b/src/ctlib/unittests/rpc_ct_setparam.c @@ -105,7 +105,7 @@ main(void) memset(&srcfmt, 0, sizeof(CS_DATAFMT)); srcfmt.datatype = CS_CHAR_TYPE; - srcfmt.maxlength = strlen(moneystring); + srcfmt.maxlength = (CS_INT) strlen(moneystring); srcfmt.precision = 5; srcfmt.scale = 2; srcfmt.locale = NULL; @@ -589,7 +589,7 @@ CS_INT disp_len; disp_len = ex_display_dlen(&columns[i]); printf("%s", columns[i].name); fflush(stdout); - l = disp_len - strlen(columns[i].name); + l = disp_len - (CS_INT) strlen(columns[i].name); for (j = 0; j < l; j++) { fputc(' ', stdout); fflush(stdout); diff --git a/src/ctlib/unittests/variant.c b/src/ctlib/unittests/variant.c index a97dcaeca5..009eb6e11d 100644 --- a/src/ctlib/unittests/variant.c +++ b/src/ctlib/unittests/variant.c @@ -33,7 +33,7 @@ main(void) CS_CHAR select[1024]; CS_CHAR col1[128]; - const char *expected[10]; + char *expected[10]; unsigned num_expected = 0; unsigned rows = 0; diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c index 3509341451..d4a18f2893 100644 --- a/src/dblib/bcp.c +++ b/src/dblib/bcp.c @@ -1526,7 +1526,10 @@ _bcp_exec_in(DBPROCESS * dbproc, DBINT * rows_copied) fseeko(hostfile, row_start, SEEK_SET); while (error_row_size > 0) { - size_t chunk = error_row_size > chunk_size ? chunk_size : (size_t) error_row_size; + size_t chunk = ((size_t) error_row_size + > chunk_size) + ? chunk_size + : (size_t) error_row_size; if (!row_in_error) { if ((row_in_error = tds_new(char, chunk)) == NULL) { diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c index 6f2fcb0e4e..90fd53115d 100644 --- a/src/dblib/dblib.c +++ b/src/dblib/dblib.c @@ -841,7 +841,7 @@ dbsetllong(LOGINREC * login, long value, int which) switch (which) { case DBSETPACKET: if (0 <= value && value <= 999999) { - tds_set_packet(login->tds_login, value); + tds_set_packet(login->tds_login, (int) value); return SUCCEED; } dbperror(0, SYBEBADPK, 0, (int) value, (int) login->tds_login->block_size); @@ -1061,7 +1061,7 @@ dbstring_length(DBSTRING * dbstr) } static int -dbstring_getchar(DBSTRING * dbstr, int i) +dbstring_getchar(DBSTRING * dbstr, ssize_t i) { /* tdsdump_log(TDS_DBG_FUNC, "dbstring_getchar(%p, %d)\n", dbstr, i); */ @@ -3455,7 +3455,7 @@ dbspr1rowlen(DBPROCESS * dbproc) for (col = 0; col < tds->res_info->num_cols; col++) { TDSCOLUMN *colinfo = tds->res_info->columns[col]; int collen = _get_printable_size(colinfo); - int namlen = tds_dstr_len(&colinfo->column_name); + int namlen = (int) tds_dstr_len(&colinfo->column_name); len += collen > namlen ? collen : namlen; @@ -3496,7 +3496,7 @@ dbspr1row(DBPROCESS * dbproc, char *buffer, DBINT buf_len) tds = dbproc->tds_socket; for (col = 0; col < tds->res_info->num_cols; col++) { - int padlen, collen, namlen; + size_t padlen, collen, namlen; TDSCOLUMN *colinfo = tds->res_info->columns[col]; if (colinfo->column_cur_size < 0) { len = 4; @@ -3567,17 +3567,18 @@ dbprrow(DBPROCESS * dbproc) TDSCOLUMN *colinfo; TDSRESULTINFO *resinfo; TDSSOCKET *tds; - int i, col, collen, namlen, len; + int i, col; + size_t collen, namlen, len; char dest[8192]; int desttype, srctype; TDSDATEREC when; STATUS status; - int padlen; + ssize_t padlen; int c; int selcol; int linechar; int op; - const char *opname; + const char *opname, *p; /* these are for compute rows */ DBINT computeid, num_cols, colid; @@ -3623,7 +3624,9 @@ dbprrow(DBPROCESS * dbproc) } } - printf("%.*s", len, dest); + p = memchr(dest, '\0', len); + fwrite(dest, 1, p == NULL ? len : (p - dest), + stdout); collen = _get_printable_size(colinfo); namlen = tds_dstr_len(&colinfo->column_name); padlen = (collen > namlen ? collen : namlen) - len; @@ -3653,7 +3656,7 @@ dbprrow(DBPROCESS * dbproc) computeid = status; for (i = 0;; ++i) { - if (i >= tds->num_comp_info) { + if ((TDS_UINT) i >= tds->num_comp_info) { free(col_printlens); return FAIL; } @@ -3690,7 +3693,10 @@ dbprrow(DBPROCESS * dbproc) op = dbaltop(dbproc, computeid, col); opname = dbprtype(op); printf("%s", opname); - for (i = 0; i < ((long) col_printlens[selcol - 1] - (long) strlen(opname)); i++) { + for (i = 0; + i < (col_printlens[selcol - 1] + - (int) strlen(opname)); + i++) { if ((c = dbstring_getchar(dbproc->dbopts[DBPRPAD].param, 0)) >= 0) putchar(c); } @@ -3768,7 +3774,9 @@ dbprrow(DBPROCESS * dbproc) putchar(c); } } - printf("%.*s", len, dest); + p = memchr(dest, '\0', len); + fwrite(dest, 1, p == NULL ? len : (p - dest), + stdout); collen = _get_printable_size(colinfo); namlen = tds_dstr_len(&colinfo->column_name); padlen = (collen > namlen ? collen : namlen) - len; @@ -3887,7 +3895,7 @@ dbsprline(DBPROCESS * dbproc, char *buffer, DBINT buf_len, DBCHAR line_char) TDSCOLUMN *colinfo; TDSRESULTINFO *resinfo; TDSSOCKET *tds; - int i, col, len, collen, namlen; + size_t i, col, len, collen, namlen; int c; tdsdump_log(TDS_DBG_FUNC, "dbsprline(%p, %s, %d, '%c')\n", dbproc, buffer, buf_len, line_char); @@ -3945,7 +3953,8 @@ dbsprhead(DBPROCESS * dbproc, char *buffer, DBINT buf_len) TDSCOLUMN *colinfo; TDSRESULTINFO *resinfo; TDSSOCKET *tds; - int i, col, collen, namlen; + int i, collen, namlen; + TDS_USMALLINT col; int padlen; int c; @@ -3959,7 +3968,7 @@ dbsprhead(DBPROCESS * dbproc, char *buffer, DBINT buf_len) for (col = 0; col < resinfo->num_cols; col++) { colinfo = resinfo->columns[col]; collen = _get_printable_size(colinfo); - namlen = tds_dstr_len(&colinfo->column_name); + namlen = (int) tds_dstr_len(&colinfo->column_name); padlen = (collen > namlen ? collen : namlen) - namlen; if (buf_len < namlen) { return FAIL; @@ -4009,8 +4018,8 @@ dbprhead(DBPROCESS * dbproc) TDSCOLUMN *colinfo; TDSRESULTINFO *resinfo; TDSSOCKET *tds; - int i, col, len, collen, namlen; - int padlen; + size_t i, col, len, collen, namlen; + size_t padlen; int c; tdsdump_log(TDS_DBG_FUNC, "dbprhead(%p)\n", dbproc); @@ -4990,7 +4999,7 @@ dbnumalts(DBPROCESS * dbproc, int computeid) TDSSOCKET *tds; TDSCOMPUTEINFO *info; TDS_SMALLINT compute_id; - int i; + TDS_UINT i; tdsdump_log(TDS_DBG_FUNC, "dbnumalts(%p, %d)\n", dbproc, computeid); CHECK_PARAMETER(dbproc, SYBENULL, -1); @@ -5048,7 +5057,7 @@ dbbylist(DBPROCESS * dbproc, int computeid, int *size) { TDSSOCKET *tds; TDSCOMPUTEINFO *info; - int i; + TDS_UINT i; const TDS_SMALLINT byte_flag = -0x8000; tdsdump_log(TDS_DBG_FUNC, "dbbylist(%p, %d, %p)\n", dbproc, computeid, size); @@ -8190,7 +8199,8 @@ dbperror(DBPROCESS *dbproc, DBINT msgno, long errnum, ...) const DBLIB_ERROR_MESSAGE *msg = &default_message; int i, rc = INT_CANCEL; - const char *os_msgtext = strerror(errnum), *rc_name = "logic error"; + const char *os_msgtext = strerror((int) errnum), + *rc_name = "logic error"; char rc_buf[16]; tdsdump_log(TDS_DBG_FUNC, "dbperror(%p, %d, %ld)\n", dbproc, msgno, errnum); /* dbproc can be NULL */ @@ -8265,7 +8275,8 @@ dbperror(DBPROCESS *dbproc, DBINT msgno, long errnum, ...) msgno, msg->msgtext); /* call the error handler */ - rc = (*_dblib_err_handler)(dbproc, msg->severity, msgno, errnum, (char*) msg->msgtext, (char*) os_msgtext); + rc = (*_dblib_err_handler)(dbproc, msg->severity, msgno, (int) errnum, + (char*) msg->msgtext, (char*) os_msgtext); switch (rc) { case INT_EXIT: rc_name = "INT_EXIT"; diff --git a/src/dblib/dbpivot.c b/src/dblib/dbpivot.c index 5b59dea59f..52a0ad7aef 100644 --- a/src/dblib/dbpivot.c +++ b/src/dblib/dbpivot.c @@ -91,7 +91,7 @@ struct col_t static TDS_SERVER_TYPE infer_col_type(int sybtype); static struct col_t * -col_init(struct col_t *pcol, int sybtype, int collen) +col_init(struct col_t *pcol, int sybtype, size_t collen) { assert(pcol); @@ -653,7 +653,7 @@ agg_equal(const AGG_T *p1, const AGG_T *p2) #define tds_alloc_column() ((TDSCOLUMN*) calloc(1, sizeof(TDSCOLUMN))) static TDSRESULTINFO * -alloc_results(size_t num_cols) +alloc_results(TDS_USMALLINT num_cols) { TDSRESULTINFO *res_info; TDSCOLUMN **ppcol; @@ -716,7 +716,8 @@ struct metadata_t { KEY_T *pacross; char *name; struct col_t col; }; static bool -reinit_results(TDSSOCKET * tds, size_t num_cols, const struct metadata_t meta[]) +reinit_results(TDSSOCKET * tds, TDS_USMALLINT num_cols, + const struct metadata_t meta[]) { TDSRESULTINFO *info; int i; @@ -778,7 +779,8 @@ typedef struct pivot_t AGG_T *output; KEY_T *across; - size_t nout, nacross; + size_t nout; + TDS_USMALLINT nacross; } PIVOT_T; static bool @@ -851,8 +853,10 @@ dbnextrow_pivoted(DBPROCESS *dbproc, PIVOT_T *pp) } else { AGG_T *pcan; key_cpy(&candidate.col_key, (KEY_T *) pcol->bcp_terminator); - if ((pcan = tds_find(&candidate, pout, pp->output + pp->nout - pout, - sizeof(*pp->output), (compare_func) agg_next)) != NULL) { + if ((pcan = (AGG_T *) tds_find + (&candidate, pout, pp->output + pp->nout - pout, + sizeof(*pp->output), (compare_func) agg_next)) + != NULL) { /* flag this output as used */ pout->row_key.keys = NULL; pval = &pcan->value; @@ -867,11 +871,11 @@ dbnextrow_pivoted(DBPROCESS *dbproc, PIVOT_T *pp) assert(pval); pcol->column_size = pval->len; - pcol->column_data = col_buffer(pval); + pcol->column_data = (unsigned char *) col_buffer(pval); copy_data_to_host_var( dbproc, pval->type, - col_buffer(pval), + (BYTE *) col_buffer(pval), pval->len, (BYTE *) pcol->column_varaddr, pcol->column_bindlen, @@ -909,7 +913,8 @@ dbpivot(DBPROCESS *dbproc, int nkeys, int *keys, int ncols, int *cols, DBPIVOT_F PIVOT_T P, *pp; AGG_T input, *pout = NULL; struct metadata_t *metadata, *pmeta; - size_t i, nmeta = 0; + int i; + TDS_USMALLINT nmeta = 0; tdsdump_log(TDS_DBG_FUNC, "dbpivot(%p, %d,%p, %d,%p, %p, %d)\n", dbproc, nkeys, keys, ncols, cols, func, val); if (logalot) { @@ -934,8 +939,10 @@ dbpivot(DBPROCESS *dbproc, int nkeys, int *keys, int ncols, int *cols, DBPIVOT_F memset(&input, 0, sizeof(input)); P.dbproc = dbproc; - if ((pp = tds_find(&P, pivots, npivots, sizeof(*pivots), (compare_func) pivot_key_equal)) == NULL ) { - pp = TDS_RESIZE(pivots, 1 + npivots); + if ((pp = (PIVOT_T *) tds_find(&P, pivots, npivots, sizeof(*pivots), + (compare_func) pivot_key_equal)) + == NULL) { + pp = (PIVOT_T *) TDS_RESIZE(pivots, 1 + npivots); if (!pp) return FAIL; pp += npivots++; @@ -955,7 +962,9 @@ dbpivot(DBPROCESS *dbproc, int nkeys, int *keys, int ncols, int *cols, DBPIVOT_F if (!col_init(input.row_key.keys+i, type, len)) return FAIL; - if (FAIL == dbbind(dbproc, keys[i], bind_type(type), input.row_key.keys[i].len, col_buffer(input.row_key.keys+i))) + if (FAIL == dbbind(dbproc, keys[i], bind_type(type), + (DBINT) input.row_key.keys[i].len, + (BYTE *) col_buffer(input.row_key.keys+i))) return FAIL; if (FAIL == dbnullbind(dbproc, keys[i], &input.row_key.keys[i].null_indicator)) return FAIL; @@ -971,7 +980,9 @@ dbpivot(DBPROCESS *dbproc, int nkeys, int *keys, int ncols, int *cols, DBPIVOT_F if (!col_init(input.col_key.keys+i, type, len)) return FAIL; - if (FAIL == dbbind(dbproc, cols[i], bind_type(type), input.col_key.keys[i].len, col_buffer(input.col_key.keys+i))) + if (FAIL == dbbind(dbproc, cols[i], bind_type(type), + (DBINT) input.col_key.keys[i].len, + (BYTE *) col_buffer(input.col_key.keys+i))) return FAIL; if (FAIL == dbnullbind(dbproc, cols[i], &input.col_key.keys[i].null_indicator)) return FAIL; @@ -984,7 +995,9 @@ dbpivot(DBPROCESS *dbproc, int nkeys, int *keys, int ncols, int *cols, DBPIVOT_F if (!col_init(&input.value, type, len)) return FAIL; - if (FAIL == dbbind(dbproc, val, bind_type(type), input.value.len, col_buffer(&input.value))) + if (FAIL == dbbind(dbproc, val, bind_type(type), + input.value.len, + (BYTE *) col_buffer(&input.value))) return FAIL; if (FAIL == dbnullbind(dbproc, val, &input.value.null_indicator)) return FAIL; @@ -992,7 +1005,10 @@ dbpivot(DBPROCESS *dbproc, int nkeys, int *keys, int ncols, int *cols, DBPIVOT_F while ((pp->status = dbnextrow(dbproc)) == REG_ROW) { /* add to unique list of crosstab columns */ - if (tds_find(&input.col_key, pp->across, pp->nacross, sizeof(*pp->across), (compare_func) key_equal) == NULL) { + if ((AGG_T *) tds_find(&input.col_key, pp->across, pp->nacross, + sizeof(*pp->across), + (compare_func) key_equal) + == NULL) { if (!TDS_RESIZE(pp->across, 1 + pp->nacross)) return FAIL; key_cpy(pp->across + pp->nacross, &input.col_key); diff --git a/src/dblib/unittests/bcp.c b/src/dblib/unittests/bcp.c index 19c397542d..fda3af8641 100644 --- a/src/dblib/unittests/bcp.c +++ b/src/dblib/unittests/bcp.c @@ -72,7 +72,8 @@ init(DBPROCESS * dbproc, const char *name) } #define VARCHAR_BIND(x) \ - bcp_bind( dbproc, (unsigned char *) &x, prefixlen, strlen(x), NULL, termlen, SYBVARCHAR, col++ ) + bcp_bind( dbproc, (unsigned char *) &x, prefixlen, (DBINT) strlen(x), \ + NULL, termlen, SYBVARCHAR, col++ ) #define INT_BIND(x) \ bcp_bind( dbproc, (unsigned char *) &x, prefixlen, -1, NULL, termlen, SYBINT4, col++ ) diff --git a/src/dblib/unittests/dbsafestr.c b/src/dblib/unittests/dbsafestr.c index 11fc7a1040..7dbf38c873 100644 --- a/src/dblib/unittests/dbsafestr.c +++ b/src/dblib/unittests/dbsafestr.c @@ -12,7 +12,7 @@ static int failed = 0; /* unsafestr must contain one quote of each type */ -static const char *unsafestr = "This is a string with ' and \" in it."; +static const char unsafestr[] = "This is a string with ' and \" in it."; /* safestr must be at least strlen(unsafestr) + 3 */ static char safestr[100]; @@ -30,7 +30,7 @@ main(int argc TDS_UNUSED, char **argv) dbinit(); - len = strlen(unsafestr); + len = sizeof(unsafestr) - 1; ret = dbsafestr(NULL, unsafestr, -1, safestr, len, DBSINGLE); if (ret != FAIL) failed++; diff --git a/src/dblib/unittests/setnull.c b/src/dblib/unittests/setnull.c index 5faa144542..07e7a16188 100644 --- a/src/dblib/unittests/setnull.c +++ b/src/dblib/unittests/setnull.c @@ -18,7 +18,8 @@ char_test(const char *null, int bindlen, const char *expected) if (null) { fprintf(stderr, "\tdbsetnull(CHARBIND, %u, '%s').\n", (unsigned int) strlen(null), null); - ret = dbsetnull(dbproc, CHARBIND, strlen(null), (BYTE *) null); + ret = dbsetnull(dbproc, CHARBIND, (int) strlen(null), + (BYTE *) null); if (ret != SUCCEED) { fprintf(stderr, "dbsetnull returned error %d\n", (int) ret); failed = 1; diff --git a/src/dblib/unittests/string_bind.c b/src/dblib/unittests/string_bind.c index f2ba6378e8..75a72d42cc 100644 --- a/src/dblib/unittests/string_bind.c +++ b/src/dblib/unittests/string_bind.c @@ -16,7 +16,7 @@ static void test_row(int vartype, const char *vartype_name, const char *expected, int line) { char str[11]; - int i; + size_t i; printf("%d: row type %s bind len %d\n", line, vartype_name, bind_len); diff --git a/src/dblib/unittests/t0013.c b/src/dblib/unittests/t0013.c index 228e68fc9f..c823a6ddd6 100644 --- a/src/dblib/unittests/t0013.c +++ b/src/dblib/unittests/t0013.c @@ -39,12 +39,13 @@ test(int argc, char **argv, int over4k) int i; DBINT testint; FILE *fp; - long result, isiz; + ssize_t result; + long isiz; char *blob, *rblob; DBBINARY *textPtr = NULL, *timeStamp = NULL; char objname[256]; char rbuf[BLOB_BLOCK_SIZE]; - long numread; + size_t numread; int data_ok; int numtowrite, numwritten; set_malloc_options(); @@ -265,7 +266,7 @@ test(int argc, char **argv, int over4k) data_ok = 0; } - printf("Read blob data row %d --> %s %ld byte comparison\n", + printf("Read blob data row %d --> %s %zu byte comparison\n", (int) testint, data_ok ? "PASSED" : "failed", numread); free(rblob); diff --git a/src/dblib/unittests/t0014.c b/src/dblib/unittests/t0014.c index 11a5c724cc..43571b6c9d 100644 --- a/src/dblib/unittests/t0014.c +++ b/src/dblib/unittests/t0014.c @@ -21,13 +21,14 @@ test(int argc, char **argv, int over4k) int i; DBINT testint; FILE *fp; - long result, isiz; + ssize_t result; + long isiz; char *blob, *rblob; unsigned char *textPtr, *timeStamp; char objname[256]; char sqlCmd[256]; char rbuf[BLOB_BLOCK_SIZE]; - long numread; + size_t numread; int numtowrite, numwritten; set_malloc_options(); @@ -226,11 +227,11 @@ test(int argc, char **argv, int over4k) return 3; } - result = fwrite((void *) rblob, numread, 1, fp); + result = (long) fwrite((void *) rblob, numread, 1, fp); fclose(fp); } - printf("Read blob data row %d --> %s %ld byte comparison\n", + printf("Read blob data row %d --> %s %zu byte comparison\n", (int) testint, (memcmp(blob, rblob, numread)) ? "failed" : "PASSED", numread); free(rblob); } diff --git a/src/dblib/unittests/timeout.c b/src/dblib/unittests/timeout.c index efbb140e23..d5e97e89b8 100644 --- a/src/dblib/unittests/timeout.c +++ b/src/dblib/unittests/timeout.c @@ -208,7 +208,8 @@ test(int per_process) start_time = time(NULL); /* keep track of when we started for reporting purposes */ ntimeouts = 0; - dbsetinterrupt(dbproc, (void*)chkintr, (void*)hndlintr); + dbsetinterrupt(dbproc, (DB_DBCHKINTR_FUNC)chkintr, + (DB_DBHNDLINTR_FUNC)hndlintr); if (FAIL == dbsqlsend(dbproc)) { fprintf(stderr, "Failed: dbsend\n"); diff --git a/src/odbc/bcp.c b/src/odbc/bcp.c index 9d71fb457f..d57d6e600a 100644 --- a/src/odbc/bcp.c +++ b/src/odbc/bcp.c @@ -422,14 +422,14 @@ _bcp_iconv_helper(const TDS_DBC *dbc, const TDSCOLUMN *bindcol, const TDS_CHAR * return destlen; } -static SQLLEN +static TDS_INT _tdsodbc_dbconvert(TDS_DBC *dbc, int srctype, const TDS_CHAR * src, SQLLEN src_len, int desttype, unsigned char * dest, TDSCOLUMN *bindcol) { CONV_RESULT dres; - SQLLEN ret; - SQLLEN len; - SQLLEN destlen = bindcol->column_size; + TDS_INT ret; + TDS_INT len; + TDS_INT destlen = bindcol->column_size; TDS_DATETIMEALL dta; TDS_NUMERIC num; SQL_NUMERIC_STRUCT * sql_num; @@ -473,10 +473,12 @@ _tdsodbc_dbconvert(TDS_DBC *dbc, int srctype, const TDS_CHAR * src, SQLLEN src_l /* oft times we are asked to convert a data type to itself */ if ((srctype == desttype || is_similar_type(srctype, desttype)) && !always_convert) { if (is_char_type(desttype)) { - ret = _bcp_iconv_helper(dbc, bindcol, src, src_len, (char *)dest, destlen); + ret = (TDS_INT) _bcp_iconv_helper + (dbc, bindcol, src, src_len, + (char *)dest, destlen); } else { - ret = destlen < src_len ? destlen : src_len; + ret = destlen < src_len ? destlen : (TDS_INT) src_len; memcpy(dest, src, ret); } return ret; @@ -529,7 +531,8 @@ _tdsodbc_dbconvert(TDS_DBC *dbc, int srctype, const TDS_CHAR * src, SQLLEN src_l case SYBCHAR: case SYBVARCHAR: case SYBTEXT: - ret = _bcp_iconv_helper(dbc, bindcol, dres.c, len, (char *)dest, destlen); + ret = (TDS_INT) _bcp_iconv_helper(dbc, bindcol, dres.c, len, + (char *) dest, destlen); free(dres.c); break; default: diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c index 5999af3e17..3f763ad3bf 100644 --- a/src/odbc/connectparams.c +++ b/src/odbc/connectparams.c @@ -582,7 +582,7 @@ tdoParseProfile(const char *option, const char *value, void *param) if (strcasecmp(p->entry, option) == 0) { strlcpy(p->buffer, value, p->buffer_len); - p->ret_val = strlen(p->buffer); + p->ret_val = (int) strlen(p->buffer); p->found = 1; } return true; @@ -638,7 +638,7 @@ SQLGetPrivateProfileString(LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault if (pszDefault && !param.found) { strlcpy(pRetBuffer, pszDefault, nRetBuffer); - param.ret_val = strlen(pRetBuffer); + param.ret_val = (int) strlen(pRetBuffer); } fclose(hFile); diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c index efaa82e016..842872aefa 100644 --- a/src/odbc/convert_tds2sql.c +++ b/src/odbc/convert_tds2sql.c @@ -48,7 +48,7 @@ static void eat_iconv_left(TDSCOLUMN * curcol, char **pbuf, size_t *plen) { - unsigned cp = ODBC_MIN(*plen, curcol->column_iconv_left); + unsigned cp = (unsigned) ODBC_MIN(*plen, curcol->column_iconv_left); memcpy(*pbuf, curcol->column_iconv_buf, cp); if (cp < curcol->column_iconv_left) memmove(curcol->column_iconv_buf, curcol->column_iconv_buf + cp, curcol->column_iconv_left - cp); @@ -113,12 +113,14 @@ odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT conv->suppress.einval = 1; conv->suppress.e2big = 1; tds_iconv(tds, conv, to_client, &ib, &il, &left_ob, &left_ol); - curcol->column_iconv_left = sizeof(curcol->column_iconv_buf) - left_ol; + curcol->column_iconv_left + = (sizeof(curcol->column_iconv_buf) + - (unsigned char) left_ol); /* copy part to fill buffer */ eat_iconv_left(curcol, &ob, &ol); } ol = ob - dest; /* bytes written */ - curcol->column_text_sqlgetdatapos += ib - src; + curcol->column_text_sqlgetdatapos += (TDS_INT) (ib - src); /* terminate string */ memset(ob, 0, char_size); } @@ -174,7 +176,7 @@ odbc_tds_convert_wide_iso(TDS_CHAR *src, TDS_UINT srclen, TDS_CHAR *buf, TDS_UIN return -1; *p = 0; - return p - buf; + return (int) (p - buf); } /* The following function is going to write in these structure not using them @@ -205,7 +207,7 @@ TDS_COMPILE_CHECK(timestamp_struct, sizeof(TIMESTAMP_STRUCT) == 16 static SQLLEN odbc_convert_datetime_to_binary(TDSCOLUMN *curcol, int srctype, TDS_DATETIMEALL * dta, TDS_CHAR * dest, SQLULEN destlen) { - size_t len, cplen; + TDS_INT len, cplen; TDS_USMALLINT buf[10]; TDSDATEREC when; @@ -239,7 +241,7 @@ odbc_convert_datetime_to_binary(TDSCOLUMN *curcol, int srctype, TDS_DATETIMEALL if (destlen == 0) return len; - cplen = ODBC_MIN(destlen, len); + cplen = ODBC_MIN((TDS_INT) destlen, len); memcpy(dest, buf, cplen); if (curcol) curcol->column_text_sqlgetdatapos += cplen; @@ -286,7 +288,8 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD CONV_RESULT ores; SQLLEN ret = SQL_NULL_DATA; - int i, cplen; + int i; + SQLULEN cplen; int binary_conversion = 0; TDS_CHAR conv_buf[256]; @@ -320,7 +323,8 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD } else if (is_numeric_type(nDestSybType)) { /* TODO use descriptor information (APD) ?? However APD can contain SQL_C_DEFAULT... */ if (drec_ixd) - ores.n.precision = drec_ixd->sql_desc_precision; + ores.n.precision + = (unsigned char) drec_ixd->sql_desc_precision; else ores.n.precision = 38; ores.n.scale = 0; @@ -412,8 +416,8 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD sprintf(buf + strlen(buf), " %c%02d:%02d", sign, off / 60, off % 60); } - nRetVal = strlen(buf); - memcpy(dest, buf, ODBC_MIN(destlen, nRetVal)); + nRetVal = (TDS_INT) strlen(buf); + memcpy(dest, buf, ODBC_MIN(destlen, (SQLULEN) nRetVal)); } else { normal_conversion: nRetVal = tds_convert(context, srctype, src, srclen, nDestSybType, &ores); @@ -431,7 +435,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD ret = nRetVal; /* TODO handle not terminated configuration */ if (destlen > 0) { - cplen = ODBC_MIN(destlen - 1, nRetVal); + cplen = ODBC_MIN(destlen - 1, (SQLULEN) nRetVal); assert(cplen >= 0); /* * odbc always terminate but do not overwrite @@ -455,7 +459,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD SQLWCHAR *wp = (SQLWCHAR *) dest; SQLCHAR *p = (SQLCHAR *) dest; - cplen = ODBC_MIN(destlen - 1, nRetVal); + cplen = ODBC_MIN(destlen - 1, (SQLULEN) nRetVal); assert(cplen >= 0); /* * odbc always terminate but do not overwrite diff --git a/src/odbc/descriptor.c b/src/odbc/descriptor.c index 4d6777ef7f..4725a72bc9 100644 --- a/src/odbc/descriptor.c +++ b/src/odbc/descriptor.c @@ -90,7 +90,7 @@ desc_alloc_records(TDS_DESC * desc, unsigned count) int i; /* shrink records */ - if (desc->header.sql_desc_count >= count) { + if ((unsigned) desc->header.sql_desc_count >= count) { for (i = count; i < desc->header.sql_desc_count; ++i) desc_free_record(&desc->records[i]); desc->header.sql_desc_count = count; @@ -101,7 +101,7 @@ desc_alloc_records(TDS_DESC * desc, unsigned count) return SQL_ERROR; memset(desc->records + desc->header.sql_desc_count, 0, sizeof(struct _drecord) * (count - desc->header.sql_desc_count)); - for (i = desc->header.sql_desc_count; i < count; ++i) { + for (i = desc->header.sql_desc_count; (unsigned) i < count; ++i) { drec = &desc->records[i]; #define STR_OP(name) tds_dstr_init(&drec->name) diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c index 5efa1c24f9..b28bfa6488 100644 --- a/src/odbc/odbc.c +++ b/src/odbc/odbc.c @@ -220,7 +220,7 @@ change_autocommit(TDS_DBC * dbc, int state) } static SQLRETURN -change_database(TDS_DBC * dbc, const char *database, int database_len) +change_database(TDS_DBC * dbc, const char *database, size_t database_len) { TDSSOCKET *tds = dbc->tds_socket; tds_mutex_check_owned(&dbc->mtx); @@ -1182,9 +1182,9 @@ ODBC_FUNC(SQLProcedures, (P(SQLHSTMT,hstmt), PCHARIN(CatalogName,SQLSMALLINT), } static TDSPARAMINFO* -odbc_build_update_params(TDS_STMT * stmt, unsigned int n_row) +odbc_build_update_params(TDS_STMT * stmt, SQLSETPOSIROW n_row) { - unsigned int n; + SQLSMALLINT n; TDSPARAMINFO * params = NULL; struct _drecord *drec_ird; @@ -1361,7 +1361,7 @@ SQLSetEnvAttr(SQLHENV henv, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER S SQLRETURN ODBC_PUBLIC ODBC_API SQLGetEnvAttr(SQLHENV henv, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER * StringLength) { - size_t size; + SQLINTEGER size; void *src; ODBC_ENTER_HENV; @@ -1454,7 +1454,7 @@ _SQLBindParameter(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fParamType, SQL odbc_errs_add(&stmt->errs, "HY104", "Invalid precision value"); ODBC_EXIT_(stmt); } - if (ibScale < 0 || ibScale > cbColDef) { + if (ibScale < 0 || (SQLULEN) ibScale > cbColDef) { odbc_errs_add(&stmt->errs, "HY104", "Invalid scale value"); ODBC_EXIT_(stmt); } @@ -1565,7 +1565,7 @@ _SQLBindParameter(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fParamType, SQL ODBC_EXIT_(stmt); } if (is_numeric) { - drec->sql_desc_precision = cbColDef; + drec->sql_desc_precision = (SQLSMALLINT) cbColDef; drec->sql_desc_scale = ibScale; } else { drec->sql_desc_length = cbColDef; @@ -1822,7 +1822,8 @@ _SQLAllocStmt(SQLHDBC hdbc, SQLHSTMT FAR * phstmt) stmt->num_param_rows = 1; pstr = NULL; /* TODO test initial cursor ... */ - if (asprintf(&pstr, "SQL_CUR%lx", (unsigned long) (TDS_UINTPTR) stmt) < 0 || !tds_dstr_set(&stmt->cursor_name, pstr)) { + if (asprintf(&pstr, "SQL_CUR%p", stmt) < 0 + || !tds_dstr_set(&stmt->cursor_name, pstr)) { free(stmt); free(pstr); odbc_errs_add(&dbc->errs, "HY001", NULL); @@ -2201,7 +2202,7 @@ _SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLP case SQL_COLUMN_COUNT: #endif case SQL_DESC_COUNT: - IOUT(SQLSMALLINT, ird->header.sql_desc_count); + IOUT(SQLUSMALLINT, ird->header.sql_desc_count); ODBC_EXIT(stmt, SQL_SUCCESS); break; } @@ -2410,7 +2411,8 @@ SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, ) { - return _SQLColAttribute(hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc _wide0); + return _SQLColAttribute(hstmt, icol, fDescType, rgbDesc, cbDescMax, + pcbDesc, (SQLLEN*) pfDesc _wide0); } #ifdef ENABLE_ODBC_WIDE @@ -2727,7 +2729,7 @@ ODBC_FUNC(SQLGetDescField, (P(SQLHDESC,hdesc), P(SQLSMALLINT,icol), P(SQLSMALLIN break; case SQL_DESC_COUNT: IRD_UPDATE(desc, &desc->errs, ODBC_EXIT(desc, SQL_ERROR)); - IOUT(SQLSMALLINT, fdesc->header.sql_desc_count); + IOUT(SQLUSMALLINT, fdesc->header.sql_desc_count); ODBC_EXIT_(desc); break; case SQL_DESC_ROWS_PROCESSED_PTR: @@ -3432,7 +3434,7 @@ _SQLExecute(TDS_STMT * stmt) /* check parameters are all OK */ - if (stmt->params && stmt->param_num <= stmt->param_count) { + if (stmt->params && stmt->param_num <= (int) stmt->param_count) { /* TODO what error ?? */ ODBC_SAFE_ERROR(stmt); return SQL_ERROR; @@ -3893,7 +3895,7 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset) TDSCOLUMN *colinfo; int i; SQLULEN curr_row, num_rows; - SQLINTEGER len = 0; + SQLLEN len = 0; struct _drecord *drec_ard; TDS_DESC *ard; SQLULEN dummy, *fetched_ptr; @@ -3996,7 +3998,7 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset) status_ptr = stmt->ird->header.sql_desc_array_status_ptr; if (status_ptr) { - for (i = 0; i < num_rows; ++i) + for (i = 0; (SQLULEN) i < num_rows; ++i) *status_ptr++ = SQL_ROW_NOROW; status_ptr = stmt->ird->header.sql_desc_array_status_ptr; } @@ -4465,7 +4467,7 @@ static SQLRETURN _SQLGetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER * StringLength WIDE) { void *src; - size_t size; + SQLINTEGER size; ODBC_ENTER_HSTMT; @@ -6127,7 +6129,7 @@ odbc_upper_column_names(TDS_STMT * stmt) for (icol = 0; icol < resinfo->num_cols; ++icol) { TDSCOLUMN *colinfo = resinfo->columns[icol]; char *p = tds_dstr_buf(&colinfo->column_name); - unsigned n, len = tds_dstr_len(&colinfo->column_name); + size_t n, len = tds_dstr_len(&colinfo->column_name); /* upper case */ /* TODO procedure */ @@ -6310,7 +6312,8 @@ _SQLParamData(SQLHSTMT hstmt, SQLPOINTER FAR * prgbValue) tdsdump_log(TDS_DBG_FUNC, "SQLParamData(%p, %p) [param_num %d, param_data_called = %d]\n", hstmt, prgbValue, stmt->param_num, stmt->param_data_called); - if (stmt->params && stmt->param_num <= stmt->param_count) { + if (stmt->params + && (unsigned int) stmt->param_num <= stmt->param_count) { SQLRETURN res; if (stmt->param_num <= 0 || stmt->param_num > stmt->apd->header.sql_desc_count) { @@ -6391,13 +6394,13 @@ ODBC_FUNC(SQLSetConnectAttr, (P(SQLHDBC,hdbc), P(SQLINTEGER,Attribute), P(SQLPOI switch (Attribute) { case SQL_ATTR_AUTOCOMMIT: /* spinellia@acm.org */ - change_autocommit(dbc, u_value); + change_autocommit(dbc, (int) u_value); break; case SQL_ATTR_CONNECTION_TIMEOUT: - dbc->attr.connection_timeout = u_value; + dbc->attr.connection_timeout = (SQLUINTEGER) u_value; break; case SQL_ATTR_ACCESS_MODE: - dbc->attr.access_mode = u_value; + dbc->attr.access_mode = (SQLUINTEGER) u_value; break; case SQL_ATTR_CURRENT_CATALOG: if (!IS_VALID_LEN(StringLength)) { @@ -6417,24 +6420,24 @@ ODBC_FUNC(SQLSetConnectAttr, (P(SQLHDBC,hdbc), P(SQLINTEGER,Attribute), P(SQLPOI break; case SQL_ATTR_CURSOR_TYPE: if (dbc->cursor_support) - dbc->attr.cursor_type = u_value; + dbc->attr.cursor_type = (SQLUINTEGER) u_value; break; case SQL_ATTR_LOGIN_TIMEOUT: - dbc->attr.login_timeout = u_value; + dbc->attr.login_timeout = (SQLUINTEGER) u_value; break; case SQL_ATTR_ODBC_CURSORS: /* TODO cursors */ - dbc->attr.odbc_cursors = u_value; + dbc->attr.odbc_cursors = (SQLUINTEGER) u_value; break; case SQL_ATTR_PACKET_SIZE: - dbc->attr.packet_size = u_value; + dbc->attr.packet_size = (SQLUINTEGER) u_value; break; case SQL_ATTR_QUIET_MODE: dbc->attr.quite_mode = (SQLHWND) (TDS_INTPTR) ValuePtr; break; #ifdef TDS_NO_DM case SQL_ATTR_TRACE: - dbc->attr.trace = u_value; + dbc->attr.trace = (SQLUINTEGER) u_value; break; case SQL_ATTR_TRACEFILE: if (!IS_VALID_LEN(StringLength)) { @@ -6447,12 +6450,13 @@ ODBC_FUNC(SQLSetConnectAttr, (P(SQLHDBC,hdbc), P(SQLINTEGER,Attribute), P(SQLPOI #endif case SQL_ATTR_TXN_ISOLATION: if (u_value != dbc->attr.txn_isolation) { - if (change_txn(dbc, u_value) == SQL_SUCCESS) - dbc->attr.txn_isolation = u_value; + if (change_txn(dbc, (SQLUINTEGER) u_value) + == SQL_SUCCESS) + dbc->attr.txn_isolation = (SQLUINTEGER)u_value; } break; case SQL_COPT_SS_MARS_ENABLED: - dbc->attr.mars_enabled = u_value; + dbc->attr.mars_enabled = (SQLUINTEGER) u_value; break; case SQL_ATTR_TRANSLATE_LIB: case SQL_ATTR_TRANSLATE_OPTION: @@ -6469,7 +6473,7 @@ ODBC_FUNC(SQLSetConnectAttr, (P(SQLHDBC,hdbc), P(SQLINTEGER,Attribute), P(SQLPOI dbc->use_oldpwd = 1; break; case SQL_COPT_SS_BCP: - dbc->attr.bulk_enabled = u_value; + dbc->attr.bulk_enabled = (SQLUINTEGER) u_value; break; case SQL_COPT_TDSODBC_IMPL_BCP_INITA: if (!ValuePtr) @@ -6612,7 +6616,7 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN odbc_errs_add(&stmt->errs, "HYC00", NULL); break; } - stmt->attr.async_enable = ui; + stmt->attr.async_enable = (SQLUINTEGER) ui; break; case SQL_ATTR_CONCURRENCY: if (stmt->attr.concurrency != ui && !stmt->dbc->cursor_support) { @@ -6638,7 +6642,7 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN odbc_errs_add(&stmt->errs, "HY092", NULL); ODBC_EXIT_(stmt); } - stmt->attr.concurrency = ui; + stmt->attr.concurrency = (SQLUINTEGER) ui; break; case SQL_ATTR_CURSOR_SCROLLABLE: if (stmt->attr.cursor_scrollable != ui && !stmt->dbc->cursor_support) { @@ -6657,7 +6661,7 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN odbc_errs_add(&stmt->errs, "HY092", NULL); ODBC_EXIT_(stmt); } - stmt->attr.cursor_scrollable = ui; + stmt->attr.cursor_scrollable = (SQLUINTEGER) ui; break; case SQL_ATTR_CURSOR_SENSITIVITY: /* don't change anything */ @@ -6676,7 +6680,7 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN stmt->attr.concurrency = SQL_CONCUR_ROWVER; break; } - stmt->attr.cursor_sensitivity = ui; + stmt->attr.cursor_sensitivity = (SQLUINTEGER) ui; break; case SQL_ATTR_CURSOR_TYPE: if (stmt->attr.cursor_type != ui && !stmt->dbc->cursor_support) { @@ -6710,14 +6714,14 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN odbc_errs_add(&stmt->errs, "HY092", NULL); ODBC_EXIT_(stmt); } - stmt->attr.cursor_type = ui; + stmt->attr.cursor_type = (SQLUINTEGER) ui; break; case SQL_ATTR_ENABLE_AUTO_IPD: if (stmt->attr.enable_auto_ipd != ui) { odbc_errs_add(&stmt->errs, "HYC00", NULL); break; } - stmt->attr.enable_auto_ipd = ui; + stmt->attr.enable_auto_ipd = (SQLUINTEGER) ui; break; case SQL_ATTR_FETCH_BOOKMARK_PTR: stmt->attr.fetch_bookmark_ptr = ValuePtr; @@ -6747,17 +6751,17 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN stmt->attr.max_rows = ui; break; case SQL_ATTR_METADATA_ID: - stmt->attr.metadata_id = ui; + stmt->attr.metadata_id = (SQLUINTEGER) ui; break; /* TODO use it !!! */ case SQL_ATTR_NOSCAN: - stmt->attr.noscan = ui; + stmt->attr.noscan = (SQLUINTEGER) ui; break; case SQL_ATTR_PARAM_BIND_OFFSET_PTR: stmt->apd->header.sql_desc_bind_offset_ptr = lp; break; case SQL_ATTR_PARAM_BIND_TYPE: - stmt->apd->header.sql_desc_bind_type = ui; + stmt->apd->header.sql_desc_bind_type = (SQLUINTEGER) ui; break; case SQL_ATTR_PARAM_OPERATION_PTR: stmt->apd->header.sql_desc_array_status_ptr = usip; @@ -6778,7 +6782,7 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN odbc_errs_add(&stmt->errs, "01S02", NULL); ui = 65534; } - stmt->attr.query_timeout = ui; + stmt->attr.query_timeout = (SQLUINTEGER) ui; break; /* retrieve data after positioning the cursor */ case SQL_ATTR_RETRIEVE_DATA: @@ -6787,7 +6791,7 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN odbc_errs_add(&stmt->errs, "01S02", NULL); break; } - stmt->attr.retrieve_data = ui; + stmt->attr.retrieve_data = (SQLUINTEGER) ui; break; case SQL_ATTR_ROW_ARRAY_SIZE: stmt->ard->header.sql_desc_array_size = ui; @@ -6800,7 +6804,7 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN case SQL_BIND_TYPE: /* although this is ODBC2 we must support this attribute */ #endif case SQL_ATTR_ROW_BIND_TYPE: - stmt->ard->header.sql_desc_bind_type = ui; + stmt->ard->header.sql_desc_bind_type = (SQLUINTEGER) ui; break; case SQL_ATTR_ROW_NUMBER: odbc_errs_add(&stmt->errs, "HY092", NULL); @@ -6824,14 +6828,14 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN odbc_errs_add(&stmt->errs, "01S02", NULL); break; } - stmt->attr.simulate_cursor = ui; + stmt->attr.simulate_cursor = (SQLUINTEGER) ui; break; case SQL_ATTR_USE_BOOKMARKS: if (stmt->cursor) { odbc_errs_add(&stmt->errs, "24000", NULL); break; } - stmt->attr.use_bookmarks = ui; + stmt->attr.use_bookmarks = (SQLUINTEGER) ui; break; case SQL_ROWSET_SIZE: /* although this is ODBC2 we must support this attribute */ if (((TDS_INTPTR) ValuePtr) < 1) { @@ -6845,7 +6849,7 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN odbc_errs_add(&stmt->errs, "HY024", NULL); break; } - stmt->attr.qn_timeout = ui; + stmt->attr.qn_timeout = (SQLUINTEGER) ui; break; case SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT: if (!IS_VALID_LEN(StringLength)) { @@ -6873,9 +6877,9 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN odbc_errs_add(&stmt->errs, "IM020", NULL); break; } - stmt->attr.param_focus = ui; - stmt->orig_apd->focus = ui; - stmt->ipd->focus = ui; + stmt->attr.param_focus = (SQLUINTEGER) ui; + stmt->orig_apd->focus = (int) ui; + stmt->ipd->focus = (int) ui; break; default: odbc_errs_add(&stmt->errs, "HY092", NULL); @@ -7287,13 +7291,13 @@ odbc_log_unimplemented_type(const char function_name[], int fType) return; } -static int +static size_t odbc_quote_metadata(TDS_DBC * dbc, char type, char *dest, DSTR * dstr) { int unquote = 0; char prev, buf[1200], *dst; const char *s = tds_dstr_cstr(dstr); - int len = tds_dstr_len(dstr); + ssize_t len = tds_dstr_len(dstr); /* limit string/id lengths */ if (len > 384) @@ -7374,7 +7378,8 @@ odbc_quote_metadata(TDS_DBC * dbc, char type, char *dest, DSTR * dstr) } static TDSPARAMINFO* -odbc_add_char_param(TDSSOCKET *tds, TDSPARAMINFO *params, const char *name, const char *value, size_t len) +odbc_add_char_param(TDSSOCKET *tds, TDSPARAMINFO *params, const char *name, + const char *value, TDS_INT len) { TDSCOLUMN *col; @@ -7424,7 +7429,8 @@ odbc_add_int_param(TDSSOCKET *tds, TDSPARAMINFO *params, const char *name, int v static SQLRETURN odbc_stat_execute(TDS_STMT * stmt _WIDE, const char *begin, int nparams, ...) { - int i, len, param_qualifier = -1; + int i, param_qualifier = -1; + size_t len; char *proc = NULL, *p; SQLRETURN retcode; va_list marker; @@ -7493,7 +7499,8 @@ odbc_stat_execute(TDS_STMT * stmt _WIDE, const char *begin, int nparams, ...) char buf[1200]; int l; - l = odbc_quote_metadata(stmt->dbc, type, buf, &value); + l = (int) odbc_quote_metadata(stmt->dbc, type, buf, + &value); if (!odbc_add_char_param(stmt->dbc->tds_socket, params, name, buf, l)) goto mem_error; diff --git a/src/odbc/odbc_checks.c b/src/odbc/odbc_checks.c index a01d4ba6a0..88b7856dff 100644 --- a/src/odbc/odbc_checks.c +++ b/src/odbc/odbc_checks.c @@ -74,7 +74,7 @@ odbc_check_stmt_extra(TDS_STMT * stmt) odbc_check_desc_extra(stmt->apd); odbc_check_desc_extra(stmt->ipd); assert(!stmt->prepared_query_is_func || stmt->prepared_query_is_rpc); - assert(stmt->param_num <= stmt->param_count + 1); + assert(stmt->param_num <= (int) stmt->param_count + 1); assert(stmt->num_param_rows >= 1); assert(stmt->curr_param_row >= 0); assert(stmt->curr_param_row <= stmt->num_param_rows); diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c index ea620734c6..42d4bb52b8 100644 --- a/src/odbc/odbc_util.c +++ b/src/odbc/odbc_util.c @@ -24,6 +24,8 @@ #include #endif /* HAVE_STDLIB_H */ +#include + #if HAVE_STRING_H #include #endif /* HAVE_STRING_H */ @@ -50,13 +52,14 @@ */ #ifdef ENABLE_ODBC_WIDE -static DSTR *odbc_iso2utf(DSTR *res, const char *s, unsigned int len); -static DSTR *odbc_mb2utf(TDS_DBC *dbc, DSTR *res, const char *s, unsigned int len); -static DSTR *odbc_wide2utf(DSTR *res, const SQLWCHAR *s, unsigned int len); +static DSTR *odbc_iso2utf(DSTR *res, const char *s, size_t len); +static DSTR *odbc_mb2utf(TDS_DBC *dbc, DSTR *res, const char *s, size_t len); +static DSTR *odbc_wide2utf(DSTR *res, const SQLWCHAR *s, size_t len); #endif int -odbc_set_stmt_query(TDS_STMT * stmt, const ODBC_CHAR *sql, int sql_len _WIDE) +odbc_set_stmt_query(TDS_STMT * stmt, const ODBC_CHAR *sql, ssize_t sql_len + _WIDE) { if (sql_len == SQL_NTS) #ifdef ENABLE_ODBC_WIDE @@ -86,8 +89,8 @@ odbc_set_stmt_query(TDS_STMT * stmt, const ODBC_CHAR *sql, int sql_len _WIDE) return SQL_SUCCESS; } -unsigned int -odbc_get_string_size(int size, const ODBC_CHAR * str _WIDE) +size_t +odbc_get_string_size(ssize_t size, const ODBC_CHAR * str _WIDE) { if (str) { if (size == SQL_NTS) @@ -105,9 +108,9 @@ odbc_get_string_size(int size, const ODBC_CHAR * str _WIDE) #ifdef ENABLE_ODBC_WIDE static DSTR* -odbc_iso2utf(DSTR *res, const char *s, unsigned int len) +odbc_iso2utf(DSTR *res, const char *s, size_t len) { - unsigned int i, o_len = len + 1; + size_t i, o_len = len + 1; char *out, *p; assert(s); @@ -133,9 +136,9 @@ odbc_iso2utf(DSTR *res, const char *s, unsigned int len) } static DSTR* -odbc_wide2utf(DSTR *res, const SQLWCHAR *s, unsigned int len) +odbc_wide2utf(DSTR *res, const SQLWCHAR *s, size_t len) { - unsigned int i, o_len = len + 1; + size_t i, o_len = len + 1; char *out, *p; #if SIZEOF_SQLWCHAR > 2 @@ -216,7 +219,7 @@ odbc_wide2utf(DSTR *res, const SQLWCHAR *s, unsigned int len) } static DSTR* -odbc_mb2utf(TDS_DBC *dbc, DSTR *res, const char *s, unsigned int len) +odbc_mb2utf(TDS_DBC *dbc, DSTR *res, const char *s, size_t len) { char *buf; @@ -265,10 +268,10 @@ odbc_mb2utf(TDS_DBC *dbc, DSTR *res, const char *s, unsigned int len) * 0x20 size is in bytes, not characters */ DSTR* -odbc_dstr_copy_flag(TDS_DBC *dbc, DSTR *s, int size, const ODBC_CHAR * str, int flag) +odbc_dstr_copy_flag(TDS_DBC *dbc, DSTR *s, ssize_t size, const ODBC_CHAR * str, int flag) { int wide = flag&1; - unsigned int len; + size_t len; len = odbc_get_string_size((flag&0x21) == 0x21 && size >= 0 ? size/SIZEOF_SQLWCHAR : size, str, wide); if (wide) @@ -278,7 +281,7 @@ odbc_dstr_copy_flag(TDS_DBC *dbc, DSTR *s, int size, const ODBC_CHAR * str, int } #else DSTR* -odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, int size, const ODBC_CHAR * str) +odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, ssize_t size, const ODBC_CHAR * str) { return tds_dstr_copyn(s, (const char *) str, odbc_get_string_size(size, str)); } @@ -298,12 +301,14 @@ odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, int size, const ODBC_CHAR * str) * 0x20 size is in bytes, not characters */ SQLRETURN -odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void FAR * pcbBuffer, const char *s, int len, int flag) +odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, + void FAR * pcbBuffer, const char *s, ssize_t len, + int flag) { SQLRETURN result = SQL_SUCCESS; int out_len = 0; #if !defined(NDEBUG) && defined(ENABLE_ODBC_WIDE) - size_t initial_size; + ptrdiff_t initial_size; #endif if (len < 0) @@ -428,7 +433,7 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void char_conv->suppress.e2big = 1; if (cbBuffer && tds_iconv(dbc->tds_socket, char_conv, to_client, &ib, &il, &ob, &ol) == (size_t)-1 && errno != E2BIG) result = SQL_ERROR; - out_len = cbBuffer - ol; + out_len = cbBuffer - (int) ol; while (result != SQL_ERROR && il) { char discard[128]; ol = sizeof(discard); @@ -483,7 +488,7 @@ odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row) /* TODO handle different type results (functions) on mssql2k */ if (stmt->prepared_query_is_func && tds->has_status) { struct _drecord *drec; - int len; + SQLLEN len; const TDS_DESC* axd = stmt->apd; TDS_INTPTR len_offset; char *data_ptr; @@ -535,7 +540,7 @@ odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row) const TDS_DESC* axd = stmt->apd; const struct _drecord *drec_apd, *drec_ipd; TDSCOLUMN *colinfo = info->columns[i]; - SQLINTEGER len; + SQLLEN len; int c_type; char *data_ptr; TDS_INTPTR len_offset; @@ -861,10 +866,12 @@ odbc_rdbms_version(TDSSOCKET * tds, char *pversion_string) } /** Return length of parameter from parameter information */ -SQLINTEGER -odbc_get_param_len(const struct _drecord *drec_axd, const struct _drecord *drec_ixd, const TDS_DESC* axd, unsigned int n_row) +SQLLEN +odbc_get_param_len(const struct _drecord *drec_axd, + const struct _drecord *drec_ixd, const TDS_DESC* axd, + SQLSETPOSIROW n_row) { - SQLINTEGER len; + SQLLEN len; int size; TDS_INTPTR len_offset; diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c index 6504ae394b..4b2c709f39 100644 --- a/src/odbc/prepare_query.c +++ b/src/odbc/prepare_query.c @@ -151,7 +151,7 @@ prepared_rpc(struct _hstmt *stmt, bool compute_row) curcol->column_cur_size = len; break; case SYBINT4: - *((TDS_INT *) dest) = strtol(start, NULL, 10); + *((TDS_INT *) dest) = atoi(start); break; case SYBINT8: *((TDS_INT8 *) dest) = tds_strtoll(start, NULL, 10); @@ -207,7 +207,8 @@ parse_prepared_query(struct _hstmt *stmt, bool compute_row) tdsdump_log(TDS_DBG_FUNC, "parsing %d parameters\n", nparam); - for (; stmt->param_num <= stmt->param_count; ++nparam, ++stmt->param_num) { + for (; stmt->param_num <= (int) stmt->param_count; + ++nparam, ++stmt->param_num) { /* find bound parameter */ if (stmt->param_num > stmt->apd->header.sql_desc_count || stmt->param_num > stmt->ipd->header.sql_desc_count) { tdsdump_log(TDS_DBG_FUNC, "parse_prepared_query: logic_error: parameter out of bounds: " @@ -247,10 +248,11 @@ start_parse_prepared_query(struct _hstmt *stmt, bool compute_row) return parse_prepared_query(stmt, compute_row); } -static TDS_INT -odbc_wchar2hex(TDS_CHAR *dest, TDS_UINT destlen, const SQLWCHAR * src, TDS_UINT srclen) +static ssize_t +odbc_wchar2hex(TDS_CHAR *dest, size_t destlen, const SQLWCHAR * src, + size_t srclen) { - unsigned int i; + size_t i; SQLWCHAR hex1, c = 0; /* if srclen if odd we must add a "0" before ... */ @@ -403,7 +405,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St p += curcol->column_cur_size; if (binary_convert) { - int res; + ssize_t res; len = orig_len; @@ -415,7 +417,8 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St res = odbc_wchar2hex(p, 1, data, 2); if (res < 0) { - odbc_convert_err_set(&stmt->errs, res); + odbc_convert_err_set(&stmt->errs, + (TDS_INT) res); return SQL_ERROR; } p += res; @@ -434,7 +437,8 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St tds_char2hex(p, len / 2u, (const TDS_CHAR*) DataPtr, len): odbc_wchar2hex(p, len / 2u, (const SQLWCHAR*) DataPtr, len); if (res < 0) { - odbc_convert_err_set(&stmt->errs, res); + odbc_convert_err_set(&stmt->errs, + (TDS_INT) res); return SQL_ERROR; } p += res; diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c index a1b7b709ae..8b192514db 100644 --- a/src/odbc/sql2tds.c +++ b/src/odbc/sql2tds.c @@ -136,7 +136,7 @@ odbc_wstr2str(TDS_STMT * stmt, const char *src, int* len) return NULL; } - *len = p - out; + *len = (int) (p - out); return out; } @@ -253,7 +253,7 @@ odbc_convert_table(TDS_STMT *stmt, SQLTVP *src, TDS_TVP *dest, SQLLEN num_rows) */ SQLRETURN odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ixd, const struct _drecord *drec_axd, TDSCOLUMN *curcol, - bool compute_row, const TDS_DESC* axd, unsigned int n_row) + bool compute_row, const TDS_DESC* axd, SQLSETPOSIROW n_row) { TDS_DBC * dbc = stmt->dbc; TDSCONNECTION * conn = dbc->tds_socket->conn; @@ -267,7 +267,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ixd, const struct _dre TDS_DATETIMEALL dta; TDS_NUMERIC num; SQL_NUMERIC_STRUCT *sql_num; - SQLINTEGER sql_len; + SQLLEN sql_len; bool need_data = false; int i; @@ -308,8 +308,9 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ixd, const struct _dre } } if (is_numeric_type(curcol->column_type)) { - curcol->column_prec = drec_ixd->sql_desc_precision; - curcol->column_scale = drec_ixd->sql_desc_scale; + curcol->column_prec + = (TDS_TINYINT) drec_ixd->sql_desc_precision; + curcol->column_scale = (TDS_TINYINT) drec_ixd->sql_desc_scale; } if (drec_ixd->sql_desc_parameter_type != SQL_PARAM_INPUT) @@ -400,9 +401,10 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ixd, const struct _dre return SQL_ERROR; } if (sql_src_type == SQL_C_WCHAR) - len = sqlwcslen((const SQLWCHAR *) src) * sizeof(SQLWCHAR); + len = (int) sqlwcslen((const SQLWCHAR *) src) + * sizeof(SQLWCHAR); else - len = strlen(src); + len = (int) strlen(src); break; case SQL_DEFAULT_PARAM: odbc_errs_add(&stmt->errs, "07S01", NULL); /* Invalid use of default parameter */ @@ -564,8 +566,10 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ixd, const struct _dre break; case SYBNUMERIC: case SYBDECIMAL: - ((TDS_NUMERIC *) dest)->precision = drec_ixd->sql_desc_precision; - ((TDS_NUMERIC *) dest)->scale = drec_ixd->sql_desc_scale; + ((TDS_NUMERIC *) dest)->precision + = (unsigned char) drec_ixd->sql_desc_precision; + ((TDS_NUMERIC *) dest)->scale + = (unsigned char) drec_ixd->sql_desc_scale; case SYBINTN: case SYBINT1: case SYBINT2: diff --git a/src/odbc/unittests/bcp.c b/src/odbc/unittests/bcp.c index 15e46c827c..be9587a92c 100644 --- a/src/odbc/unittests/bcp.c +++ b/src/odbc/unittests/bcp.c @@ -139,7 +139,10 @@ init(void) } #define VARCHAR_BIND(x) \ - bcp_bind( odbc_conn, (prefixlen == 0 ? (void*)&x.value : (void*)&x.prefix), prefixlen, strlen(x.value), NULL, termlen, BCP_TYPE_SQLVARCHAR, col++ ) + bcp_bind( odbc_conn, \ + (prefixlen == 0 ? (void*)&x.value : (void*)&x.prefix), \ + prefixlen, (SQLINTEGER) strlen(x.value), NULL, termlen, \ + BCP_TYPE_SQLVARCHAR, col++ ) #define INT_BIND(x) \ bcp_bind( odbc_conn, (prefixlen == 0 ? (void*)&x.value : (void*)&x.prefix), prefixlen, SQL_VARLEN_DATA, NULL, termlen, BCP_TYPE_SQLINT4, col++ ) diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c index 967f517221..cd80386854 100644 --- a/src/odbc/unittests/blob1.c +++ b/src/odbc/unittests/blob1.c @@ -30,7 +30,7 @@ fill_hex(char *buf, size_t len, unsigned int start, unsigned int step) static int -check_chars(const char *buf, size_t len, unsigned int start, unsigned int step) +check_chars(const char *buf, size_t len, SQLLEN start, unsigned int step) { size_t n; @@ -42,7 +42,7 @@ check_chars(const char *buf, size_t len, unsigned int start, unsigned int step) } static int -check_hex(const char *buf, size_t len, unsigned int start, unsigned int step) +check_hex(const char *buf, size_t len, SQLLEN start, unsigned int step) { size_t n; char symbol[3]; @@ -70,9 +70,9 @@ static test_info test_infos[MAX_TESTS]; static unsigned num_tests = 0; static void -dump(FILE* out, const char* start, void* buf, unsigned len) +dump(FILE* out, const char* start, void* buf, SQLULEN len) { - unsigned n; + SQLULEN n; char s[17]; if (len >= 16) len = 16; @@ -183,7 +183,7 @@ static void add_test(SQLSMALLINT c_type, SQLSMALLINT sql_type, const char *db_type, unsigned gen1, unsigned gen2) { test_info *t = NULL; - size_t buf_len; + int buf_len; if (num_tests >= MAX_TESTS) { fprintf(stderr, "too max tests\n"); diff --git a/src/odbc/unittests/c2string.c b/src/odbc/unittests/c2string.c index e557a7cfd8..9ab448a655 100644 --- a/src/odbc/unittests/c2string.c +++ b/src/odbc/unittests/c2string.c @@ -37,7 +37,7 @@ odbc_c2string(char *out, SQLSMALLINT out_c_type, const void *in, size_t in_len) } buf_t; #undef IN #define IN (*((const buf_t*) in)) - int i; + size_t i; const SQL_NUMERIC_STRUCT *num; char *s; @@ -50,7 +50,7 @@ odbc_c2string(char *out, SQLSMALLINT out_c_type, const void *in, size_t in_len) i = SQL_MAX_NUMERIC_LEN; for (; i > 0 && !num->val[--i];) continue; - for (; i >= 0; --i) + for (; (int) i >= 0; --i) s += sprintf(s, "%02X", num->val[i]); break; case SQL_C_BINARY: @@ -78,7 +78,7 @@ odbc_c2string(char *out, SQLSMALLINT out_c_type, const void *in, size_t in_len) break; case SQL_C_SBIGINT: assert(in_len == sizeof(SQLBIGINT)); - sprintf(s, "%" PRId64, IN.bi); + sprintf(s, "%" PRId64, (int64_t) IN.bi); break; case SQL_C_SHORT: assert(in_len == sizeof(SQLSMALLINT)); diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c index ab7e87d73a..8d04cfd650 100644 --- a/src/odbc/unittests/cancel.c +++ b/src/odbc/unittests/cancel.c @@ -73,7 +73,7 @@ static HANDLE alarm_cond = NULL; static DWORD WINAPI alarm_thread_proc(LPVOID arg) { - unsigned int timeout = (uintptr_t) arg; + unsigned int timeout = (unsigned int) (uintptr_t) arg; switch (WaitForSingleObject(alarm_cond, timeout * 1000)) { case WAIT_OBJECT_0: return 0; diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c index dc0aeb1640..9b8910f300 100644 --- a/src/odbc/unittests/common.c +++ b/src/odbc/unittests/common.c @@ -49,7 +49,7 @@ static char db_str_version[32]; static int check_lib(char *path, const char *file) { - int len = strlen(path); + size_t len = strlen(path); FILE *f; strcat(path, file); @@ -85,7 +85,7 @@ odbc_read_login_info(void) char *s1, *s2; const char *const *search_p; char path[1024]; - int len; + size_t len; int ini_override = 1; #if defined(_WIN32) && !defined(TDS_NO_DM) UWORD old_config_mode; @@ -668,19 +668,19 @@ odbc_read_error(void) printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err); } -int -odbc_to_sqlwchar(SQLWCHAR *dst, const char *src, int n) +SQLLEN +odbc_to_sqlwchar(SQLWCHAR *dst, const char *src, SQLLEN n) { - int i = n; + SQLLEN i = n; while (--i >= 0) dst[i] = (unsigned char) src[i]; return n * sizeof(SQLWCHAR); } -int -odbc_from_sqlwchar(char *dst, const SQLWCHAR *src, int n) +SQLLEN +odbc_from_sqlwchar(char *dst, const SQLWCHAR *src, SQLLEN n) { - int i; + SQLLEN i; if (n < 0) { const SQLWCHAR *p = src; for (n=1; *p++ != 0; ++n) diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h index 2a5a843cfc..e991e713c6 100644 --- a/src/odbc/unittests/common.h +++ b/src/odbc/unittests/common.h @@ -198,8 +198,8 @@ TDS_SYS_SOCKET odbc_find_last_socket(void); */ void odbc_c2string(char *out, SQLSMALLINT out_c_type, const void *in, size_t in_len); -int odbc_to_sqlwchar(SQLWCHAR *dst, const char *src, int n); -int odbc_from_sqlwchar(char *dst, const SQLWCHAR *src, int n); +SQLLEN odbc_to_sqlwchar(SQLWCHAR *dst, const char *src, SQLLEN n); +SQLLEN odbc_from_sqlwchar(char *dst, const SQLWCHAR *src, SQLLEN n); typedef struct odbc_buf ODBC_BUF; extern ODBC_BUF *odbc_buf; diff --git a/src/odbc/unittests/connect2.c b/src/odbc/unittests/connect2.c index ed26b784de..ad16385487 100644 --- a/src/odbc/unittests/connect2.c +++ b/src/odbc/unittests/connect2.c @@ -58,7 +58,8 @@ check_dbname(const char *dbname) static void set_dbname(const char *dbname) { - CHKSetConnectAttr(SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER) T(dbname), strlen(dbname)*sizeof(SQLTCHAR), "SI"); + CHKSetConnectAttr(SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER) T(dbname), + (SQLINTEGER) strlen(dbname)*sizeof(SQLTCHAR), "SI"); } int @@ -83,7 +84,8 @@ main(void) printf("SQLConnect after not existing..\n"); strcpy(tmp, "IDontExist"); - CHKSetConnectAttr(SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER) tmp, strlen(tmp), "E"); + CHKSetConnectAttr(SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER) tmp, + (SQLINTEGER) strlen(tmp), "E"); check_dbname("tempdb"); odbc_disconnect(); diff --git a/src/odbc/unittests/convert_error.c b/src/odbc/unittests/convert_error.c index 9707a88946..3f3da21eab 100644 --- a/src/odbc/unittests/convert_error.c +++ b/src/odbc/unittests/convert_error.c @@ -22,7 +22,7 @@ Test(const char *bind1, SQLSMALLINT type1, const char *bind2, SQLSMALLINT type2) ++test_num; sprintf(sql, "insert into #test_output values (%s, %s)", bind1, bind2); - CHKPrepare(T(sql), strlen(sql), "S"); + CHKPrepare(T(sql), (SQLINTEGER) strlen(sql), "S"); if (bind1[0] == '?') CHKBindParameter(id++, SQL_PARAM_INPUT, SQL_C_LONG, type1, 3, 0, &test_num, 0, &ind, "S"); if (bind2[0] == '?') diff --git a/src/odbc/unittests/cursor7.c b/src/odbc/unittests/cursor7.c index 2c95cbf0b0..6917a3d1ce 100644 --- a/src/odbc/unittests/cursor7.c +++ b/src/odbc/unittests/cursor7.c @@ -17,7 +17,7 @@ Test(void) SQLUSMALLINT statuses[ROWS]; SQLULEN num_row; - int i; + SQLLEN i; SQLRETURN RetCode; odbc_reset_statement(); diff --git a/src/odbc/unittests/describecol.c b/src/odbc/unittests/describecol.c index eed4683f93..024a7e136a 100644 --- a/src/odbc/unittests/describecol.c +++ b/src/odbc/unittests/describecol.c @@ -47,11 +47,11 @@ lookup(const char *name, const struct lookup_int *table) } static const char* -unlookup(long int value, const struct lookup_int *table) +unlookup(SQLLEN value, const struct lookup_int *table) { static char buf[32]; - sprintf(buf, "%ld", value); + sprintf(buf, "%ld", (long) value); if (!table) return buf; diff --git a/src/odbc/unittests/freeclose.c b/src/odbc/unittests/freeclose.c index e1fcd9d150..4ca4c0a9d5 100644 --- a/src/odbc/unittests/freeclose.c +++ b/src/odbc/unittests/freeclose.c @@ -93,7 +93,7 @@ init_fake_server(int ip_port) } static void -write_all(TDS_SYS_SOCKET s, const void *buf, size_t len) +write_all(TDS_SYS_SOCKET s, const void *buf, int len) { int res, l; fd_set fds_write; diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c index 12fd8567ca..840e4c77c7 100644 --- a/src/odbc/unittests/getdata.c +++ b/src/odbc/unittests/getdata.c @@ -34,7 +34,7 @@ static int mycmp(const char *s1, const char *s2) { SQLWCHAR buf[128], *wp; - unsigned l; + size_t l; if (type == SQL_C_CHAR) return strcmp(s1, s2); diff --git a/src/odbc/unittests/long_error.c b/src/odbc/unittests/long_error.c index fc8f938ba2..ffd9a40164 100644 --- a/src/odbc/unittests/long_error.c +++ b/src/odbc/unittests/long_error.c @@ -50,7 +50,7 @@ main(void) static void extract_error(SQLHANDLE handle, SQLSMALLINT type) { - SQLINTEGER i = 0; + SQLSMALLINT i = 0; SQLINTEGER native; SQLTCHAR state[7]; SQLTCHAR text[256]; diff --git a/src/odbc/unittests/params.c b/src/odbc/unittests/params.c index 555cf4b49e..ef58922f93 100644 --- a/src/odbc/unittests/params.c +++ b/src/odbc/unittests/params.c @@ -16,7 +16,7 @@ static const char sp_define[] = "CREATE PROCEDURE spTestProc\n" " SELECT @OutString = 'This is cool!'\n" " IF @InParam < 10\n" " RETURN (0)\n" " ELSE\n" " RETURN (1)\n"; -#define SP_TEXT "{?=call spTestProc(?,?,?)}" +static char sp_text[] = "{?=call spTestProc(?,?,?)}"; #define OUTSTRING_LEN 20 static int @@ -38,7 +38,7 @@ Test(int bind_before) odbc_command(sp_define); if (!bind_before) - CHKPrepare(T(SP_TEXT), strlen(SP_TEXT), "S"); + CHKPrepare(T(sp_text), sizeof(sp_text) - 1, "S"); CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &ReturnCode, 0, &cbReturnCode, "S"); CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &InParam, 0, &cbInParam, "S"); @@ -50,7 +50,7 @@ Test(int bind_before) OUTSTRING_LEN, &cbOutString, "S"); if (bind_before) - CHKPrepare(T(SP_TEXT), strlen(SP_TEXT), "S"); + CHKPrepare(T(sp_text), sizeof(sp_text) - 1, "S"); CHKExecute("S"); diff --git a/src/odbc/unittests/putdata.c b/src/odbc/unittests/putdata.c index b03e9ebbf7..2928cdd27d 100644 --- a/src/odbc/unittests/putdata.c +++ b/src/odbc/unittests/putdata.c @@ -24,7 +24,7 @@ static void Test(int direct) { SQLLEN ind; - int len = strlen(test_text), n, i; + int len = sizeof(test_text) - 1, n, i; const char *p; char *pp; SQLPOINTER ptr; @@ -65,7 +65,7 @@ Test(int direct) ODBC_REPORT_ERROR("Wrong pointer from SQLParamData"); } while (*p) { - int l = strlen(p); + int l = (int) strlen(p); if (l < n) n = l; @@ -119,7 +119,7 @@ Test(int direct) if (ptr != (SQLPOINTER) 4567) ODBC_REPORT_ERROR("Wrong pointer from SQLParamData"); while (pb != (buf + 254)) { - int l = buf + 254 - pb; + int l = (int) (buf + 254 - pb); if (l < n) n = l; diff --git a/src/odbc/unittests/raiserror.c b/src/odbc/unittests/raiserror.c index d8919f09ac..1cfef60670 100644 --- a/src/odbc/unittests/raiserror.c +++ b/src/odbc/unittests/raiserror.c @@ -134,7 +134,8 @@ Test(int level) TestResult(result, level, "SQLExecDirect"); /* test with SQLPrepare/SQLExecute */ - if (!SQL_SUCCEEDED(SQLPrepare(odbc_stmt, T(SP_TEXT), strlen(SP_TEXT)))) { + if ( !SQL_SUCCEEDED(SQLPrepare(odbc_stmt, T(SP_TEXT), + (SQLINTEGER) strlen(SP_TEXT))) ) { fprintf(stderr, "SQLPrepare failure!\n"); exit(1); } diff --git a/src/odbc/unittests/rebindpar.c b/src/odbc/unittests/rebindpar.c index 81270a8e30..ffa2dc2dfa 100644 --- a/src/odbc/unittests/rebindpar.c +++ b/src/odbc/unittests/rebindpar.c @@ -12,7 +12,7 @@ static void TestInsert(char *buf) { SQLLEN ind; - int l = strlen(buf); + int l = (int) strlen(buf); char sql[200]; /* insert some data and test success */ diff --git a/src/odbc/unittests/rpc.c b/src/odbc/unittests/rpc.c index f095c7d601..531fb0be85 100644 --- a/src/odbc/unittests/rpc.c +++ b/src/odbc/unittests/rpc.c @@ -140,7 +140,7 @@ Test(const char *name) printf("executing SQLFetch...\n"); printf("\t%-30s\n\t%s\n", C(name), dashes); for (nrows=0; CHKFetch("SNo") == SQL_SUCCESS; nrows++) { - const SQLINTEGER icol = 1; + const SQLUSMALLINT icol = 1; char buf[60]; SQLLEN len; CHKGetData( icol diff --git a/src/odbc/unittests/stats.c b/src/odbc/unittests/stats.c index d8f97cc248..0950c75e6c 100644 --- a/src/odbc/unittests/stats.c +++ b/src/odbc/unittests/stats.c @@ -17,7 +17,7 @@ static const char *proc = "stat_proc"; static const char *table = "stat_proc"; static const char *column = "@t"; -#define LEN(x) (x) ? strlen(x) : 0 +#define LEN(x) (x) ? (SQLSMALLINT) strlen(x) : 0 static void TestProc(const char *catalog, const char *type, const char *expected) diff --git a/src/odbc/unittests/tables.c b/src/odbc/unittests/tables.c index cd7eccbc14..236659a648 100644 --- a/src/odbc/unittests/tables.c +++ b/src/odbc/unittests/tables.c @@ -55,16 +55,16 @@ static char expected_type[20] = "SYSTEM TABLE"; static void DoTest(const char *type, int row_returned, int line) { - int table_len = SQL_NULL_DATA; + SQLSMALLINT table_len = SQL_NULL_DATA; char table_buf[80]; int found = 0; -#define LEN(x) (x) ? strlen(x) : SQL_NULL_DATA +#define LEN(x) (x) ? (SQLSMALLINT) strlen(x) : SQL_NULL_DATA if (table) { strcpy(table_buf, table); strcat(table_buf, "garbage"); - table_len = strlen(table); + table_len = LEN(table); } printf("Test type '%s' %s row at line %d\n", type ? type : "", row_returned ? "with" : "without", line); diff --git a/src/odbc/unittests/tvp.c b/src/odbc/unittests/tvp.c index eb2c8954d1..c82d2b2bd1 100644 --- a/src/odbc/unittests/tvp.c +++ b/src/odbc/unittests/tvp.c @@ -61,7 +61,8 @@ get_desc_field(SQLINTEGER desc_type, SQLSMALLINT icol, SQLSMALLINT fDescType, si memset(&buf, 0x5a, sizeof(buf)); ind = 1234; - CHKGetDescField(desc, icol, fDescType, &buf, size, &ind, "S"); + CHKGetDescField(desc, icol, fDescType, &buf, (SQLINTEGER) size, &ind, + "S"); assert(ind == size); return buf; @@ -388,8 +389,8 @@ TestDescriptorValues(void) SQLWCHAR *tableName; SQLLEN numRows; SQLPOINTER ptr; - SQLSMALLINT count, type; - SQLLEN len; + SQLSMALLINT type; + SQLLEN count, len; bool failed = false; tableName = odbc_get_sqlwchar(&odbc_buf, "TVPType"); diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c index 134eefec9f..efe5b52f76 100644 --- a/src/odbc/unittests/utf8.c +++ b/src/odbc/unittests/utf8.c @@ -52,10 +52,13 @@ TestBinding(int minimun) SQLLEN s1_len, s2_len; unsigned int len; - len = minimun ? (strlen(strings_hex[p-strings]) - 2) /4 : 40; + len = minimun ? ((int) strlen(strings_hex[p-strings]) - 2) / 4 + : 40; CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_WCHAR, len, 0, (void *) p[0], 0, &s1_len, "S"); - len = minimun ? (strlen(strings_hex[p+1-strings]) - 2) /4 : 40; + len = minimun + ? ((int) strlen(strings_hex[p+1-strings]) - 2) / 4 + : 40; /* FIXME this with SQL_VARCHAR produce wrong protocol data */ CHKBindParameter(3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_WVARCHAR, len, 0, (void *) p[1], 0, &s2_len, "S"); diff --git a/src/odbc/winsetup.c b/src/odbc/winsetup.c index 8ec5ad4d9a..6a003fee9a 100644 --- a/src/odbc/winsetup.c +++ b/src/odbc/winsetup.c @@ -326,7 +326,7 @@ ConfigDSN(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszAttribut #endif if (result < 0) { DWORD errorcode = GetLastError(); - char buf[1000]; + TCHAR buf[1000]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errorcode, 0, buf, 1000, NULL); } diff --git a/src/replacements/iconv.c b/src/replacements/iconv.c index 132302f0db..98ce157dea 100644 --- a/src/replacements/iconv.c +++ b/src/replacements/iconv.c @@ -76,7 +76,7 @@ static int get_utf8(const unsigned char *p, size_t len, ICONV_CHAR *out) { uint32_t uc, state = UTF8_ACCEPT; - size_t l = 1; + unsigned int l = 1; do { switch (decode_utf8(&state, &uc, *p++)) { @@ -94,7 +94,7 @@ static int put_utf8(unsigned char *buf, size_t buf_len, ICONV_CHAR c) { #define MASK(n) ((0xffffffffu << (n)) & 0xffffffffu) - size_t o_len; + int o_len; if ((c & MASK(7)) == 0) { if (buf_len < 1) @@ -130,7 +130,7 @@ put_utf8(unsigned char *buf, size_t buf_len, ICONV_CHAR c) c >>= 6; } while (--buf_len); *--buf = (0xff00u >> o_len) | c; - return o_len; + return (int) o_len; } static int diff --git a/src/tds/bulk.c b/src/tds/bulk.c index 447ed3329d..7080380913 100644 --- a/src/tds/bulk.c +++ b/src/tds/bulk.c @@ -507,7 +507,7 @@ tds5_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, return rc; /* unknown but zero */ tds_put_smallint(tds, 0); - tds_put_byte(tds, bindcol->on_server.column_type); + TDS_PUT_BYTE(tds, bindcol->on_server.column_type); tds_put_byte(tds, 0xff - bcpinfo->blob_cols); /* * offset of txptr we stashed during variable @@ -733,7 +733,7 @@ tds5_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_ * Is this column of "variable" type, i.e. NULLable * or naturally variable length e.g. VARCHAR */ - if (bcpinfo->sybase_count > i) { + if (bcpinfo->sybase_count > (TDS_INT) i) { if (bcpinfo->sybase_colinfo[i].offset >= 0) continue; } else { @@ -907,7 +907,7 @@ tds7_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo) else tds_put_smallint(tds, bcpcol->column_usertype); tds_put_smallint(tds, bcpcol->column_flags); - tds_put_byte(tds, bcpcol->on_server.column_type); + TDS_PUT_BYTE(tds, bcpcol->on_server.column_type); assert(bcpcol->funcs); bcpcol->funcs->put_info(tds, bcpcol); diff --git a/src/tds/config.c b/src/tds/config.c index 30b96c5353..08f8dc326e 100644 --- a/src/tds/config.c +++ b/src/tds/config.c @@ -618,8 +618,9 @@ tds_parse_conf_section(const char *option, const char *value, void *param) char *end; long flags; flags = strtol(value, &end, 0); - if (*value != '\0' && *end == '\0' && flags != LONG_MIN && flags != LONG_MAX) - login->debug_flags = flags; + if (*value != '\0' && *end == '\0' && flags > INT_MIN + && flags < INT_MAX) + login->debug_flags = (int) flags; } else if (!strcmp(option, TDS_STR_TIMEOUT) || !strcmp(option, TDS_STR_QUERY_TIMEOUT)) { if (atoi(value)) login->query_timeout = atoi(value); diff --git a/src/tds/convert.c b/src/tds/convert.c index 9ca8b42c5c..7c3f4fd6e4 100644 --- a/src/tds/convert.c +++ b/src/tds/convert.c @@ -301,10 +301,11 @@ tds_convert_binary(const TDS_UCHAR * src, TDS_INT srclen, int desttype, CONV_RES return TDS_CONVERT_NOAVAIL; } -TDS_INT -tds_char2hex(TDS_CHAR *dest, TDS_UINT destlen, const TDS_CHAR * src, TDS_UINT srclen) +ssize_t +tds_char2hex(TDS_CHAR *dest, size_t destlen, + const TDS_CHAR * src, size_t srclen) { - unsigned int i; + size_t i; unsigned char hex1, c = 0; /* if srclen if odd we must add a "0" before ... */ @@ -1118,7 +1119,7 @@ tds_convert_money4(const TDSCONTEXT * tds_ctx, const TDS_MONEY4 * src, int destt dollars = mny.mny4 / 10000; if (!IS_UINT(dollars)) return TDS_CONVERT_OVERFLOW; - cr->ui = dollars; + cr->ui = (TDS_UINT) dollars; return sizeof(TDS_UINT); break; case SYBINT8: @@ -1507,7 +1508,7 @@ tds_convert_bigdatetime(const TDSCONTEXT * tds_ctx, const TDS_BIGDATETIME * bigd dta.time = bdt % (UINT64_C(86400) * 1000000u) * 10u; bdt /= UINT64_C(86400) * 1000000u; dta.has_date = 1; - dta.date = bdt - BIGDATETIME_BIAS; + dta.date = (TDS_INT) (bdt - BIGDATETIME_BIAS); return tds_convert_datetimeall(tds_ctx, SYBMSDATETIME2, &dta, desttype, cr); } @@ -1869,7 +1870,10 @@ tds_convert_to_binary(int srctype, const TDS_CHAR * src, TDS_UINT srclen, int de test_alloc(cr->ib); ib = cr->ib; } - return tds_char2hex(ib, desttype == TDS_CONVERT_BINARY ? cr->cb.len : 0xffffffffu, src, srclen); + return (TDS_INT) tds_char2hex(ib, + desttype == TDS_CONVERT_BINARY + ? cr->cb.len : 0xffffffffu, + src, srclen); default: return TDS_CONVERT_NOAVAIL; @@ -3248,7 +3252,7 @@ tds_datecrack(TDS_INT datetype, const void *di, TDSDATEREC * dr) secs = bigdatetime % 60u; bigdatetime /= 60u; dt_time = bigdatetime % (24u*60u); - dt_days = bigdatetime / (24u*60u) - BIGDATETIME_BIAS; + dt_days = (int) (bigdatetime / (24u*60u) - BIGDATETIME_BIAS); } else { return TDS_FAIL; } diff --git a/src/tds/data.c b/src/tds/data.c index 7239ff4558..86aedbeaf3 100644 --- a/src/tds/data.c +++ b/src/tds/data.c @@ -514,7 +514,7 @@ tds_varmax_stream_read(TDSINSTREAM *stream, void *ptr, size_t len) /* read part of data */ if (len > s->chunk_left) len = s->chunk_left; - s->chunk_left -= len; + s->chunk_left -= (TDS_INT) len; if (tds_get_n(s->tds, ptr, len)) return len; return -1; @@ -796,7 +796,7 @@ tds_generic_get(TDSSOCKET * tds, TDSCOLUMN * curcol) dest = curcol->column_data; if (is_blob_col(curcol)) { TDSDATAINSTREAM r; - size_t allocated; + int allocated; TDSRET ret; blob = (TDSBLOB *) dest; /* cf. column_varint_size case 4, above */ @@ -901,13 +901,13 @@ tds_generic_put_info(TDSSOCKET * tds, TDSCOLUMN * col) && is_char_type(col->column_type)) { size = 255; } - tds_put_byte(tds, size); + TDS_PUT_BYTE(tds, size); break; case 2: - tds_put_smallint(tds, size); + TDS_PUT_SMALLINT(tds, size); break; case 4: - tds_put_int(tds, size); + TDS_PUT_INT(tds, size); break; case 8: tds_put_smallint(tds, 0xffff); @@ -1042,15 +1042,15 @@ tds_generic_put(TDSSOCKET * tds, TDSCOLUMN * curcol, int bcp7) tds_put_n(tds, textptr, 16); tds_put_n(tds, textptr, 8); } - tds_put_int(tds, colsize); + TDS_PUT_INT(tds, colsize); break; case 2: colsize = MIN(colsize, size); - tds_put_smallint(tds, colsize); + TDS_PUT_SMALLINT(tds, colsize); break; case 1: colsize = MIN(colsize, size); - tds_put_byte(tds, colsize); + TDS_PUT_BYTE(tds, colsize); break; case 0: /* TODO should be column_size */ @@ -1091,7 +1091,7 @@ tds_generic_put(TDSSOCKET * tds, TDSCOLUMN * curcol, int bcp7) case 4: if ( !is_blob_col(curcol) ) { colsize = MAX(MIN(colsize, 0x7fffffff), 1); - tds_put_int(tds, colsize); + TDS_PUT_INT(tds, colsize); break; } /* It's a BLOB... */ @@ -1099,11 +1099,11 @@ tds_generic_put(TDSSOCKET * tds, TDSCOLUMN * curcol, int bcp7) tds_put_n(tds, blob->textptr, 16); tds_put_n(tds, blob->timestamp, 8); colsize = MIN(colsize, 0x7fffffff); - tds_put_int(tds, colsize); + TDS_PUT_INT(tds, colsize); break; case 2: colsize = MIN(colsize, 8000); - tds_put_smallint(tds, colsize); + TDS_PUT_SMALLINT(tds, colsize); break; case 1: if (!colsize) { @@ -1117,7 +1117,7 @@ tds_generic_put(TDSSOCKET * tds, TDSCOLUMN * curcol, int bcp7) return TDS_SUCCESS; } colsize = MIN(colsize, 255); - tds_put_byte(tds, colsize); + TDS_PUT_BYTE(tds, colsize); break; case 0: /* TODO should be column_size */ @@ -1393,7 +1393,7 @@ tds_msdatetime_put(TDSSOCKET *tds, TDSCOLUMN *col, int bcp7 TDS_UNUSED) TDS_PUT_UA2LE(p, dta->offset); p += 2; } - buf[0] = p - buf - 1; + buf[0] = (unsigned char) (p - buf - 1); tds_put_n(tds, buf, p - buf); return TDS_SUCCESS; @@ -1527,7 +1527,7 @@ tds_mstabletype_put_info(TDSSOCKET *tds, TDSCOLUMN *col) { TDS_TVP *table = (TDS_TVP *) col->column_data; TDSFREEZE current_freeze[1]; - size_t written; + unsigned int written; /* TVP_TYPENAME */ tds_put_byte(tds, 0); /* Empty DB name */ diff --git a/src/tds/gssapi.c b/src/tds/gssapi.c index f4c018bf35..9611e3c02f 100644 --- a/src/tds/gssapi.c +++ b/src/tds/gssapi.c @@ -459,7 +459,7 @@ tds_gss_continue(TDSSOCKET * tds, struct tds_gss_auth *auth, gss_buffer_desc *to } auth->tds_auth.packet = (uint8_t *) send_tok.value; - auth->tds_auth.packet_len = send_tok.length; + auth->tds_auth.packet_len = (int) send_tok.length; return TDS_SUCCESS; } diff --git a/src/tds/login.c b/src/tds/login.c index 8b5d9cd775..bca92dfa82 100644 --- a/src/tds/login.c +++ b/src/tds/login.c @@ -417,7 +417,7 @@ tds_setup_connection(TDSSOCKET *tds, TDSLOGIN *login, bool set_db, bool set_spid { TDSRET erc; char *str; - int len; + size_t len; bool parse_results = false; len = 192 + tds_quote_id(tds, NULL, tds_dstr_cstr(&login->database),-1); @@ -971,7 +971,7 @@ tds7_send_login(TDSSOCKET * tds, const TDSLOGIN * login) TDS_INT time_zone = -120; TDS_INT tds7version = tds70Version; - TDS_INT block_size = 4096; + unsigned int block_size = 4096; unsigned char option_flag1 = TDS_SET_LANG_ON | TDS_USE_DB_NOTIFY | TDS_INIT_DB_FATAL; unsigned char option_flag2 = login->option_flag2; @@ -988,9 +988,9 @@ tds7_send_login(TDSSOCKET * tds, const TDSLOGIN * login) const char *user_name = tds_dstr_cstr(&login->user_name); unsigned char *pwd; - /* FIXME: These are defined as size_t, but should be TDS_SMALLINT. */ + /* FIXME: These should be TDS_SMALLINT. */ size_t user_name_len = strlen(user_name); - size_t auth_len = 0; + unsigned int auth_len = 0; static const char ext_data[] = "\x0a\x01\x00\x00\x00\x01" /* Enable UTF-8 */ @@ -1014,7 +1014,7 @@ tds7_send_login(TDSSOCKET * tds, const TDSLOGIN * login) }; struct { const void *ptr; - unsigned pos, len, limit; + size_t pos, len, limit; } data_fields[NUM_DATA_FIELDS], *field; tds->out_flag = TDS7_LOGIN; @@ -1277,7 +1277,7 @@ tds71_do_login(TDSSOCKET * tds, TDSLOGIN* login) { int i, pkt_len; const char *instance_name = tds_dstr_isempty(&login->instance_name) ? "MSSQLServer" : tds_dstr_cstr(&login->instance_name); - int instance_name_len = strlen(instance_name) + 1; + TDS_USMALLINT instance_name_len = strlen(instance_name) + 1; TDS_CHAR crypt_flag; unsigned int start_pos = 21; TDSRET ret; diff --git a/src/tds/mem.c b/src/tds/mem.c index 227ff6dcb8..e76b4b2528 100644 --- a/src/tds/mem.c +++ b/src/tds/mem.c @@ -883,7 +883,8 @@ tds_init_login(TDSLOGIN *login, TDSLOCALE * locale) } TDSCURSOR * -tds_alloc_cursor(TDSSOCKET *tds, const char *name, TDS_INT namelen, const char *query, TDS_INT querylen) +tds_alloc_cursor(TDSSOCKET *tds, const char *name, size_t namelen, + const char *query, size_t querylen) { TDSCURSOR *cursor; TDSCURSOR *pcursor; @@ -1344,7 +1345,7 @@ tds_alloc_socket(TDSCONTEXT * context, unsigned int bufsize) #endif /* !ENABLE_ODBC_MARS */ TDSSOCKET * -tds_realloc_socket(TDSSOCKET * tds, size_t bufsize) +tds_realloc_socket(TDSSOCKET * tds, unsigned int bufsize) { TDSPACKET *packet; #if ENABLE_ODBC_MARS diff --git a/src/tds/net.c b/src/tds/net.c index e9b4ba7fe9..937ae6d53d 100644 --- a/src/tds/net.c +++ b/src/tds/net.c @@ -728,10 +728,12 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds) * @TODO remove tds, save error somewhere, report error in another way * @returns 0 if blocking, <0 error >0 bytes read */ -static int -tds_socket_read(TDSCONNECTION * conn, TDSSOCKET *tds, unsigned char *buf, int buflen) +static ssize_t +tds_socket_read(TDSCONNECTION * conn, TDSSOCKET *tds, unsigned char *buf, + size_t buflen) { - int len, err; + ssize_t len; + int err; #if ENABLE_EXTRA_CHECKS /* this simulate the fact that recv can return less bytes */ @@ -763,10 +765,12 @@ tds_socket_read(TDSCONNECTION * conn, TDSSOCKET *tds, unsigned char *buf, int bu * Write to an OS socket * @returns 0 if blocking, <0 error >0 bytes readed */ -static int -tds_socket_write(TDSCONNECTION *conn, TDSSOCKET *tds, const unsigned char *buf, int buflen) +static ssize_t +tds_socket_write(TDSCONNECTION *conn, TDSSOCKET *tds, const unsigned char *buf, + size_t buflen) { - int err, len; + int err; + ssize_t len; char *errstr; #if ENABLE_EXTRA_CHECKS @@ -860,7 +864,7 @@ tds_wakeup_send(TDSPOLLWAKEUP *wakeup, char cancel) static int tds_connection_signaled(TDSCONNECTION *conn) { - int len; + ssize_t len; char to_cancel[16]; #if defined(__linux__) && HAVE_EVENTFD @@ -917,14 +921,15 @@ tds_check_cancel(TDSCONNECTION *conn) * Loops until we have received some characters * return -1 on failure */ -int -tds_goodread(TDSSOCKET * tds, unsigned char *buf, int buflen) +ssize_t +tds_goodread(TDSSOCKET * tds, unsigned char *buf, size_t buflen) { if (tds == NULL || buf == NULL || buflen < 1) return -1; for (;;) { - int len, err; + ssize_t len; + int err; /* FIXME this block writing from other sessions */ len = tds_select(tds, TDSSELREAD, tds->query_timeout); @@ -966,8 +971,8 @@ tds_goodread(TDSSOCKET * tds, unsigned char *buf, int buflen) } } -int -tds_connection_read(TDSSOCKET * tds, unsigned char *buf, int buflen) +ssize_t +tds_connection_read(TDSSOCKET * tds, unsigned char *buf, size_t buflen) { TDSCONNECTION *conn = tds->conn; @@ -988,10 +993,10 @@ tds_connection_read(TDSSOCKET * tds, unsigned char *buf, int buflen) * \param last 1 if this is the last packet, else 0 * \return length written (>0), <0 on failure */ -int +ssize_t tds_goodwrite(TDSSOCKET * tds, const unsigned char *buffer, size_t buflen) { - int len; + ssize_t len; size_t sent = 0; assert(tds && buffer); @@ -1053,10 +1058,11 @@ tds_socket_flush(TDS_SYS_SOCKET sock TDS_UNUSED) #endif } -int -tds_connection_write(TDSSOCKET *tds, const unsigned char *buf, int buflen, int final) +ssize_t +tds_connection_write(TDSSOCKET *tds, const unsigned char *buf, size_t buflen, + int final) { - int sent; + ssize_t sent; TDSCONNECTION *conn = tds->conn; #if !defined(_WIN32) && !defined(MSG_NOSIGNAL) && !defined(DOS32X) && !defined(SO_NOSIGPIPE) @@ -1102,7 +1108,7 @@ tds7_get_instance_ports(FILE *output, struct addrinfo *addr) int retval; TDS_SYS_SOCKET s; char msg[16*1024]; - int msg_len = 0; + ssize_t msg_len = 0; int port = 0; char ipaddr[128]; @@ -1238,7 +1244,7 @@ tds7_get_instance_port(struct addrinfo *addr, const char *instance) int retval; TDS_SYS_SOCKET s; char msg[1024]; - int msg_len; + ssize_t msg_len; int port = 0; char ipaddr[128]; @@ -1355,7 +1361,7 @@ tds7_get_instance_port(struct addrinfo *addr, const char *instance) } } if (port_ok && instance_ok) { - port = l; + port = (int) l; break; } } diff --git a/src/tds/packet.c b/src/tds/packet.c index e257adfca9..fb32ae0410 100644 --- a/src/tds/packet.c +++ b/src/tds/packet.c @@ -599,7 +599,7 @@ tds_read_packet(TDSSOCKET * tds) tds->in_len = 0; tds->in_pos = 0; for (p = pkt, end = p+8; p < end;) { - int len = tds_connection_read(tds, p, end - p); + ssize_t len = tds_connection_read(tds, p, end - p); if (len <= 0) { tds_close_socket(tds); return -1; @@ -632,7 +632,7 @@ tds_read_packet(TDSSOCKET * tds) tds->in_flag = pkt[0]; /* Set the length and pos (not sure what pos is used for now */ - tds->in_len = p - pkt; + tds->in_len = (unsigned int) (p - pkt); tds->in_pos = 8; tdsdump_dump_buf(TDS_DBG_NETWORK, "Received packet", tds->in_buf, tds->in_len); @@ -815,7 +815,7 @@ int tds_put_cancel(TDSSOCKET * tds) { unsigned char out_buf[8]; - int sent; + ssize_t sent; out_buf[0] = TDS_CANCEL; /* out_flag */ out_buf[1] = 1; /* final */ @@ -931,12 +931,12 @@ tds_freeze(TDSSOCKET *tds, TDSFREEZE *freeze, unsigned size_len) * * @return bytes written since ::tds_freeze call */ -size_t +unsigned int tds_freeze_written(TDSFREEZE *freeze) { TDSSOCKET *tds = freeze->tds; TDSPACKET *pkt = freeze->pkt; - size_t size; + unsigned int size; CHECK_FREEZE_EXTRA(freeze); diff --git a/src/tds/query.c b/src/tds/query.c index b222ec44e4..e1e8cb9661 100644 --- a/src/tds/query.c +++ b/src/tds/query.c @@ -123,7 +123,8 @@ tds_ascii_to_ucs2(char *buffer, const char *buf) * \return string allocated (or input pointer if no conversion required) or NULL if error */ const char * -tds_convert_string(TDSSOCKET * tds, TDSICONV * char_conv, const char *s, int len, size_t *out_len) +tds_convert_string(TDSSOCKET * tds, TDSICONV * char_conv, const char *s, + ssize_t len, size_t *out_len) { char *buf; @@ -399,7 +400,9 @@ tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * param TDSFREEZE outer; TDSRET rc; - converted_query = tds_convert_string(tds, tds->conn->char_convs[client2ucs2], query, (int)query_len, &converted_query_len); + converted_query = tds_convert_string + (tds, tds->conn->char_convs[client2ucs2], + query, query_len, &converted_query_len); if (!converted_query) { tds_set_state(tds, TDS_IDLE); return TDS_FAIL; @@ -745,7 +748,7 @@ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out) CHECK_TDS_EXTRA(tds); CHECK_COLUMN_EXTRA(curcol); - size = tds_fix_column_size(tds, curcol); + size = (unsigned int) tds_fix_column_size(tds, curcol); switch (tds_get_conversion_type(curcol->on_server.column_type, curcol->on_server.column_size)) { case XSYBCHAR: @@ -954,7 +957,7 @@ tds7_write_param_def_from_query(TDSSOCKET * tds, const char* converted_query, si { char declaration[128], *p; int i, count; - size_t written; + unsigned int written; TDSFREEZE outer, inner; assert(IS_TDS7_PLUS(tds->conn)); @@ -1020,7 +1023,7 @@ tds7_write_param_def_from_params(TDSSOCKET * tds, const char* query, size_t quer size_t len; } *ids = NULL; TDSFREEZE outer, inner; - size_t written; + unsigned int written; assert(IS_TDS7_PLUS(tds->conn)); @@ -1077,8 +1080,9 @@ tds7_write_param_def_from_params(TDSSOCKET * tds, const char* query, size_t quer if (ids[i].p) { tds_put_n(tds, ids[i].p, ids[i].len); } else { - tds_put_string(tds, tds_dstr_cstr(¶ms->columns[i]->column_name), - tds_dstr_len(¶ms->columns[i]->column_name)); + const DSTR *name = ¶ms->columns[i]->column_name; + tds_put_string(tds, tds_dstr_cstr(name), + (int) tds_dstr_len(name)); } tds_put_smallint(tds, ' '); @@ -1308,7 +1312,7 @@ tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params, size_t query_len; TDSCOLUMN *param; TDSDYNAMIC *dyn; - size_t id_len; + unsigned int id_len; TDSFREEZE outer; CHECK_TDS_EXTRA(tds); @@ -1415,7 +1419,7 @@ tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params, tds->out_flag = TDS_NORMAL; - id_len = strlen(dyn->id); + id_len = (unsigned int) strlen(dyn->id); tds_put_byte(tds, TDS5_DYNAMIC_TOKEN); tds_freeze(tds, &outer, 2); tds_put_byte(tds, TDS_DYN_EXEC_IMMED); @@ -1592,12 +1596,12 @@ tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags) CHECK_COLUMN_EXTRA(curcol); if (flags & TDS_PUT_DATA_USE_NAME) { - len = tds_dstr_len(&curcol->column_name); + len = (int) tds_dstr_len(&curcol->column_name); tdsdump_log(TDS_DBG_ERROR, "tds_put_data_info putting param_name \n"); if (IS_TDS7_PLUS(tds->conn)) { TDSFREEZE outer; - size_t written; + unsigned int written; tds_freeze(tds, &outer, 1); if ((flags & TDS_PUT_DATA_PREFIX_NAME) != 0) @@ -1626,7 +1630,7 @@ tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags) tds_put_byte(tds, curcol->column_output); /* status (input) */ if (!IS_TDS7_PLUS(tds->conn)) tds_put_int(tds, curcol->column_usertype); /* usertype */ - tds_put_byte(tds, curcol->on_server.column_type); + TDS_PUT_BYTE(tds, curcol->on_server.column_type); if (curcol->funcs->put_info(tds, curcol) != TDS_SUCCESS) return TDS_FAIL; @@ -1957,7 +1961,8 @@ tds4_send_emulated_rpc(TDSSOCKET * tds, const char *rpc_name, TDSPARAMINFO * par param = params->columns[i]; tds_put_string(tds, sep, -1); if (!tds_dstr_isempty(¶m->column_name)) { - tds_put_string(tds, tds_dstr_cstr(¶m->column_name), tds_dstr_len(¶m->column_name)); + tds_put_string(tds, tds_dstr_cstr(¶m->column_name), + (int)tds_dstr_len(¶m->column_name)); tds_put_string(tds, "=", 1); } if (param->column_output) { @@ -2002,7 +2007,7 @@ tds_submit_rpc(TDSSOCKET * tds, const char *rpc_name, TDSPARAMINFO * params, TDS rpc_name_len = (int)strlen(rpc_name); if (IS_TDS7_PLUS(tds->conn)) { TDSFREEZE outer; - size_t written; + unsigned int written; if (tds_start_query_head(tds, TDS_RPC, head) != TDS_SUCCESS) return TDS_FAIL; @@ -2219,7 +2224,7 @@ tds_quote(char *buffer, char quoting, const char *id, size_t len) * \see tds_quote_id_rpc */ size_t -tds_quote_id(TDSSOCKET * tds, char *buffer, const char *id, int idlen) +tds_quote_id(TDSSOCKET * tds, char *buffer, const char *id, ssize_t idlen) { size_t i, len; @@ -2264,7 +2269,7 @@ tds_quote_id(TDSSOCKET * tds, char *buffer, const char *id, int idlen) * \see tds_quote_id */ size_t -tds_quote_id_rpc(TDSSOCKET * tds, char *buffer, const char *id, int idlen) +tds_quote_id_rpc(TDSSOCKET * tds, char *buffer, const char *id, ssize_t idlen) { size_t len; /* We are quoting for RPC calls, not base language queries. For RPC calls Sybase @@ -2289,7 +2294,8 @@ tds_quote_id_rpc(TDSSOCKET * tds, char *buffer, const char *id, int idlen) * \result written chars (not including needed terminator) */ size_t -tds_quote_string(TDSSOCKET * tds TDS_UNUSED, char *buffer, const char *str, int len) +tds_quote_string(TDSSOCKET * tds TDS_UNUSED, char *buffer, const char *str, + ssize_t len) { return tds_quote(buffer, '\'', str, len < 0 ? strlen(str) : (size_t) len); } @@ -2397,8 +2403,9 @@ tds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, bool TDSRET rc = TDS_SUCCESS; /* cursor statement */ - converted_query = tds_convert_string(tds, tds->conn->char_convs[client2ucs2], - cursor->query, (int)strlen(cursor->query), &converted_query_len); + converted_query = tds_convert_string + (tds, tds->conn->char_convs[client2ucs2], cursor->query, + strlen(cursor->query), &converted_query_len); if (!converted_query) { if (!*something_to_send) tds_set_state(tds, TDS_IDLE); @@ -2859,7 +2866,7 @@ TDSRET tds_cursor_setname(TDSSOCKET * tds, TDSCURSOR * cursor) { TDSFREEZE outer; - size_t written; + unsigned int written; CHECK_TDS_EXTRA(tds); @@ -2992,7 +2999,7 @@ tds_cursor_update(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_OPERATION op, unsigned int n, num_params; const char *table_name = NULL; TDSFREEZE outer; - size_t written; + unsigned int written; /* empty table name */ tds_put_byte(tds, 0); diff --git a/src/tds/read.c b/src/tds/read.c index ed1da12ab7..99e31f6956 100644 --- a/src/tds/read.c +++ b/src/tds/read.c @@ -210,7 +210,9 @@ tds_get_char_data(TDSSOCKET * tds, char *row_buffer, size_t wire_size, TDSCOLUMN } in_left = curcol->column_size; - curcol->column_cur_size = read_and_convert(tds, curcol->char_conv, &wire_size, row_buffer, in_left); + curcol->column_cur_size + = (TDS_INT) read_and_convert(tds, curcol->char_conv, &wire_size, + row_buffer, in_left); if (TDS_UNLIKELY(wire_size > 0)) { tds_get_n(tds, NULL, wire_size); tdsdump_log(TDS_DBG_NETWORK, "error: tds_get_char_data: discarded %u on wire while reading %d into client. \n", @@ -252,7 +254,7 @@ tds_get_n(TDSSOCKET * tds, void *dest, size_t need) if (dest != NULL) { memcpy((char *) dest, tds->in_buf + tds->in_pos, need); } - tds->in_pos += need; + tds->in_pos += (unsigned int) need; } return true; } diff --git a/src/tds/sspi.c b/src/tds/sspi.c index b1e5ddc302..e3196022d0 100644 --- a/src/tds/sspi.c +++ b/src/tds/sspi.c @@ -279,12 +279,12 @@ tds_sspi_get_auth(TDSSOCKET * tds) #else identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; #endif - identity.Password = (void *) passwd; + identity.Password = (_TUCHAR *) passwd; identity.PasswordLength = (unsigned long) _tcslen(passwd); - identity.Domain = (void *) user_name; + identity.Domain = (_TUCHAR *) user_name; identity.DomainLength = (unsigned long) (p - user_name); user_name = p + 1; - identity.User = (void *) user_name; + identity.User = (_TUCHAR *) user_name; identity.UserLength = (unsigned long) _tcslen(user_name); } diff --git a/src/tds/tds_checks.c b/src/tds/tds_checks.c index c53471c69e..b9b14b287c 100644 --- a/src/tds/tds_checks.c +++ b/src/tds/tds_checks.c @@ -53,7 +53,7 @@ void tds_check_tds_extra(const TDSSOCKET * tds) { const int invalid_state = 0; - int i; + TDS_UINT i; TDSDYNAMIC *cur_dyn = NULL; TDSCURSOR *cur_cursor = NULL; diff --git a/src/tds/token.c b/src/tds/token.c index f72b460387..54dac9072a 100644 --- a/src/tds/token.c +++ b/src/tds/token.c @@ -2629,7 +2629,8 @@ tds_process_dynamic(TDSSOCKET * tds) drain = id_len - TDS_MAX_DYNID_LEN; id_len = TDS_MAX_DYNID_LEN; } - id_len = tds_get_string(tds, id_len, id, TDS_MAX_DYNID_LEN); + id_len = (TDS_TINYINT) tds_get_string(tds, id_len, id, + TDS_MAX_DYNID_LEN); id[id_len] = '\0'; if (drain) { tds_get_n(tds, NULL, drain); diff --git a/src/tds/unittests/allcolumns.c b/src/tds/unittests/allcolumns.c index 49d0f8b4f2..5fdba1bfb4 100644 --- a/src/tds/unittests/allcolumns.c +++ b/src/tds/unittests/allcolumns.c @@ -232,7 +232,7 @@ static void create_type(TDSSOCKET *tds, int desttype, int server_type, tds_any_t break; } assert(src); - srclen = strlen(src); + srclen = (TDS_UINT) strlen(src); /* * Now at last do the conversion diff --git a/src/tds/unittests/charconv.c b/src/tds/unittests/charconv.c index 3d85a1f7ae..d78856310f 100644 --- a/src/tds/unittests/charconv.c +++ b/src/tds/unittests/charconv.c @@ -102,9 +102,9 @@ add_odd(char *buf, int *pos, enum Odd type) return 0; case ODD_NORMAL: - buf[*pos] = 0xC0 + (x >> 6); + buf[*pos] = (char) (0xC0 + (x >> 6)); ++*pos; - buf[*pos] = 0x80 + (x & 0x3f); + buf[*pos] = (char) (0x80 + (x & 0x3f)); ++*pos; return 0; diff --git a/src/tds/unittests/convert.c b/src/tds/unittests/convert.c index 7f6c81d093..b39382a3bb 100644 --- a/src/tds/unittests/convert.c +++ b/src/tds/unittests/convert.c @@ -224,7 +224,7 @@ main(int argc, char **argv) break; } assert(src); - srclen = strlen(src); + srclen = (TDS_UINT) strlen(src); break; case SYBINT1: case SYBUINT1: diff --git a/src/tds/unittests/convert_bounds.c b/src/tds/unittests/convert_bounds.c index e68991beae..0d5535a721 100644 --- a/src/tds/unittests/convert_bounds.c +++ b/src/tds/unittests/convert_bounds.c @@ -216,7 +216,8 @@ is_valid(const char *num, int type, CONV_RESULT *cr) if (!cr) cr = &dummy_cr; - return convert_and_free(SYBVARCHAR, num, strlen(num), type, cr) >= 0; + return convert_and_free(SYBVARCHAR, num, (TDS_UINT) strlen(num), type, + cr) >= 0; } /* convert multiple precision to a floating number of a specific type */ diff --git a/src/tds/unittests/corrupt.c b/src/tds/unittests/corrupt.c index 03d325db66..f6c476e600 100644 --- a/src/tds/unittests/corrupt.c +++ b/src/tds/unittests/corrupt.c @@ -56,7 +56,7 @@ unfinished_query_test(TDSSOCKET *tds) memset(strchr(buf, 0), 0, 16); /* convert if needed */ - len = strlen(buf); + len = (int) strlen(buf); for (i = len; --i >= 0; ) { char c = buf[i]; buf[i * char_len + 0] = c; diff --git a/src/tds/unittests/freeze.c b/src/tds/unittests/freeze.c index 56fd4bbbd3..e12595e1e0 100644 --- a/src/tds/unittests/freeze.c +++ b/src/tds/unittests/freeze.c @@ -195,8 +195,7 @@ static void test1(void) { TDSFREEZE outer, inner; - size_t written; - unsigned left; + unsigned written, left; /* just to not start at 0 */ append("test", 4); diff --git a/src/tds/unittests/iconv_fread.c b/src/tds/unittests/iconv_fread.c index f2374383b9..63b451330f 100644 --- a/src/tds/unittests/iconv_fread.c +++ b/src/tds/unittests/iconv_fread.c @@ -84,8 +84,8 @@ main(void) return 1; } memset(buf, 'a', i); - buf[i] = 0xC0 + (x >> 6); - buf[i+1] = 0x80 + (x & 0x3f); + buf[i] = (char) (0xC0 + (x >> 6)); + buf[i+1] = (char) (0x80 + (x & 0x3f)); buf[i+2] = '!'; buf[i+3] = '!'; diff --git a/src/tds/unittests/t0007.c b/src/tds/unittests/t0007.c index 8902aa32e6..4c990ea222 100644 --- a/src/tds/unittests/t0007.c +++ b/src/tds/unittests/t0007.c @@ -399,9 +399,13 @@ main(void) /* try conversion from char (already tested above) */ cr_src.n.precision = 20; cr_src.n.scale = 0; - len_src = tds_convert(&ctx, SYBVARCHAR, *value, strlen(*value), *type1, &cr_src); + len_src = tds_convert(&ctx, SYBVARCHAR, *value, + (TDS_UINT) strlen(*value), *type1, + &cr_src); cr_dst.n.precision = 20; cr_dst.n.scale = 0; - len_dst = tds_convert(&ctx, SYBVARCHAR, *value, strlen(*value), *type2, &cr_dst); + len_dst = tds_convert(&ctx, SYBVARCHAR, *value, + (TDS_UINT) strlen(*value), *type2, + &cr_dst); if (len_src <= 0 || len_dst <= 0) continue; cr_dst.n.precision = 20; cr_dst.n.scale = 0; diff --git a/src/tds/unittests/t0008.c b/src/tds/unittests/t0008.c index f326053b0f..85f2374802 100644 --- a/src/tds/unittests/t0008.c +++ b/src/tds/unittests/t0008.c @@ -45,7 +45,9 @@ test(const char *src, const char *intro, const char *cont, int prec, int scale, memset(&cr.n, 0, sizeof(cr.n)); cr.n.precision = prec; cr.n.scale = scale; - if (tds_convert(&ctx, SYBVARCHAR, src, strlen(src), SYBNUMERIC, &cr) < 0) + if (tds_convert(&ctx, SYBVARCHAR, src, (TDS_UINT) strlen(src), + SYBNUMERIC, &cr) + < 0) strcpy(buf, "error"); else { sprintf(buf, "prec=%d scale=%d", cr.n.precision, cr.n.scale); diff --git a/src/tds/unittests/utf8_1.c b/src/tds/unittests/utf8_1.c index da9bd0e0ce..b635077031 100644 --- a/src/tds/unittests/utf8_1.c +++ b/src/tds/unittests/utf8_1.c @@ -197,7 +197,7 @@ main(void) if (IS_TDS7_PLUS(tds->conn)) { char type[32]; char buf[1024]; - int i, len; + size_t i, len; strcpy(buf, "aaa"); len = 0; diff --git a/src/tds/vstrbuild.c b/src/tds/vstrbuild.c index 32274e941d..00561bc9c6 100644 --- a/src/tds/vstrbuild.c +++ b/src/tds/vstrbuild.c @@ -45,7 +45,7 @@ struct string_linked_list */ static char * -norm_fmt(const char *fmt, int fmtlen) +norm_fmt(const char *fmt, ssize_t fmtlen) { char *newfmt; char *cp; diff --git a/src/tds/write.c b/src/tds/write.c index 7cc4a041a8..0b2fffeb1a 100644 --- a/src/tds/write.c +++ b/src/tds/write.c @@ -141,7 +141,7 @@ tds_put_string(TDSSOCKET * tds, const char *s, int len) tds_dataout_stream_init(&w, tds); res = tds_convert_stream(tds, tds->conn->char_convs[iconv_entry], to_server, &r.stream, &w.stream); - return w.written; + return (int) w.written; } int diff --git a/src/utils/des.c b/src/utils/des.c index f1520bf142..f53339269a 100644 --- a/src/utils/des.c +++ b/src/utils/des.c @@ -623,9 +623,10 @@ spinit(DES_KEY * key) /* ECB MODE */ int -tds_des_ecb_encrypt(const void *plaintext, int len, DES_KEY * akey, unsigned char *output) +tds_des_ecb_encrypt(const void *plaintext, size_t len, DES_KEY * akey, + unsigned char *output) { - int j; + size_t j; const unsigned char *plain = (const unsigned char *) plaintext; for (j = 0; j < len / 8; j++) { From 0ec213be3cd3e1572886d06ae45d7968112a6da5 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Tue, 21 May 2024 14:46:04 -0400 Subject: [PATCH 46/49] Comment out or fully retire unread variables. All could at least potentially receive updates, but they were never consulted or even logged. Leave some commented out rather than fully retired for ease of reinstatement if they're helpful to examine in a debugger. --- src/dblib/bcp.c | 3 +-- src/dblib/unittests/numeric.c | 3 +-- src/dblib/unittests/timeout.c | 4 ++-- src/odbc/unittests/testodbc.c | 8 ++++---- src/tds/read.c | 3 +-- src/tds/unittests/t0006.c | 6 +++--- src/tds/unittests/utf8_1.c | 4 ++-- src/tds/unittests/utf8_3.c | 6 +++--- src/tds/write.c | 4 ++-- 9 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c index d4a18f2893..125cdb5eae 100644 --- a/src/dblib/bcp.c +++ b/src/dblib/bcp.c @@ -1686,7 +1686,6 @@ bcp_readfmt(DBPROCESS * dbproc, const char filename[]) BCP_HOSTCOLINFO hostcol[1]; FILE *ffile; char buffer[1024]; - float lf_version = 0.0; int li_numcols = 0; int colinfo_count = 0; @@ -1703,7 +1702,7 @@ bcp_readfmt(DBPROCESS * dbproc, const char filename[]) } if ((_bcp_fgets(buffer, sizeof(buffer), ffile)) != NULL) { - lf_version = (float)atof(buffer); + /* version (float), ignored */ } else if (ferror(ffile)) { dbperror(dbproc, SYBEBRFF, errno); goto Cleanup; diff --git a/src/dblib/unittests/numeric.c b/src/dblib/unittests/numeric.c index dd32c1a66d..6ebe99860a 100644 --- a/src/dblib/unittests/numeric.c +++ b/src/dblib/unittests/numeric.c @@ -45,7 +45,6 @@ test(int bind_type, const char *bind_name, int override_prec, int override_scale DBNUMERIC *num = NULL, *num2 = NULL; RETCODE ret; DBTYPEINFO ti; - int i; printf("*** Starting test msdblib %d bind %s prec %d scale %d out prec %d out scale %d line %d\n", msdblib, bind_name, override_prec, override_scale, out_prec, out_scale, line); @@ -118,7 +117,7 @@ test(int bind_type, const char *bind_name, int override_prec, int override_scale ret = dbconvert_ps(dbproc, SYBVARCHAR, (const BYTE *) "246.9", -1, SYBDECIMAL, (BYTE *) num2, sizeof(*num2), &ti); chk(ret > 0, "dbconvert_ps"); - for (i=0; (ret = dbresults(dbproc)) != NO_MORE_RESULTS; ++i) { + while ((ret = dbresults(dbproc)) != NO_MORE_RESULTS) { RETCODE row_code; switch (ret) { diff --git a/src/dblib/unittests/timeout.c b/src/dblib/unittests/timeout.c index d5e97e89b8..bdf3f955fd 100644 --- a/src/dblib/unittests/timeout.c +++ b/src/dblib/unittests/timeout.c @@ -102,7 +102,7 @@ test(int per_process) DBPROCESS *dbproc; int i, r; RETCODE erc, row_code; - int num_resultset = 0; + /* int num_resultset = 0; */ char teststr[1024]; char timeout[32]; @@ -238,7 +238,7 @@ test(int per_process) printf("dbrows() returned SUCCEED, processing rows\n"); ncols = dbnumcols(dbproc); - ++num_resultset; + /* ++num_resultset; */ printf("bound 1 of %d columns ('%s') in result %d.\n", ncols, dbcolname(dbproc, 1), ++r); dbbind(dbproc, 1, STRINGBIND, 0, (BYTE *) teststr); diff --git a/src/odbc/unittests/testodbc.c b/src/odbc/unittests/testodbc.c index 9642080f03..b1e268d415 100644 --- a/src/odbc/unittests/testodbc.c +++ b/src/odbc/unittests/testodbc.c @@ -190,7 +190,7 @@ TestRawODBCGuid(void) SQLCHAR name[20]; SQLGUID sqlguid; - int count = 0; + /* int count = 0; */ AB_FUNCT(("TestRawODBCGuid (in)")); @@ -299,7 +299,7 @@ TestRawODBCGuid(void) queryString = "SELECT name, guid FROM #pet"; CHKExecDirect(T(queryString), SQL_NTS, "S"); while (SQLFetch(odbc_stmt) == SQL_SUCCESS) { - count++; + /* count++; */ CHKGetData(1, SQL_CHAR, name, 20, 0, "S"); CHKGetData(2, SQL_CHAR, guid, 37, 0, "S"); @@ -321,7 +321,7 @@ TestRawODBCGuid(void) queryString = "SELECT name, guid FROM #pet"; CHKExecDirect(T(queryString), SQL_NTS, "S"); while (CHKFetch("SNo") == SQL_SUCCESS) { - count++; + /* count++; */ CHKGetData(1, SQL_CHAR, name, 20, 0, "S"); CHKGetData(2, SQL_GUID, &sqlguid, 16, 0, "S"); @@ -351,7 +351,7 @@ TestRawODBCGuid(void) CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_GUID, 0, 0, guid, 0, &lenOrInd, "S"); CHKExecDirect(T(queryString), SQL_NTS, "S"); while (SQLFetch(odbc_stmt) == SQL_SUCCESS) { - count++; + /* count++; */ CHKGetData(1, SQL_CHAR, name, 20, 0, "S"); CHKGetData(2, SQL_CHAR, guid, 37, 0, "S"); diff --git a/src/tds/read.c b/src/tds/read.c index 99e31f6956..62e7485f80 100644 --- a/src/tds/read.c +++ b/src/tds/read.c @@ -275,14 +275,13 @@ static size_t read_and_convert(TDSSOCKET * tds, TDSICONV * char_conv, size_t * wire_size, char *outbuf, size_t outbytesleft) { - int res; TDSDATAINSTREAM r; TDSSTATICOUTSTREAM w; tds_datain_stream_init(&r, tds, *wire_size); tds_staticout_stream_init(&w, outbuf, outbytesleft); - res = tds_convert_stream(tds, char_conv, to_client, &r.stream, &w.stream); + tds_convert_stream(tds, char_conv, to_client, &r.stream, &w.stream); *wire_size = r.wire_size; return (char *) w.stream.buffer - outbuf; } diff --git a/src/tds/unittests/t0006.c b/src/tds/unittests/t0006.c index 1c26059810..84dcbd4d2d 100644 --- a/src/tds/unittests/t0006.c +++ b/src/tds/unittests/t0006.c @@ -30,7 +30,7 @@ main(void) TDSSOCKET *tds; int verbose = 0; int rc; - int row_count, i; + int /* row_count, */ i; /* variables for conversions */ TDSCOLUMN *curcol; @@ -102,7 +102,7 @@ main(void) rc = tds_submit_query(tds, "SELECT * FROM #test_table"); - row_count = 0; + /* row_count = 0; */ while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_RETURN_ROW|TDS_RETURN_COMPUTE)) == TDS_SUCCESS) { switch (result_type) { case TDS_ROW_RESULT: @@ -132,7 +132,7 @@ main(void) } } } - row_count++; + /* row_count++; */ case TDS_COMPUTE_RESULT: break; default: diff --git a/src/tds/unittests/utf8_1.c b/src/tds/unittests/utf8_1.c index b635077031..1f311a2d18 100644 --- a/src/tds/unittests/utf8_1.c +++ b/src/tds/unittests/utf8_1.c @@ -197,11 +197,11 @@ main(void) if (IS_TDS7_PLUS(tds->conn)) { char type[32]; char buf[1024]; - size_t i, len; + size_t len; strcpy(buf, "aaa"); len = 0; - for (i = 0; strlen(buf) < 980 && len < 200; ++i) { + while (strlen(buf) < 980 && len < 200) { char tmp[256]; strcat(buf, japanese); diff --git a/src/tds/unittests/utf8_3.c b/src/tds/unittests/utf8_3.c index 48822769e4..7db16a9cea 100644 --- a/src/tds/unittests/utf8_3.c +++ b/src/tds/unittests/utf8_3.c @@ -32,7 +32,7 @@ test(const char *buf) { char query[1024]; char tmp[129 * 3]; - int i; + /* int i; */ int rc; TDS_INT result_type; int done_flags; @@ -67,7 +67,7 @@ test(const char *buf) exit(1); } - i = 0; + /* i = 0; */ while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_STOPAT_ROWFMT|TDS_STOPAT_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE)) == TDS_SUCCESS) { TDSCOLUMN *curcol; @@ -83,7 +83,7 @@ test(const char *buf) (unsigned) tds_dstr_len(&curcol->column_name), tmp, (unsigned int) strlen(tmp)); exit(1); } - ++i; + /* ++i; */ } if (rc != TDS_SUCCESS || result_type == TDS_ROW_RESULT || result_type == TDS_COMPUTE_RESULT) { diff --git a/src/tds/write.c b/src/tds/write.c index 0b2fffeb1a..1706086480 100644 --- a/src/tds/write.c +++ b/src/tds/write.c @@ -96,7 +96,6 @@ tds_put_n(TDSSOCKET * tds, const void *buf, size_t n) int tds_put_string(TDSSOCKET * tds, const char *s, int len) { - int res; TDSSTATICINSTREAM r; TDSDATAOUTSTREAM w; enum TDS_ICONV_ENTRY iconv_entry; @@ -140,7 +139,8 @@ tds_put_string(TDSSOCKET * tds, const char *s, int len) tds_staticin_stream_init(&r, s, len); tds_dataout_stream_init(&w, tds); - res = tds_convert_stream(tds, tds->conn->char_convs[iconv_entry], to_server, &r.stream, &w.stream); + tds_convert_stream(tds, tds->conn->char_convs[iconv_entry], to_server, + &r.stream, &w.stream); return (int) w.written; } From 6c6981d835123308bdb2572e68a150612423f3cf Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Tue, 21 May 2024 14:52:30 -0400 Subject: [PATCH 47/49] Acknowledge non-exhaustive TDS_SERVER_TYPE switch statements. Add no-op default cases to switch statements that don't explicitly cover all of TDS_SERVER_TYPE. --- src/ctlib/ct.c | 2 ++ src/dblib/dbpivot.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c index 658926209c..2b5498fd89 100644 --- a/src/ctlib/ct.c +++ b/src/ctlib/ct.c @@ -2186,6 +2186,8 @@ _ct_get_client_type(const TDSCOLUMN *col, bool describe) case SYBMSDATETIME2: case SYBMSDATETIMEOFFSET: break; + default: /* SYBNTEXT, etc. */ + break; } return _cs_convert_not_client(NULL, col, NULL, NULL); diff --git a/src/dblib/dbpivot.c b/src/dblib/dbpivot.c index 52a0ad7aef..ac858fe2d3 100644 --- a/src/dblib/dbpivot.c +++ b/src/dblib/dbpivot.c @@ -174,6 +174,9 @@ col_equal(const struct col_t *pc1, const struct col_t *pc2) case SYBMSTABLE: assert( false && pc1->type ); break; + + default: + return false; } return false; } @@ -218,6 +221,9 @@ col_buffer(struct col_t *pcol) case SYBMSTABLE: assert( false && pcol->type ); break; + + default: + return NULL; } return NULL; From 526fe1c6abf5fb08efa2326c6f3e9d1e81e7f2b1 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Tue, 21 May 2024 15:32:58 -0400 Subject: [PATCH 48/49] Formally address static analyzer concerns. * Add more explicit sanity checks and initializers. * Avoid potential zero-byte allocations (whose behavior is undefined). * challenge.c (make_ntlm_v2_hash): Account for the (theoretical) possibility that the full username could lack a backslash or even be null altogether. * mem.c (tds_init_login): Don't leak lc_all when unable to populate client_charset. * query.c (tds_convert_string): Clear *out_len if allocation fails. * vstrbuild.c (tds_vstrbuild): Use unsigned int for counts that will never be negative. * dbpivot.c (make_col_name): Elide gratuitous calls to strdup, which resulted in leaks because string_value already allocates memory. * rpc_ct_setparam.c (ex_display_results): Avoid memory leaks in some error cases. --- src/ctlib/unittests/datafmt.c | 3 +++ src/ctlib/unittests/rpc_ct_setparam.c | 1 + src/ctlib/unittests/t0004.c | 13 +++++++++++++ src/dblib/dbpivot.c | 3 ++- src/dblib/unittests/t0013.c | 4 ++++ src/dblib/unittests/t0014.c | 5 +++++ src/odbc/convert_tds2sql.c | 8 +++++++- src/odbc/prepare_query.c | 2 +- src/tds/challenge.c | 15 ++++++++++----- src/tds/config.c | 3 ++- src/tds/mem.c | 6 ++++-- src/tds/query.c | 4 +++- src/tds/unittests/charconv.c | 2 +- src/tds/vstrbuild.c | 8 ++++---- 14 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/ctlib/unittests/datafmt.c b/src/ctlib/unittests/datafmt.c index b322981691..6e9553b2ca 100644 --- a/src/ctlib/unittests/datafmt.c +++ b/src/ctlib/unittests/datafmt.c @@ -71,6 +71,9 @@ main(int argc, char *argv[]) fprintf(stderr, "CS_CHAR_TYPE\n"); datafmt.format = CS_FMT_NULLTERM; addr = (char *) malloc(datafmt.maxlength); + } else { + fputs("unexpected data type\n", stderr); + return 1; } fprintf(stderr, "binding column 1 (%s)\n", datafmt.name); diff --git a/src/ctlib/unittests/rpc_ct_setparam.c b/src/ctlib/unittests/rpc_ct_setparam.c index 23d7415dd5..b45b14d9be 100644 --- a/src/ctlib/unittests/rpc_ct_setparam.c +++ b/src/ctlib/unittests/rpc_ct_setparam.c @@ -351,6 +351,7 @@ int i, j; ret = ct_bind(cmd, (i + 1), &outdatafmt[i], coldata[i].value, &coldata[i].valuelen, & coldata[i].indicator); if (ret != CS_SUCCEED) { + free(coldata[i].value); fprintf(stderr, "ct_bind failed \n"); break; } diff --git a/src/ctlib/unittests/t0004.c b/src/ctlib/unittests/t0004.c index 4be6dfeae7..d37d391292 100644 --- a/src/ctlib/unittests/t0004.c +++ b/src/ctlib/unittests/t0004.c @@ -4,6 +4,7 @@ #include #include "common.h" +#include #include /* protos */ @@ -121,12 +122,17 @@ do_results(CS_COMMAND * cmd, CS_INT * results) { int result_num; CS_RETCODE results_ret, result_type; +bool done = false; result_num = 0; while ((results_ret = ct_results(cmd, &result_type)) == CS_SUCCEED) { printf("result_ret %d result_type %d\n", results_ret, result_type); if (result_type == CS_STATUS_RESULT) continue; + if (done) { + fputs("No further results were expected\n", stderr); + return CS_FAIL; + } if (result_type != results[result_num]) { fprintf(stderr, "ct_results() expected %d received %d\n", results[result_num], result_type); return CS_FAIL; @@ -137,8 +143,15 @@ CS_RETCODE results_ret, result_type; return CS_FAIL; } break; + case CS_CMD_DONE: + done = true; + break; } result_num++; } + if ( !done ) { + fputs("Never saw CS_CMD_DONE\n", stderr); + return CS_FAIL; + } return results_ret; } diff --git a/src/dblib/dbpivot.c b/src/dblib/dbpivot.c index ac858fe2d3..126cb111da 100644 --- a/src/dblib/dbpivot.c +++ b/src/dblib/dbpivot.c @@ -99,6 +99,7 @@ col_init(struct col_t *pcol, int sybtype, size_t collen) if (pcol->type == TDS_INVALID_TYPE) return NULL; pcol->len = collen; + pcol->s = NULL; switch (sybtype) { case 0: @@ -535,7 +536,7 @@ make_col_name(DBPROCESS *dbproc, const KEY_T *k) return NULL; } for(pc=k->keys; pc < k->keys + k->nkeys; pc++) { - *s++ = strdup(string_value(pc)); + *s++ = string_value(pc); } output = join(k->nkeys, names, "/"); diff --git a/src/dblib/unittests/t0013.c b/src/dblib/unittests/t0013.c index c823a6ddd6..7ad3c1c320 100644 --- a/src/dblib/unittests/t0013.c +++ b/src/dblib/unittests/t0013.c @@ -252,6 +252,10 @@ test(int argc, char **argv, int over4k) } data_ok = 1; + if (rblob == NULL) { + fputs("No blob data received", stderr); + return 7; + } if (memcmp(blob, rblob, numread) != 0) { printf("Saving first blob data row to file: %s\n", argv[2]); if ((fp = fopen(argv[2], "wb")) == NULL) { diff --git a/src/dblib/unittests/t0014.c b/src/dblib/unittests/t0014.c index 43571b6c9d..4347ce46a1 100644 --- a/src/dblib/unittests/t0014.c +++ b/src/dblib/unittests/t0014.c @@ -218,6 +218,11 @@ test(int argc, char **argv, int over4k) } } + if (rblob == NULL) { + fputs("No blob data received", stderr); + return 7; + } + if (i == 0) { printf("Saving first blob data row to file: %s\n", argv[2]); if ((fp = fopen(argv[2], "wb")) == NULL) { diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c index 842872aefa..0a1b52bb9f 100644 --- a/src/odbc/convert_tds2sql.c +++ b/src/odbc/convert_tds2sql.c @@ -69,8 +69,14 @@ odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT /* FIXME MARS not correct cause is the global tds but stmt->tds can be NULL on SQLGetData */ TDSSOCKET *tds = stmt->dbc->tds_socket; + TDSICONV *conv; - TDSICONV *conv = curcol->char_conv; + if (curcol == NULL) { + odbc_errs_add(&stmt->errs, "HY013", NULL); + return SQL_NULL_DATA; + } + + conv = curcol->char_conv; if (!conv) conv = tds->conn->char_convs[client2server_chardata]; if (desttype == SQL_C_WCHAR) { diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c index 4b2c709f39..ff363135b3 100644 --- a/src/odbc/prepare_query.c +++ b/src/odbc/prepare_query.c @@ -447,7 +447,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St } else { memcpy(blob->textvalue + curcol->column_cur_size, DataPtr, len); } - } else { + } else if (len > 0) { memcpy(curcol->column_data + curcol->column_cur_size, DataPtr, len); } diff --git a/src/tds/challenge.c b/src/tds/challenge.c index cc5e354be6..3e98df37e9 100644 --- a/src/tds/challenge.c +++ b/src/tds/challenge.c @@ -163,7 +163,7 @@ static TDSRET make_ntlm_v2_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_v2_hash[16]) { const char *user_name, *domain; - size_t domain_len, user_name_len, len, buf_usc2le_len = 0; + size_t domain_len, user_name_len = 0, len, buf_usc2le_len = 0; const char *p; unsigned char ntlm_hash[16]; @@ -174,13 +174,15 @@ make_ntlm_v2_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_v2_has user_name = tds_dstr_cstr(&tds->login->user_name); /* parse domain\username */ - p = strchr(user_name, '\\'); + p = user_name ? strchr(user_name, '\\') : NULL; domain = user_name; - domain_len = p - user_name; + domain_len = p ? p - user_name : 0; - user_name = p + 1; - user_name_len = strlen(user_name); + if (p != NULL) { + user_name = p + 1; + user_name_len = strlen(user_name); + } if (user_name_len > 128) user_name_len = 128; @@ -225,6 +227,9 @@ make_lm_v2_response(const unsigned char ntlm_v2_hash[16], int mac_len = 16 + client_data_len; unsigned char *mac; + if (client_data == NULL || client_data_len <= 0) + return NULL; + mac = tds_new(unsigned char, mac_len); if (!mac) return NULL; diff --git a/src/tds/config.c b/src/tds/config.c index 08f8dc326e..e5c1059930 100644 --- a/src/tds/config.c +++ b/src/tds/config.c @@ -701,7 +701,8 @@ tds_parse_conf_section(const char *option, const char *value, void *param) } if (!s || got_error) { - login->valid_configuration = 0; + if (login) + login->valid_configuration = 0; return false; } return true; diff --git a/src/tds/mem.c b/src/tds/mem.c index e76b4b2528..0fe09e757d 100644 --- a/src/tds/mem.c +++ b/src/tds/mem.c @@ -550,7 +550,7 @@ tds_alloc_row(TDSRESULTINFO * res_info) } res_info->row_size = row_size; - ptr = tds_new0(unsigned char, res_info->row_size); + ptr = tds_new0(unsigned char, row_size ? row_size : 1); res_info->current_row = ptr; if (!ptr) return TDS_FAIL; @@ -850,8 +850,10 @@ tds_init_login(TDSLOGIN *login, TDSLOCALE * locale) if (strtok_r(lc_all, ".", &tok)) { char *encoding = strtok_r(NULL, "@", &tok); if (encoding) { - if (!tds_dstr_copy(&login->client_charset, encoding)) + if (!tds_dstr_copy(&login->client_charset, encoding)) { + free(lc_all); return NULL; + } } } free(lc_all); diff --git a/src/tds/query.c b/src/tds/query.c index e1e8cb9661..65e5be671d 100644 --- a/src/tds/query.c +++ b/src/tds/query.c @@ -146,8 +146,10 @@ tds_convert_string(TDSSOCKET * tds, TDSICONV * char_conv, const char *s, /* allocate needed buffer (+1 is to exclude 0 case) */ ol = il * char_conv->to.charset.max_bytes_per_char / char_conv->from.charset.min_bytes_per_char + 1; buf = tds_new(char, ol); - if (!buf) + if (!buf) { + *out_len = 0; return NULL; + } ib = s; ob = buf; diff --git a/src/tds/unittests/charconv.c b/src/tds/unittests/charconv.c index d78856310f..775796d259 100644 --- a/src/tds/unittests/charconv.c +++ b/src/tds/unittests/charconv.c @@ -58,7 +58,7 @@ convert(TDSSOCKET *tds, TDSICONV *conv, TDS_ICONV_DIRECTION direction, const char *from, size_t from_len, char *dest, size_t *dest_len) { /* copy to make valgrind test fail on memory problems */ - char *in = tds_new(char, from_len); + char *in = tds_new(char, from_len ? from_len : 1); char *out = tds_new(char, *dest_len); int res; TDSSTATICINSTREAM r; diff --git a/src/tds/vstrbuild.c b/src/tds/vstrbuild.c index 00561bc9c6..17ac78d67c 100644 --- a/src/tds/vstrbuild.c +++ b/src/tds/vstrbuild.c @@ -84,14 +84,14 @@ tds_vstrbuild(char *buffer, int buflen, int *resultlen, const char *text, int te char *token; const char *sep = "\377"; char *lasts; - int tokcount = 0; + unsigned int tokcount = 0; struct string_linked_list *head = NULL; struct string_linked_list *item = NULL; struct string_linked_list **tail = &head; - int i; + unsigned int i; int state; char **string_array = NULL; - int pnum = 0; + unsigned int pnum = 0; int pdigit; char *paramp = NULL; TDSRET rc = TDS_FAIL; @@ -156,7 +156,7 @@ tds_vstrbuild(char *buffer, int buflen, int *resultlen, const char *text, int te case CALCPARAM: switch (*text) { case '!': - if (pnum <= tokcount) { + if (pnum > 0 && pnum <= tokcount) { paramp = string_array[pnum - 1]; state = OUTPARAM; } From f703addf566c18220afced30b3c4586373e60653 Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Tue, 21 May 2024 15:38:29 -0400 Subject: [PATCH 49/49] Fix miscellaneous one-off warnings. * odbc.h: For Clang, substitute __attribute__((visibility("default"))) for __attribute__((externally_visible)), which it at least historically didn't support. * odbc/unittests/common.h: When the ODBC 3 API is available, favor SQLSetStmtAttr over SQLSetStmtOption, which is deprecated. * dblib/bcp.c (_bcp_get_col_data): Comment out an always-true comparison of column_bindlen (which was never signed) to zero. * tds5_bcp_add_variable_columns: Explicitly mark 256 as unsigned to avoid spurious signed-vs.-unsigned comparison warnings. * gssapi.c: On macOS, additionally suppress __API_DEPRECATED right before including gssapi_krb5.h (which is at least the last explicitly included system header). * tls.c: Define _WIN32_WINNT ahead of config.h, which might otherwise supply a somewhat different definition, yielding a warning. * ctlib/unittests/t0009.c: Pre-zero compute_col3. Optimized builds with Clang or LLVM-based ICC can otherwise yield a Valgrind warning concerning a strcmp call that reads slightly past the trailing NUL. --- include/freetds/odbc.h | 4 +++- src/ctlib/unittests/t0009.c | 2 +- src/dblib/bcp.c | 2 +- src/odbc/unittests/common.h | 5 +++++ src/tds/bulk.c | 2 +- src/tds/gssapi.c | 6 ++++++ src/tds/tls.c | 4 ++-- 7 files changed, 19 insertions(+), 6 deletions(-) diff --git a/include/freetds/odbc.h b/include/freetds/odbc.h index f7e49786e1..6a9b67b9f8 100644 --- a/include/freetds/odbc.h +++ b/include/freetds/odbc.h @@ -74,7 +74,9 @@ extern "C" #endif #include -#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__) +#ifdef __clang__ +#define ODBC_API SQL_API __attribute__((visibility("default"))) +#elif defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__) #define ODBC_API SQL_API __attribute__((externally_visible)) #else #define ODBC_API SQL_API diff --git a/src/ctlib/unittests/t0009.c b/src/ctlib/unittests/t0009.c index 353884303e..0cb4e7bb32 100644 --- a/src/ctlib/unittests/t0009.c +++ b/src/ctlib/unittests/t0009.c @@ -39,7 +39,7 @@ main(void) CS_CHAR col3[32]; CS_INT compute_col1; - CS_CHAR compute_col3[32]; + CS_CHAR compute_col3[32] = ""; unsigned rows[3] = { 0, 0, 0 }; diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c index 125cdb5eae..07d85ee241 100644 --- a/src/dblib/bcp.c +++ b/src/dblib/bcp.c @@ -2228,7 +2228,7 @@ _bcp_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset TDS_UNUSED /* if (Max) column length specified take that into consideration. */ - if (bindcol->column_bindlen >= 0) { + /* if (bindcol->column_bindlen >= 0) */ { /* bindlen is unsigned */ if (bindcol->column_bindlen == 0) goto null_data; if (collen) diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h index e991e713c6..dee9585b2e 100644 --- a/src/odbc/unittests/common.h +++ b/src/odbc/unittests/common.h @@ -160,8 +160,13 @@ SQLSMALLINT odbc_alloc_handle_err_type(SQLSMALLINT type); CHKR2(SQLSetPos, (odbc_stmt,a,b,c), SQL_HANDLE_STMT, odbc_stmt, res) #define CHKSetStmtAttr(a,b,c,res) \ CHKR2(SQLSetStmtAttr, (odbc_stmt,a,b,c), SQL_HANDLE_STMT, odbc_stmt, res) +#if ODBCVER >= 0x0300 +#define CHKSetStmtOption(a,b,res) \ + CHKSetStmtAttr(a, (SQLPOINTER) b, SQL_NTS, res) +#else #define CHKSetStmtOption(a,b,res) \ CHKR2(SQLSetStmtOption, (odbc_stmt,a,b), SQL_HANDLE_STMT, odbc_stmt, res) +#endif #define CHKTables(a,b,c,d,e,f,g,h,res) \ CHKR2(SQLTables, (odbc_stmt,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, odbc_stmt, res) #define CHKProcedureColumns(a,b,c,d,e,f,g,h,res) \ diff --git a/src/tds/bulk.c b/src/tds/bulk.c index 7080380913..97662d6f52 100644 --- a/src/tds/bulk.c +++ b/src/tds/bulk.c @@ -825,7 +825,7 @@ tds5_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_ unsigned int n_pfx = 1; for (i = 0; i <= ncols ; ++i) - if ((offsets[i] / 256) < pfx_top) + if ((offsets[i] / 256u) < pfx_top) ++n_pfx; *poff++ = n_pfx; --pfx_top; diff --git a/src/tds/gssapi.c b/src/tds/gssapi.c index 9611e3c02f..4f2ced2a97 100644 --- a/src/tds/gssapi.c +++ b/src/tds/gssapi.c @@ -62,6 +62,8 @@ #ifdef __APPLE__ #define KERBEROS_APPLE_DEPRECATED(x) #define GSSKRB_APPLE_DEPRECATED(x) +#undef __API_DEPRECATED +#define __API_DEPRECATED(x, y) #endif #include @@ -238,8 +240,12 @@ tds_gss_get_auth(TDSSOCKET * tds) */ gss_buffer_desc send_tok; OM_uint32 maj_stat, min_stat; +#ifdef __APPLE__ +# define nt_principal *(gss_OID_desc *) GSS_KRB5_NT_PRINCIPAL_NAME +#else /* same as GSS_KRB5_NT_PRINCIPAL_NAME but do not require .so library */ static gss_OID_desc nt_principal = { 10, (void*) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01" }; +#endif const char *server_name; /* Storage for getaddrinfo calls */ struct addrinfo *addrs = NULL; diff --git a/src/tds/tls.c b/src/tds/tls.c index 682c994951..54aad8b4e5 100644 --- a/src/tds/tls.c +++ b/src/tds/tls.c @@ -18,11 +18,11 @@ * Boston, MA 02111-1307, USA. */ -#include - /* enabled some additional definitions for inet_pton */ #define _WIN32_WINNT 0x600 +#include + #include #if HAVE_ERRNO_H