Skip to Content.
Sympa Menu

freetds - Re: [freetds] FreeBCP -n causes SIGSEGV, -c fails on input

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "ZIGLIO, Frediano, VF-IT" <Frediano.Ziglio AT vodafone.com>
  • To: "FreeTDS Development Group" <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] FreeBCP -n causes SIGSEGV, -c fails on input
  • Date: Tue, 31 Jan 2006 14:22:32 +0100

>
> Thanks Mark,
>
> Funnily enough, I discovered this myself only yesterday.
> A fix is being worked on as we speak.
>
> I will have a look at reproducing your problem with the -c option.
> Could you specify the -e <error file> option ?
> It should give us more information on which columns/fields are causing
> the problem
>
> regards,
>
> Bill
>

Opps...


len = _bcp_measure_terminated_field(hostfile, hostcol->terminator,
hostcol->term_len);
if (len > 0x7fffffffl || len < 0) {
*row_error = TRUE;
tdsdump_log(TDS_DBG_FUNC, "_bcp_measure_terminated_field
returned -1!\n");
/* FIXME emit message? dbperror(dbproc, SYBEMEM, 0); */
return (FAIL);
}
collen = len;
if (collen == 0)
data_is_null = 1;


tdsdump_log(TDS_DBG_FUNC, "_bcp_measure_terminated_field returned %d\n",
collen);
/*
* Allocate a column buffer guaranteed to be big enough hold the
post-iconv data.
*/
if (bcpcol->char_conv) {
if (bcpcol->on_server.column_size > bcpcol->column_size)
collen = (collen * bcpcol->on_server.column_size) /
bcpcol->column_size;
cd = bcpcol->char_conv->to_wire;
tdsdump_log(TDS_DBG_FUNC, "Adjusted collen is %d.\n", collen);

} else {
cd = (iconv_t) - 1;
}

coldata = (BYTE *) calloc(1, 1 + collen);
if (coldata == NULL) {
*row_error = TRUE;
tdsdump_log(TDS_DBG_FUNC, "calloc returned NULL pointer!\n");
dbperror(dbproc, SYBEMEM, errno);
return (FAIL);
}

/*
* Read and convert the data
*/
col_bytes_left = collen;
/* TODO make tds_iconv_fread handle terminator directly to avoid fseek
in _bcp_measure_terminated_field */
file_bytes_left = tds_iconv_fread(cd, hostfile, collen,
hostcol->term_len, (TDS_CHAR *)coldata, &col_bytes_left);
collen -= col_bytes_left;


tds_iconv_fread should be called with character len not with allocated
bytes...

Now is much better :)

$ ./freebcp dbo.bcp_in_test in mao.txt -c -U test -S OPDN106 -P test -t
"@|@" -e err.txt

Starting copy...

3 rows copied.

I'm going to commit, patch

diff -u -1 -0 -r1.135.2.2 bcp.c
--- src/dblib/bcp.c 29 Jan 2006 21:56:24 -0000 1.135.2.2
+++ src/dblib/bcp.c 31 Jan 2006 13:20:50 -0000
@@ -1181,41 +1181,42 @@
if (is_fixed_type(hostcol->datatype)) {
collen =
tds_get_size_by_type(hostcol->datatype);
}

/*
* The data file either contains prefixes stating the
length, or is delimited.
* If delimited, we "measure" the field by looking for
the terminator, then read it,
* and set collen to the field's post-iconv size.
*/
if (hostcol->term_len > 0) { /* delimited data file */
- int file_bytes_left;
+ int file_bytes_left, file_len;
size_t col_bytes_left;
offset_type len;
iconv_t cd;

len = _bcp_measure_terminated_field(hostfile,
hostcol->terminator, hostcol->term_len);
if (len > 0x7fffffffl || len < 0) {
*row_error = TRUE;
tdsdump_log(TDS_DBG_FUNC,
"_bcp_measure_terminated_field returned -1!\n");
/* FIXME emit message? dbperror(dbproc,
SYBEMEM, 0); */
return (FAIL);
}
collen = len;
if (collen == 0)
data_is_null = 1;


tdsdump_log(TDS_DBG_FUNC,
"_bcp_measure_terminated_field returned %d\n", collen);
/*
* Allocate a column buffer guaranteed to be big
enough hold the post-iconv data.
*/
+ file_len = collen;
if (bcpcol->char_conv) {
if (bcpcol->on_server.column_size >
bcpcol->column_size)
collen = (collen *
bcpcol->on_server.column_size) / bcpcol->column_size;
cd = bcpcol->char_conv->to_wire;
tdsdump_log(TDS_DBG_FUNC, "Adjusted
collen is %d.\n", collen);

} else {
cd = (iconv_t) - 1;
}
@@ -1225,21 +1226,21 @@
tdsdump_log(TDS_DBG_FUNC, "calloc
returned NULL pointer!\n");
dbperror(dbproc, SYBEMEM, errno);
return (FAIL);
}

/*
* Read and convert the data
*/
col_bytes_left = collen;
/* TODO make tds_iconv_fread handle terminator
directly to avoid fseek in _bcp_measure_terminated_field */
- file_bytes_left = tds_iconv_fread(cd, hostfile,
collen, hostcol->term_len, (TDS_CHAR *)coldata, &col_bytes_left);
+ file_bytes_left = tds_iconv_fread(cd, hostfile,
file_len, hostcol->term_len, (TDS_CHAR *)coldata, &col_bytes_left);
collen -= col_bytes_left;

/* tdsdump_log(TDS_DBG_FUNC, "collen is %d after
tds_iconv_fread()\n", collen); */

if (file_bytes_left != 0) {
tdsdump_log(TDS_DBG_FUNC, "col %d: %d of
%d bytes unread\nfile_bytes_left != 0!\n",
(i+1),
file_bytes_left, collen);
*row_error = TRUE;
free(coldata);
return FAIL;


I noted that tds_iconv_fread is used only for BCP... I think that on
future release this function will handle terminator detection so to
remove limit to have a real file instead of a pipe...

freddy77




Archive powered by MHonArc 2.6.24.

Top of Page