[freetds] Status: 0.62rc2

Christos Zoulas christos at zoulas.com
Mon Jan 5 09:18:56 EST 2004


On Jan 5,  2:43pm, freddyz77 at tin.it (Frediano Ziglio) wrote:
-- Subject: Re: [freetds] Status: 0.62rc2

| bcp_sendrow use a fixed size buffer, _bcp_add_variable_columns does not
| detect null and copy from an invalid address. Both issues are really
| bad...

Try this patch. Sorry I don't have sybase...

--- ./bcp.c.orig	2003-12-24 13:53:04.000000000 -0500
+++ ./bcp.c	2004-01-05 09:17:39.000000000 -0500
@@ -587,7 +587,7 @@
 
 				/* null columns have zero output */
 				if (tds_get_null(resinfo->current_row, bcpcol->tab_colnum - 1))
-					bcpcol->data_size = 0;
+					bcpcol->data_size = -1;
 				else
 					bcpcol->data_size = curcol->column_cur_size;
 
@@ -732,7 +732,10 @@
 					 * For null columns, the above work to determine the output buffer size is moot, 
 					 * because bcpcol->data_size is zero, so dbconvert() won't write anything, and returns zero. 
 					 */
-					buflen = dbconvert(dbproc,
+					if (bcpcol->data_size == -1)
+						buflen = -1;
+					else
+						buflen = dbconvert(dbproc,
 							   bcpcol->db_type,
 							   bcpcol->data, bcpcol->data_size, hostcol->datatype, outbuf, destlen);
 
@@ -782,7 +785,8 @@
 					buflen = buflen > hostcol->column_len ? hostcol->column_len : buflen;
 				}
 
-				fwrite(outbuf, buflen, 1, hostfile);
+				if (buflen > 0)
+					fwrite(outbuf, buflen, 1, hostfile);
 
 				free(outbuf);
 
@@ -868,9 +872,10 @@
 				break;
 			}
 
-			if (collen == 0)
+			if (collen == -1) {
 				data_is_null = 1;
-
+				collen = 0;
+			}
 		}
 
 		/* if (Max) column length specified take that into consideration. */
@@ -923,7 +928,9 @@
 				tdsdump_log(TDS_DBG_FUNC, "_bcp_measure_terminated_field returned -1!\n");
 				/* FIXME emit message? _bcp_err_handler(dbproc, SYBEMEM); */
 				return (FAIL);
-			}
+			} else if (collen == 0)
+				data_is_null = 1;
+
 
 			tdsdump_log(TDS_DBG_FUNC, "_bcp_measure_terminated_field returned %d\n", collen);
 			/* 
@@ -969,6 +976,21 @@
 			 *      because English dates expressed as UTF-8 strings are indistinguishable from the ASCII.  
 			 */
 		} else {	/* unterminated field */
+			bcpcol = dbproc->bcp.db_columns[hostcol->tab_colnum - 1];
+			if (collen == 0 && (is_nullable_type(bcpcol->db_type)
+			    || bcpcol->db_nullable)) {
+				TDS_SMALLINT len;
+				if (fread(&len, sizeof(len), 1, hostfile) != 1) {
+					if (i != 0)
+						_bcp_err_handler(dbproc, SYBEBCRE);
+					return (FAIL);
+				}
+				collen = len;
+				if (collen == -1) {
+					collen = 0;
+					data_is_null = 1;
+				}
+			}
 			coldata = (BYTE *) calloc(1, 1 + collen);
 			if (coldata == NULL) {
 				*row_error = TRUE;
@@ -1001,7 +1023,7 @@
 		 */
 		if (hostcol->tab_colnum) {
 			if (data_is_null) {
-				bcpcol->data_size = 0;
+				bcpcol->data_size = -1;
 			} else {
 				desttype = tds_get_conversion_type(bcpcol->db_type, bcpcol->db_length);
 
@@ -1046,7 +1068,7 @@
 					bcpcol->data_size = converted_data_size;
 				}
 			}
-			if (bcpcol->data_size == 0) {	/* Are we trying to insert a NULL ? */
+			if (bcpcol->data_size == -1) {	/* Are we trying to insert a NULL ? */
 				if (!bcpcol->db_nullable) {
 					/* too bad if the column is not nullable */
 					hostcol->column_error = HOST_COL_NULL_ERROR;
@@ -1165,7 +1187,7 @@
 
 		if (!is_nullable_type(bcpcol->db_type) && !(bcpcol->db_nullable)) {
 
-			if (!(bcpcol->db_nullable) && bcpcol->data_size == 0) {
+			if (!(bcpcol->db_nullable) && bcpcol->data_size == -1) {
 				_bcp_err_handler(dbproc, SYBEBCNN);
 				return FAIL;
 			}
@@ -1235,7 +1257,7 @@
 			/* but if its a NOT NULL column, and we have no data */
 			/* throw an error                                    */
 
-			if (!(bcpcol->db_nullable) && bcpcol->data_size == 0) {
+			if (!(bcpcol->db_nullable) && bcpcol->data_size == -1) {
 				_bcp_err_handler(dbproc, SYBEBCNN);
 				return FAIL;
 			}
@@ -1249,9 +1271,12 @@
 				memcpy(&rowbuffer[row_pos], num->array, cpbytes);
 			} else {
 				/* compute the length to copy to the row ** buffer */
-
-				cpbytes = bcpcol->data_size > bcpcol->db_length ? bcpcol->db_length : bcpcol->data_size;
-				memcpy(&rowbuffer[row_pos], bcpcol->data, cpbytes);
+				if (bcpcol->data_size == -1) {
+					cpbytes = 0;
+				} else {
+					cpbytes = bcpcol->data_size > bcpcol->db_length ? bcpcol->db_length : bcpcol->data_size;
+					memcpy(&rowbuffer[row_pos], bcpcol->data, cpbytes);
+				}
 
 			}
 
@@ -2508,7 +2533,7 @@
 
 			if (hostcol->tab_colnum) {
 				if (data_is_null) {
-					bcpcol->data_size = 0;
+					bcpcol->data_size = -1;
 				} else {
 					desttype = tds_get_conversion_type(bcpcol->db_type, bcpcol->db_length);
 
@@ -2526,7 +2551,7 @@
 
 			if (hostcol->tab_colnum) {
 				if (data_is_null) {
-					bcpcol->data_size = 0;
+					bcpcol->data_size = -1;
 				} else {
 					desttype = tds_get_conversion_type(bcpcol->db_type, bcpcol->db_length);
 
@@ -2542,7 +2567,7 @@
 			}
 		}
 
-		if (bcpcol->data_size == 0) {	/* Are we trying to insert a NULL? */
+		if (bcpcol->data_size == -1) {	/* Are we trying to insert a NULL? */
 			if (!bcpcol->db_nullable) {
 				/* too bad if the column is not nullable */
 				_bcp_err_handler(dbproc, SYBEBCNN);


More information about the FreeTDS mailing list