+Attempted fix of bug #976: Segfault in yaz_iconv. The yaz_iconv function
+write handlers no longer carries a 'last' parameter. This will make
+yaz_iconv flush "less" characters. A flush is performed by call to
+yaz_iconv(cd, 0, 0, &outbut, &outbytesleft) .
+
Definition of wrbuf_diags moved to querytowrbuf.h. Function wrbuf_put_zquery
removed, because function yaz_query_to_wrbuf does the same.
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* $Id: wrbuf.h,v 1.25 2007-03-19 14:40:06 adam Exp $ */
+/* $Id: wrbuf.h,v 1.26 2007-03-20 21:37:31 adam Exp $ */
/**
* \file wrbuf.h
YAZ_EXPORT int wrbuf_iconv_putchar(WRBUF b, yaz_iconv_t cd, int ch);
+YAZ_EXPORT void wrbuf_iconv_reset(WRBUF b, yaz_iconv_t cd);
+
YAZ_EXPORT void wrbuf_chop_right(WRBUF b);
/** \brief cut size of WRBUF */
* Copyright (C) 1995-2007, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: marcdisp.c,v 1.48 2007-03-19 14:40:07 adam Exp $
+ * $Id: marcdisp.c,v 1.49 2007-03-20 21:37:32 adam Exp $
*/
/**
static void marc_iconv_reset(yaz_marc_t mt, WRBUF wr)
{
- if (mt->iconv_cd)
- {
- char outbuf[12];
- size_t outbytesleft = sizeof(outbuf);
- char *outp = outbuf;
- size_t r = yaz_iconv(mt->iconv_cd, 0, 0, &outp, &outbytesleft);
- if (r != (size_t) (-1))
- wrbuf_write(wr, outbuf, outp - outbuf);
- }
+ wrbuf_iconv_reset(wr, mt->iconv_cd);
}
static int marc_exec_leader(const char *leader_spec, char *leader,
wrbuf_puts(wr, "(");
wrbuf_iconv_write(wr, mt->iconv_cd,
n->u.comment, strlen(n->u.comment));
+ marc_iconv_reset(mt, wr);
wrbuf_puts(wr, ")\n");
break;
case YAZ_MARC_LEADER:
}
/* write dummy FS (makes MARC-8 to become ASCII) */
wrbuf_iconv_putchar(wr_data_tmp, mt->iconv_cd, ' ');
+ marc_iconv_reset(mt, wr_data_tmp);
data_length += wrbuf_len(wr_data_tmp);
break;
case YAZ_MARC_CONTROLFIELD:
n->u.controlfield.data);
marc_iconv_reset(mt, wr_data_tmp);
wrbuf_iconv_putchar(wr_data_tmp, mt->iconv_cd, ' ');/* field sep */
+ marc_iconv_reset(mt, wr_data_tmp);
data_length += wrbuf_len(wr_data_tmp);
break;
case YAZ_MARC_COMMENT:
* Copyright (C) 1995-2007, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: siconv.c,v 1.36 2007-03-17 00:10:40 adam Exp $
+ * $Id: siconv.c,v 1.37 2007-03-20 21:37:32 adam Exp $
*/
/**
* \file siconv.c
unsigned long (*read_handle)(yaz_iconv_t cd, unsigned char *inbuf,
size_t inbytesleft, size_t *no_read);
size_t (*write_handle)(yaz_iconv_t cd, unsigned long x,
- char **outbuf, size_t *outbytesleft,
- int last);
+ char **outbuf, size_t *outbytesleft);
size_t (*flush_handle)(yaz_iconv_t cd,
char **outbuf, size_t *outbytesleft);
int marc8_esc_mode;
}
static size_t yaz_write_advancegreek(yaz_iconv_t cd, unsigned long x,
- char **outbuf, size_t *outbytesleft,
- int last)
+ char **outbuf, size_t *outbytesleft)
{
size_t k = 0;
unsigned char *out = (unsigned char*) *outbuf;
}
static size_t yaz_write_UTF8(yaz_iconv_t cd, unsigned long x,
- char **outbuf, size_t *outbytesleft,
- int last)
+ char **outbuf, size_t *outbytesleft)
{
return yaz_write_UTF8_char(x, outbuf, outbytesleft, &cd->my_errno);
}
return 0;
}
-
static size_t yaz_write_ISO8859_1 (yaz_iconv_t cd, unsigned long x,
- char **outbuf, size_t *outbytesleft,
- int last)
+ char **outbuf, size_t *outbytesleft)
{
/* list of two char unicode sequence that, when combined, are
equivalent to single unicode chars that can be represented in
cd->compose_char = 0;
}
- if (!last && x > 32 && x < 127 && cd->compose_char == 0)
+ if (x > 32 && x < 127 && cd->compose_char == 0)
{
cd->compose_char = x;
return 0;
return 0;
}
+static size_t yaz_flush_ISO8859_1(yaz_iconv_t cd,
+ char **outbuf, size_t *outbytesleft)
+{
+ if (cd->compose_char)
+ {
+ unsigned char *outp = (unsigned char *) *outbuf;
+ if (*outbytesleft < 1)
+ {
+ cd->my_errno = YAZ_ICONV_E2BIG;
+ return (size_t)(-1);
+ }
+ *outp++ = (unsigned char) cd->compose_char;
+ (*outbytesleft)--;
+ *outbuf = (char *) outp;
+ cd->compose_char = 0;
+ }
+ return 0;
+}
static size_t yaz_write_UCS4 (yaz_iconv_t cd, unsigned long x,
- char **outbuf, size_t *outbytesleft,
- int last)
+ char **outbuf, size_t *outbytesleft)
{
unsigned char *outp = (unsigned char *) *outbuf;
if (*outbytesleft >= 4)
}
static size_t yaz_write_UCS4LE (yaz_iconv_t cd, unsigned long x,
- char **outbuf, size_t *outbytesleft,
- int last)
+ char **outbuf, size_t *outbytesleft)
{
unsigned char *outp = (unsigned char *) *outbuf;
if (*outbytesleft >= 4)
char *utf8_outbuf = utf8_buf;
size_t utf8_outbytesleft = sizeof(utf8_buf)-1, r;
- r = yaz_write_UTF8(cd, x, &utf8_outbuf, &utf8_outbytesleft, 0);
+ r = yaz_write_UTF8(cd, x, &utf8_outbuf, &utf8_outbytesleft);
if (r == (size_t)(-1))
{
cd->my_errno = YAZ_ICONV_EILSEQ;
static size_t yaz_write_marc8_2(yaz_iconv_t cd, unsigned long x,
- char **outbuf, size_t *outbytesleft,
- int last)
+ char **outbuf, size_t *outbytesleft)
{
int comb = 0;
const char *page_chr = 0;
return r;
cd->write_marc8_last = y;
}
- if (last)
- {
- size_t r = flush_combos(cd, outbuf, outbytesleft);
- if (r)
- {
- if (comb)
- cd->write_marc8_comb_no--;
- else
- cd->write_marc8_last = 0;
- return r;
- }
- }
return 0;
}
}
static size_t yaz_write_marc8(yaz_iconv_t cd, unsigned long x,
- char **outbuf, size_t *outbytesleft,
- int last)
+ char **outbuf, size_t *outbytesleft)
{
int i;
for (i = 0; latin1_comb[i].x1; i++)
int last_ch = cd->write_marc8_last;
r = yaz_write_marc8_2(cd, latin1_comb[i].x1,
- outbuf, outbytesleft, 0);
+ outbuf, outbytesleft);
if (r)
return r;
r = yaz_write_marc8_2(cd, latin1_comb[i].x2,
- outbuf, outbytesleft, last);
+ outbuf, outbytesleft);
if (r && cd->my_errno == YAZ_ICONV_E2BIG)
{
/* not enough room. reset output to original values */
return r;
}
}
- return yaz_write_marc8_2(cd, x, outbuf, outbytesleft, last);
+ return yaz_write_marc8_2(cd, x, outbuf, outbytesleft);
}
#if HAVE_WCHAR_H
-static size_t yaz_write_wchar_t (yaz_iconv_t cd, unsigned long x,
- char **outbuf, size_t *outbytesleft,
- int last)
+static size_t yaz_write_wchar_t(yaz_iconv_t cd, unsigned long x,
+ char **outbuf, size_t *outbytesleft)
{
unsigned char *outp = (unsigned char *) *outbuf;
if (!yaz_matchstr(tocode, "UTF8"))
cd->write_handle = yaz_write_UTF8;
else if (!yaz_matchstr(tocode, "ISO88591"))
+ {
cd->write_handle = yaz_write_ISO8859_1;
+ cd->flush_handle = yaz_flush_ISO8859_1;
+ }
else if (!yaz_matchstr (tocode, "UCS4"))
cd->write_handle = yaz_write_UCS4;
else if (!yaz_matchstr(tocode, "UCS4LE"))
}
cd->init_flag = 0;
+ if (!inbuf || !*inbuf)
+ {
+ if (outbuf && *outbuf)
+ {
+ if (cd->unget_x)
+ r = (*cd->write_handle)(cd, cd->unget_x, outbuf, outbytesleft);
+ if (cd->flush_handle)
+ r = (*cd->flush_handle)(cd, outbuf, outbytesleft);
+ }
+ if (r == 0)
+ cd->init_flag = 1;
+ cd->unget_x = 0;
+ return r;
+ }
while (1)
{
unsigned long x;
x = cd->unget_x;
no_read = cd->no_read_x;
}
- else if (inbuf && *inbuf)
+ else
{
if (*inbytesleft == 0)
{
r = *inbuf - inbuf0;
break;
}
- x = (cd->read_handle)(cd, (unsigned char *) *inbuf, *inbytesleft,
- &no_read);
+ x = (*cd->read_handle)(cd, (unsigned char *) *inbuf, *inbytesleft,
+ &no_read);
if (no_read == 0)
{
r = (size_t)(-1);
break;
}
}
- else
- {
- r = 0;
- if (cd->flush_handle && outbuf && *outbuf)
- r = (*cd->flush_handle)(cd, outbuf, outbytesleft);
- if (r == 0)
- cd->init_flag = 1;
- break;
- }
if (x)
{
- r = (cd->write_handle)(cd, x, outbuf, outbytesleft,
- (*inbytesleft - no_read) == 0 ? 1 : 0);
+ r = (*cd->write_handle)(cd, x, outbuf, outbytesleft);
if (r)
{
/* unable to write it. save it because read_handle cannot
* Copyright (C) 1995-2007, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: wrbuf.c,v 1.18 2007-03-19 14:40:07 adam Exp $
+ * $Id: wrbuf.c,v 1.19 2007-03-20 21:37:32 adam Exp $
*/
/**
return wrbuf_iconv_write_x(b, cd, buf, size, 1);
}
+void wrbuf_iconv_reset(WRBUF b, yaz_iconv_t cd)
+{
+ if (cd)
+ {
+ char outbuf[12];
+ size_t outbytesleft = sizeof(outbuf);
+ char *outp = outbuf;
+ size_t r = yaz_iconv(cd, 0, 0, &outp, &outbytesleft);
+ if (r != (size_t) (-1))
+ wrbuf_write(b, outbuf, outp - outbuf);
+ }
+}
+
const char *wrbuf_cstr(WRBUF b)
{
wrbuf_putc(b, '\0'); /* add '\0' */
* Copyright (C) 1995-2007, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: zoom-c.c,v 1.118 2007-03-19 20:58:34 adam Exp $
+ * $Id: zoom-c.c,v 1.119 2007-03-20 21:37:32 adam Exp $
*/
/**
* \file zoom-c.c
odr_prepend(c->odr_out, "ZOOM-C",
ireq->implementationName));
- version = odr_strdup(c->odr_out, "$Revision: 1.118 $");
+ version = odr_strdup(c->odr_out, "$Revision: 1.119 $");
if (strlen(version) > 10) /* check for unexpanded CVS strings */
version[strlen(version)-2] = '\0';
ireq->implementationVersion =
*from = '\0';
strcpy(to, "UTF-8");
+
if (record_charset && *record_charset)
{
/* Use "from,to" or just "from" */
if (*from && *to && (cd = yaz_iconv_open(to, from)))
{
- char outbuf[12];
- size_t inbytesleft = sz;
- const char *inp = buf;
-
if (!rec->wrbuf_iconv)
rec->wrbuf_iconv = wrbuf_alloc();
wrbuf_rewind(rec->wrbuf_iconv);
- while (inbytesleft)
- {
- size_t outbytesleft = sizeof(outbuf);
- char *outp = outbuf;
- size_t r = yaz_iconv(cd, (char**) &inp,
- &inbytesleft,
- &outp, &outbytesleft);
- if (r == (size_t) (-1))
- {
- int e = yaz_iconv_error(cd);
- if (e != YAZ_ICONV_E2BIG)
- break;
- }
- wrbuf_write(rec->wrbuf_iconv, outbuf, outp - outbuf);
- }
+ wrbuf_iconv_write(rec->wrbuf_iconv, cd, buf, sz);
+ wrbuf_iconv_reset(rec->wrbuf_iconv, cd);
+
buf = wrbuf_cstr(rec->wrbuf_iconv);
sz = wrbuf_len(rec->wrbuf_iconv);
yaz_iconv_close(cd);
* Copyright (C) 2005-2007, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: tst_record_conv.c,v 1.15 2007-03-19 22:17:41 adam Exp $
+ * $Id: tst_record_conv.c,v 1.16 2007-03-20 21:37:32 adam Exp $
*
*/
#include <yaz/record_conv.h>
else if (strcmp(output_expect_record, wrbuf_cstr(output_record)))
{
ret = 0;
- printf("got-output_record = %s\n", wrbuf_cstr(output_record));
- printf("output_expect_record = %s\n", output_expect_record);
+ printf("got-output_record len=%d: %s\n",
+ wrbuf_len(output_record),wrbuf_cstr(output_record));
+ printf("output_expect_record len=%d %s\n",
+ strlen(output_expect_record), output_expect_record);
}
else
{
* Copyright (C) 1995-2007, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: tsticonv.c,v 1.28 2007-03-19 14:40:07 adam Exp $
+ * $Id: tsticonv.c,v 1.29 2007-03-20 21:37:32 adam Exp $
*/
#if HAVE_CONFIG_H
return 0;
}
else
+ {
+ yaz_iconv(cd, 0, 0, &outbuf, &outbytesleft);
break;
+ }
}
+
return compare_buffers("tsticonv 22", 0,
expect_len, expect_buf,
outbuf - outbuf0, outbuf0);
if (e != YAZ_ICONV_E2BIG)
break;
}
+ else
+ {
+ size_t outbytesleft = sizeof(outbuf);
+ char *outp = outbuf;
+ r = yaz_iconv(cd, 0, 0, &outp, &outbytesleft);
+ wrbuf_write(b, outbuf, outp - outbuf);
+ break;
+ }
}
if (wrbuf_len(b) == strlen(cmpbuf)
&& !memcmp(cmpbuf, wrbuf_buf(b), wrbuf_len(b)))
return;
r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
YAZ_CHECK(r != (size_t) (-1));
+
+ r = yaz_iconv(cd, 0, 0, &outbuf, &outbytesleft);
+ YAZ_CHECK(r != (size_t) (-1));
yaz_iconv_close(cd);
if (r == (size_t) (-1))
return;
outbytesleft = sizeof(outbuf1);
r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
YAZ_CHECK(r != (size_t) (-1));
+
+ r = yaz_iconv(cd, 0, 0, &outbuf, &outbytesleft);
+ if (r == (size_t)(-1))
+ {
+ fprintf(stderr, "failed\n");
+ }
+ YAZ_CHECK(r != (size_t) (-1));
+
if (r != (size_t)(-1))
{
ret = compare_buffers("dconvert", i,
strlen(iso_8859_1_a[i]), iso_8859_1_a[i],
- sizeof(outbuf1) - outbytesleft, outbuf1);
+ sizeof(outbuf1) - outbytesleft, outbuf1);
YAZ_CHECK(ret);
}
yaz_iconv_close(cd);