[freetds] bcp is really busted
Christos Zoulas
christos at zoulas.com
Wed Dec 24 14:01:39 EST 2003
Hello,
Create a table with a single varchar(X) field.
insert five rows
1. fooo
2. bar
3. barfoo
4.
5. NULL
Copy the table into a file: notice the contents.
^D\0fooo^C\0bar^F\0barfoo\0\0\0\0
Obviously this will not work because the code does not differentiate
between the empty string and NULL. Look at the code: assumptions
everywhere about datalen == 0 being equivalent to NULL.
Try to copy the table back out. Notice it fails to insert anything,
and code goes to infinite loop, because it thinks that the length
of the field is always 0. Figure out the minimum change patch:
--- bcp.c.orig 2003-12-24 13:53:04.000000000 -0500
+++ bcp.c 2003-12-24 13:52:40.000000000 -0500
@@ -969,6 +969,17 @@
* 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;
+ }
coldata = (BYTE *) calloc(1, 1 + collen);
if (coldata == NULL) {
*row_error = TRUE;
Of course this does not fix the NULL problem; this would require a lot
more work, because we need to change the way we write and the way we
read.
Happy Holidays,
christos
More information about the FreeTDS
mailing list