2323#include <stdarg.h>
2424#include <stdio.h>
2525#include <assert.h>
26+ #include <ctype.h>
2627
2728#if HAVE_STRING_H
2829#include <string.h>
@@ -1053,8 +1054,10 @@ _bcp_check_eof(DBPROCESS * dbproc, FILE *file, int icol)
10531054 * Convert column for input to a table
10541055 */
10551056static TDSRET
1056- _bcp_convert_in (DBPROCESS * dbproc , TDS_SERVER_TYPE srctype , const TDS_CHAR * src , TDS_UINT srclen ,
1057- TDS_SERVER_TYPE desttype , BCPCOLDATA * coldata )
1057+ _bcp_convert_in (DBPROCESS * dbproc , TDS_SERVER_TYPE srctype ,
1058+ const TDS_CHAR * src , TDS_UINT srclen ,
1059+ TDS_SERVER_TYPE desttype , BCPCOLDATA * coldata ,
1060+ TDS_UINT destlen )
10581061{
10591062 bool variable = true;
10601063 CONV_RESULT cr , * p_cr ;
@@ -1070,9 +1073,45 @@ _bcp_convert_in(DBPROCESS *dbproc, TDS_SERVER_TYPE srctype, const TDS_CHAR *src,
10701073 }
10711074
10721075 len = tds_convert (dbproc -> tds_socket -> conn -> tds_ctx , srctype , src , srclen , desttype , p_cr );
1076+ if (len == TDS_CONVERT_SYNTAX && is_binary_type (desttype )) {
1077+ char * s = (char * ) src ;
1078+ int srclen2 = destlen * 2 ;
1079+ if (srclen > 1 && s [0 ] == '0' && (s [1 ] == 'x' || s [1 ] == 'X' ))
1080+ srclen2 += 2 ;
1081+ /* Match full input's low order bit to get correct phase. */
1082+ if (srclen & 1 )
1083+ -- srclen2 ;
1084+ if (srclen2 < srclen ) {
1085+ len = tds_convert (dbproc -> tds_socket -> conn -> tds_ctx ,
1086+ srctype , src , srclen2 , desttype ,
1087+ p_cr );
1088+ }
1089+ /*
1090+ * Check the last character to avoid interference from
1091+ * space and NUL stripping.
1092+ */
1093+ if (len == destlen && isxdigit (s [srclen2 - 1 ])) {
1094+ free (p_cr -> ib );
1095+ dbperror (dbproc , SYBECOFL , 0 );
1096+ return TDS_FAIL ;
1097+ } else {
1098+ if (len >= 0 )
1099+ free (p_cr -> ib );
1100+ len = TDS_CONVERT_SYNTAX ;
1101+ }
1102+ }
10731103 if (len < 0 ) {
10741104 _dblib_convert_err (dbproc , len );
10751105 return TDS_FAIL ;
1106+ } else if (len > destlen ) {
1107+ if ((is_binary_type (srctype ) && is_binary_type (desttype ))
1108+ || (is_char_type (srctype ) && is_char_type (desttype ))) {
1109+ dbperror (dbproc , SYBEBCOR , 0 );
1110+ /* Proceed anyway */
1111+ } else {
1112+ dbperror (dbproc , SYBECOFL , 0 );
1113+ return TDS_FAIL ;
1114+ }
10761115 }
10771116
10781117 coldata -> datalen = len ;
@@ -1336,8 +1375,11 @@ _bcp_read_hostfile(DBPROCESS * dbproc, FILE * hostfile, bool *row_error, bool sk
13361375
13371376 desttype = tds_get_conversion_type (bcpcol -> column_type , bcpcol -> column_size );
13381377
1339- rc = _bcp_convert_in (dbproc , hostcol -> datatype , (const TDS_CHAR * ) coldata , collen ,
1340- desttype , bcpcol -> bcp_column_data );
1378+ rc = _bcp_convert_in (dbproc , hostcol -> datatype ,
1379+ (const TDS_CHAR * ) coldata ,
1380+ collen , desttype ,
1381+ bcpcol -> bcp_column_data ,
1382+ bcpcol -> column_size );
13411383 if (TDS_FAILED (rc )) {
13421384 hostcol -> column_error = HOST_COL_CONV_ERROR ;
13431385 * row_error = true;
@@ -2258,8 +2300,9 @@ _bcp_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset TDS_UNUSED
22582300 if (collen < 0 )
22592301 collen = (int ) strlen ((char * ) dataptr );
22602302
2261- rc = _bcp_convert_in (dbproc , coltype , (const TDS_CHAR * ) dataptr , collen ,
2262- desttype , bindcol -> bcp_column_data );
2303+ rc = _bcp_convert_in (dbproc , coltype , (const TDS_CHAR * ) dataptr ,
2304+ collen , desttype , bindcol -> bcp_column_data ,
2305+ bindcol -> column_size );
22632306 if (TDS_FAILED (rc ))
22642307 return rc ;
22652308 rtrim_bcpcol (bindcol );
0 commit comments