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/include/cspublic.h b/include/cspublic.h index 38d6fb7fa5..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 @@ -613,9 +618,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 */ @@ -770,10 +777,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/ctlib.h b/include/ctlib.h index 1009b4e342..e466ca5533 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; @@ -323,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]; @@ -393,8 +405,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, + 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/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/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/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..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 @@ -152,7 +154,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 +634,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 +645,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 +705,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/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..df0b73c840 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 @@ -384,7 +401,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) @@ -890,6 +910,7 @@ typedef struct tds_message TDS_TINYINT severity; /* for library-generated errors */ int oserr; + TDS_CHAR *osstr; } TDSMESSAGE; typedef struct tds_upd_col @@ -1365,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); @@ -1375,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); @@ -1432,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) \ @@ -1536,10 +1562,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 +1576,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; @@ -1565,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); @@ -1608,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); @@ -1691,6 +1722,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 @@ -1706,6 +1741,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/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/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/include/freetds/utils/des.h b/include/freetds/utils/des.h index a05a207657..a90315a9ff 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 @@ -25,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/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/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; 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/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/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/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/ctlib/blk.c b/src/ctlib/blk.c index 34aeaccdd4..fffeb50ac0 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) @@ -214,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) @@ -282,19 +283,55 @@ 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) +{ + 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; + 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 blk_drop(CS_BLKDESC * blkdesc) { @@ -482,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) { @@ -494,10 +546,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 @@ -594,6 +672,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 @@ -601,16 +681,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; } } @@ -641,9 +724,19 @@ _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); + 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 @@ -651,21 +744,26 @@ _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 (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; + } + 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); @@ -693,7 +791,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 { @@ -705,19 +803,23 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset) null_column = true; } - if (!null_column) { - CONV_RESULT convert_buffer; + if (!null_column && !is_blob_type(bindcol->column_type)) { 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 CS_FAIL; + return TDS_FAIL; destfmt.datatype = desttype; destfmt.maxlength = bindcol->on_server.column_size; destfmt.precision = bindcol->column_prec; @@ -726,9 +828,27 @@ _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, tds_desttype, + (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 + && 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; + } } } diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c index ad89d6130d..c3abfa6eab 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); @@ -504,10 +502,12 @@ 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, + 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; @@ -549,20 +549,27 @@ _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; } 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 || 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; @@ -584,6 +591,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) { @@ -592,14 +607,14 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdat 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); @@ -622,6 +637,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); @@ -777,8 +794,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; @@ -821,15 +844,24 @@ _cs_convert(CS_CONTEXT * ctx, const CS_DATAFMT_COMMON * srcfmt, CS_VOID * srcdat *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: + case SYBNVARCHAR: + case SYBNTEXT: ret = CS_SUCCEED; if (len > destlen) { 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) { @@ -839,7 +871,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; } @@ -848,7 +886,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; @@ -856,13 +900,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: @@ -873,7 +928,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; @@ -887,7 +944,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, TDS_INVALID_TYPE, NULL); } CS_RETCODE @@ -937,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; @@ -1116,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) @@ -1131,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) @@ -1149,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)) { @@ -1164,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; @@ -1172,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 396048e849..2b5498fd89 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; @@ -609,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: @@ -766,7 +770,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) { @@ -843,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); @@ -1954,7 +1961,9 @@ _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, 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", @@ -2142,6 +2151,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; @@ -2163,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); @@ -2179,6 +2204,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)) @@ -2208,11 +2234,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; @@ -2495,11 +2522,15 @@ 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) + 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)) @@ -2636,7 +2667,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; @@ -2656,7 +2688,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; @@ -2771,7 +2804,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; @@ -2952,12 +2985,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->namelen = strlen(cmd->iodesc->name); + 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->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; @@ -2979,8 +3026,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; @@ -3093,7 +3147,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; @@ -3115,7 +3172,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; @@ -3312,7 +3373,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; @@ -3383,6 +3444,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); @@ -3391,6 +3454,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) { @@ -3900,6 +3987,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) { @@ -3942,6 +4052,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); @@ -4203,7 +4359,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) { @@ -4227,9 +4385,24 @@ 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; + } 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/ctlib/ctutil.c b/src/ctlib/ctutil.c index bae42588d4..f0adde041b 100644 --- a/src/ctlib/ctutil.c +++ b/src/ctlib/ctutil.c @@ -125,9 +125,12 @@ _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.osstring[0] = '\0'; - errmsg.osstringlen = 0; + 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); + } + /* if there is no connection, attempt to call the context handler */ if (!con) { ctx = (CS_CONTEXT *) ctx_tds->parent; @@ -181,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) @@ -206,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 */ @@ -270,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; } @@ -314,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/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/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/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..5c24925f1a 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; @@ -19,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 */ @@ -46,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 @@ -296,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/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..6e9553b2ca 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[]) @@ -69,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/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..6fc7356c81 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)"; @@ -108,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; @@ -142,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"); @@ -167,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; @@ -182,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/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..786ee0a0c0 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)) @@ -112,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; @@ -552,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 883cb7cebc..b45b14d9be 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)) @@ -103,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; @@ -349,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; } @@ -587,7 +590,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_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..d37d391292 100644 --- a/src/ctlib/unittests/t0004.c +++ b/src/ctlib/unittests/t0004.c @@ -4,6 +4,9 @@ #include #include "common.h" +#include +#include + /* protos */ int do_fetch(CS_COMMAND * cmd); CS_RETCODE do_results(CS_COMMAND * cmd, CS_INT * results); @@ -119,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; @@ -135,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/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..0cb4e7bb32 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; @@ -37,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/ctlib/unittests/variant.c b/src/ctlib/unittests/variant.c index 66e8be8c52..009eb6e11d 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) @@ -32,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/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/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/dblib/bcp.c b/src/dblib/bcp.c index 3509341451..07d85ee241 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) { @@ -1683,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; @@ -1700,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; @@ -2226,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/dblib/dblib.c b/src/dblib/dblib.c index 966cb0acd9..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); */ @@ -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) @@ -3447,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; @@ -3488,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; @@ -3559,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; @@ -3615,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; @@ -3645,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; } @@ -3682,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); } @@ -3760,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; @@ -3879,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); @@ -3937,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; @@ -3951,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; @@ -4001,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); @@ -4982,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); @@ -5040,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); @@ -6634,6 +6651,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; @@ -6652,8 +6670,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; @@ -8175,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 */ @@ -8250,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/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/dblib/dbpivot.c b/src/dblib/dbpivot.c index 5b59dea59f..126cb111da 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); @@ -99,6 +99,7 @@ col_init(struct col_t *pcol, int sybtype, int collen) if (pcol->type == TDS_INVALID_TYPE) return NULL; pcol->len = collen; + pcol->s = NULL; switch (sybtype) { case 0: @@ -174,6 +175,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 +222,9 @@ col_buffer(struct col_t *pcol) case SYBMSTABLE: assert( false && pcol->type ); break; + + default: + return NULL; } return NULL; @@ -529,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, "/"); @@ -653,7 +660,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 +723,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 +786,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 +860,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 +878,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 +920,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 +946,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 +969,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 +987,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 +1002,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 +1012,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/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..fda3af8641 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); @@ -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/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 6532a129c5..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,12 +35,16 @@ #include #include +#include + #if !defined(EXIT_FAILURE) #define EXIT_FAILURE 1 #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/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..7dbf38c873 100644 --- a/src/dblib/unittests/dbsafestr.c +++ b/src/dblib/unittests/dbsafestr.c @@ -5,12 +5,14 @@ #include "common.h" +#include + #ifndef DBNTWIN32 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]; @@ -28,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/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..6ebe99860a 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) { @@ -43,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); @@ -116,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/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..07e7a16188 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; @@ -16,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/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..75a72d42cc 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; @@ -14,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/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..7ad3c1c320 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; @@ -37,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(); @@ -249,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) { @@ -263,7 +270,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 0c494155df..4347ce46a1 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" }; @@ -19,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(); @@ -215,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) { @@ -224,11 +232,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/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..63284241c0 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 = ""; @@ -91,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"); 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..bdf3f955fd 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; @@ -100,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]; @@ -206,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"); @@ -235,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/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/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 46e2ce20c6..3f763ad3bf 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 @@ -578,13 +582,16 @@ 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; } -static int +#ifndef _WIN32 +static +#endif +int SQLGetPrivateProfileString(LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer, LPCSTR pszFileName) { @@ -631,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..0a1b52bb9f 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); @@ -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) { @@ -113,12 +119,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 +182,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 +213,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 +247,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 +294,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 +329,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 +422,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 +441,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 +465,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 c9369df192..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); @@ -1997,7 +1998,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) { @@ -2199,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; } @@ -2408,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 @@ -2725,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: @@ -3168,7 +3172,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; @@ -3430,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; @@ -3891,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; @@ -3994,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; } @@ -4463,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; @@ -6125,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 */ @@ -6308,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) { @@ -6389,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)) { @@ -6415,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)) { @@ -6445,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: @@ -6467,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) @@ -6610,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) { @@ -6636,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) { @@ -6655,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 */ @@ -6674,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) { @@ -6708,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; @@ -6745,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; @@ -6776,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: @@ -6785,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; @@ -6798,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); @@ -6822,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) { @@ -6843,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)) { @@ -6871,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); @@ -7285,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) @@ -7372,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; @@ -7422,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; @@ -7491,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; @@ -7532,7 +7541,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_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_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/odbc/odbc_util.c b/src/odbc/odbc_util.c index 5153a459a1..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); @@ -128,14 +131,14 @@ 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); } 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 @@ -211,12 +214,12 @@ 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); } 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..ff363135b3 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; @@ -443,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/odbc/sql2tds.c b/src/odbc/sql2tds.c index 50db6e06b4..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,13 +566,16 @@ 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: case SYBINT4: case SYBINT8: + case SYB5INT8: case SYBFLT8: case SYBDATETIME: case SYBBIT: 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..be9587a92c 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; @@ -138,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/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..cd80386854 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 @@ -29,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; @@ -41,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]; @@ -69,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; @@ -182,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 6c11cf41fa..9ab448a655 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) @@ -36,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; @@ -49,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: @@ -77,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 b76d4e32e9..8d04cfd650 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 @@ -72,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/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..9b8910f300 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; @@ -48,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); @@ -84,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; @@ -667,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 e3f88434c0..dee9585b2e 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; @@ -158,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) \ @@ -196,8 +203,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/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 96ea32342e..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); @@ -12,18 +14,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/unittests/connect2.c b/src/odbc/unittests/connect2.c index 8befd72ca2..ad16385487 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 @@ -56,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 @@ -81,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/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..3f3da21eab 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 @@ -20,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/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..6917a3d1ce 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 @@ -15,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/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..024a7e136a 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 @@ -45,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/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..4ca4c0a9d5 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; @@ -91,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/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..840e4c77c7 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) @@ -33,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/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..ffd9a40164 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 @@ -48,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/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..ef58922f93 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 */ @@ -14,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 @@ -36,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"); @@ -48,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/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..2928cdd27d 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[] = @@ -22,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; @@ -63,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; @@ -117,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/qn.c b/src/odbc/unittests/qn.c index cf344e5ad3..c6f5430423 100644 --- a/src/odbc/unittests/qn.c +++ b/src/odbc/unittests/qn.c @@ -1,12 +1,14 @@ #include "common.h" -#include #include "odbcss.h" #include #include +#include + /* 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 +133,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/odbc/unittests/raiserror.c b/src/odbc/unittests/raiserror.c index 7a4ffce94a..1cfef60670 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 */ @@ -132,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 8611a578a2..ffa2dc2dfa 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) @@ -10,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/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..531fb0be85 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" @@ -139,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/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..0950c75e6c 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]; @@ -15,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) @@ -97,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(); @@ -113,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(); 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..236659a648 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 @@ -53,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/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..b1e268d415 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) @@ -188,7 +190,7 @@ TestRawODBCGuid(void) SQLCHAR name[20]; SQLGUID sqlguid; - int count = 0; + /* int count = 0; */ AB_FUNCT(("TestRawODBCGuid (in)")); @@ -297,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"); @@ -319,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"); @@ -349,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/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..c82d2b2bd1 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 @@ -60,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; @@ -387,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/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..efe5b52f76 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 @@ -50,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/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/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..6a003fee9a 100644 --- a/src/odbc/winsetup.c +++ b/src/odbc/winsetup.c @@ -318,10 +318,15 @@ 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]; + TCHAR buf[1000]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errorcode, 0, buf, 1000, NULL); } @@ -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/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/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/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/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/tds/bulk.c b/src/tds/bulk.c index 12968d4f5c..97662d6f52 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 */ /** @@ -74,6 +78,10 @@ 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); +static int tds_bcp_is_bound(TDSBCPINFO *bcpinfo, TDSCOLUMN *colinfo); /** * Initialize BCP information. @@ -168,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)); @@ -285,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; @@ -328,18 +340,22 @@ 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 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]; @@ -350,7 +366,8 @@ tds7_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_c if ((!bcpinfo->identity_insert_on && bindcol->column_identity) || bindcol->column_timestamp || - bindcol->column_computed) { + bindcol->column_computed || + !tds_bcp_is_bound(bcpinfo, bindcol)) { continue; } @@ -358,6 +375,8 @@ tds7_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_c 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); @@ -366,7 +385,17 @@ 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 (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)); @@ -382,21 +411,25 @@ tds7_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_c 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 */ @@ -427,29 +460,68 @@ 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 = 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 */ 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, bindcol->on_server.column_type); + 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++; } } @@ -470,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); @@ -477,12 +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, offset); + rc = tds7_send_record(tds, bcpinfo, get_col_data, null_error, + 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; } @@ -536,7 +632,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; } @@ -627,15 +724,16 @@ 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 * 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 { @@ -645,8 +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(get_col_data(bcpinfo, bcpcol, offset))) + 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 */ @@ -666,12 +769,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; @@ -708,13 +818,14 @@ 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; 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; @@ -764,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++; @@ -785,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; } @@ -794,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); @@ -917,6 +1030,7 @@ enum { BULKCOL_length, BULKCOL_status, BULKCOL_offset, + BULKCOL_dflt, /* number of columns needed */ BULKCOL_COUNT, @@ -938,6 +1052,9 @@ tds5_bulk_insert_column(const char *name) BULKCOL(colcnt); BULKCOL(colid); break; + case 'd': + BULKCOL(dflt); + break; case 't': BULKCOL(type); break; @@ -955,6 +1072,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) { @@ -970,6 +1108,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); @@ -996,9 +1135,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) { @@ -1040,6 +1184,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, @@ -1062,6 +1210,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. */ @@ -1373,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/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 277795d019..e5c1059930 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"; @@ -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); @@ -700,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/convert.c b/src/tds/convert.c index 320c5efdab..7c3f4fd6e4 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 @@ -298,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 ... */ @@ -1115,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: @@ -1504,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); } @@ -1866,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; @@ -1986,8 +1993,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; @@ -3247,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 aaab739db3..86aedbeaf3 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; @@ -387,7 +390,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) @@ -512,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; @@ -723,6 +725,22 @@ 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; + } 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... */ len = tds_get_byte(tds); blob = (TDSBLOB *) curcol->column_data; @@ -738,11 +756,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: @@ -783,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 */ @@ -884,14 +897,17 @@ tds_generic_put_info(TDSSOCKET * tds, TDSCOLUMN * col) case 0: break; case 1: - tds_put_byte(tds, size); + if (col->column_output && col->column_size <= 0 + && is_char_type(col->column_type)) { + size = 255; + } + TDS_PUT_BYTE(tds, size); break; case 2: - tds_put_smallint(tds, size); + TDS_PUT_SMALLINT(tds, size); break; - case 5: case 4: - tds_put_int(tds, size); + TDS_PUT_INT(tds, size); break; case 8: tds_put_smallint(tds, 0xffff); @@ -934,9 +950,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); @@ -962,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; } @@ -1005,13 +1018,19 @@ 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... */ + 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)) { @@ -1023,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 */ @@ -1046,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]; @@ -1067,20 +1088,22 @@ 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); 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) { @@ -1094,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 */ @@ -1109,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]; @@ -1367,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; @@ -1501,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..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; @@ -459,7 +465,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/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. 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; diff --git a/src/tds/login.c b/src/tds/login.c index f754f63243..bca92dfa82 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); @@ -416,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); @@ -440,7 +441,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; @@ -968,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; @@ -985,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 */ @@ -1011,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; @@ -1274,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 c487f7d087..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); @@ -883,7 +885,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 +1347,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 @@ -1864,10 +1867,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/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/net.c b/src/tds/net.c index 466776c0b3..937ae6d53d 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 */ /* @@ -723,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 */ @@ -758,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 @@ -855,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 @@ -912,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); @@ -961,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; @@ -983,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); @@ -1048,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) @@ -1097,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]; @@ -1233,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]; @@ -1350,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 089750c773..65e5be671d 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; @@ -145,8 +146,10 @@ tds_convert_string(TDSSOCKET * tds, TDSICONV * char_conv, const char *s, int len /* 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; @@ -399,7 +402,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 +750,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 +959,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 +1025,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 +1082,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 +1314,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 +1421,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); @@ -1554,10 +1560,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: @@ -1588,12 +1598,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) @@ -1622,7 +1632,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; @@ -1953,7 +1963,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) { @@ -1998,7 +2009,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; @@ -2215,7 +2226,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; @@ -2260,7 +2271,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 @@ -2285,7 +2296,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); } @@ -2393,8 +2405,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); @@ -2855,7 +2868,7 @@ TDSRET tds_cursor_setname(TDSSOCKET * tds, TDSCURSOR * cursor) { TDSFREEZE outer; - size_t written; + unsigned int written; CHECK_TDS_EXTRA(tds); @@ -2988,7 +3001,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 1403c63482..62e7485f80 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", @@ -240,15 +242,19 @@ 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 */ 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; } @@ -269,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/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 c027666032..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; @@ -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); @@ -235,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); 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/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 diff --git a/src/tds/token.c b/src/tds/token.c index 1cafae71cc..54dac9072a 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; @@ -2627,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); @@ -2687,6 +2690,7 @@ tds5_process_dyn_result2(TDSSOCKET * tds) unsigned int col, num_cols; TDSCOLUMN *curcol; TDSPARAMINFO *info; + TDSDYNAMIC *dyn = NULL; CHECK_TDS_EXTRA(tds); @@ -2697,7 +2701,7 @@ tds5_process_dyn_result2(TDSSOCKET * tds) if ((info = tds_alloc_results(num_cols)) == NULL) return TDS_FAIL; if (tds->cur_dyn) { - TDSDYNAMIC *dyn = tds->cur_dyn; + dyn = tds->cur_dyn; tds_free_param_results(dyn->res_info); dyn->res_info = info; } else { @@ -2740,6 +2744,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); diff --git a/src/tds/unittests/allcolumns.c b/src/tds/unittests/allcolumns.c index abf9c00178..5fdba1bfb4 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) { @@ -231,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 d8f901be26..775796d259 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 */ @@ -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; @@ -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/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..b39382a3bb 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; @@ -38,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); @@ -157,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"; @@ -214,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 48bbb099ea..0d5535a721 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); @@ -215,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 317a5ce23d..f6c476e600 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 @@ -54,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/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 d64e9063c2..e12595e1e0 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 @@ -30,7 +29,11 @@ #endif /* HAVE_UNISTD_H */ #include +#include +#include + +#ifdef TDS_HAVE_MUTEX #ifdef _WIN32 #define SHUT_WR SD_SEND #endif @@ -128,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 */ @@ -138,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; @@ -192,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); @@ -418,6 +420,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]); @@ -483,3 +486,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/iconv_fread.c b/src/tds/unittests/iconv_fread.c index 4911dc63d6..63b451330f 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 */ @@ -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/log_elision.c b/src/tds/unittests/log_elision.c index 1d737f9494..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,9 @@ #include #endif /* HAVE_UNISTD_H */ +#include + +#ifdef TDS_HAVE_MUTEX enum { LOOP = 100, THREADS = 3, @@ -142,3 +144,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/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..84dcbd4d2d 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 @@ -28,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; @@ -100,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: @@ -130,7 +132,7 @@ main(void) } } } - row_count++; + /* row_count++; */ case TDS_COMPUTE_RESULT: break; default: diff --git a/src/tds/unittests/t0007.c b/src/tds/unittests/t0007.c index 3f25f24753..4c990ea222 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 @@ -397,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 fe15d787c1..85f2374802 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; @@ -43,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/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..1f311a2d18 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; @@ -196,11 +197,11 @@ main(void) if (IS_TDS7_PLUS(tds->conn)) { char type[32]; char buf[1024]; - int 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_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..7db16a9cea 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; @@ -31,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; @@ -66,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; @@ -82,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/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"; diff --git a/src/tds/vstrbuild.c b/src/tds/vstrbuild.c index 32274e941d..17ac78d67c 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; @@ -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; } diff --git a/src/tds/write.c b/src/tds/write.c index 7cc4a041a8..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,8 +139,9 @@ 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); - return w.written; + tds_convert_stream(tds, tds->conn->char_convs[iconv_entry], to_server, + &r.stream, &w.stream); + return (int) w.written; } int 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 \ 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++) { 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 cfe38bac46..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 @@ -35,11 +34,14 @@ #endif #include "tds_sysdep_public.h" +#include #include #include #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) {