From 21193c8eeba6d03f680ad34acbbb4cff14d87809 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Mar 2011 18:13:05 -0700 Subject: Don't burn 2k of stack on every iconv, use the heap when it's a slow call. Autobuild-User: Jeremy Allison Autobuild-Date: Thu Mar 31 04:09:09 CEST 2011 on sn-devel-104 --- lib/util/charset/iconv.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/util/charset/iconv.c b/lib/util/charset/iconv.c index e3cdbdfc8e..24434ec809 100644 --- a/lib/util/charset/iconv.c +++ b/lib/util/charset/iconv.c @@ -164,32 +164,41 @@ _PUBLIC_ size_t smb_iconv(smb_iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { - char cvtbuf[2048]; - size_t bufsize; - /* in many cases we can go direct */ if (cd->direct) { return cd->direct(cd->cd_direct, inbuf, inbytesleft, outbuf, outbytesleft); } - /* otherwise we have to do it chunks at a time */ - while (*inbytesleft > 0) { - char *bufp1 = cvtbuf; - const char *bufp2 = cvtbuf; + { +#ifndef SMB_ICONV_BUFSIZE +#define SMB_ICONV_BUFSIZE 2048 +#endif + size_t bufsize; + char *cvtbuf = talloc_array(cd, char, SMB_ICONV_BUFSIZE); - bufsize = sizeof(cvtbuf); - - if (cd->pull(cd->cd_pull, - inbuf, inbytesleft, &bufp1, &bufsize) == -1 - && errno != E2BIG) return -1; + if (!cvtbuf) { + return (size_t)-1; + } - bufsize = sizeof(cvtbuf) - bufsize; + while (*inbytesleft > 0) { + char *bufp1 = cvtbuf; + const char *bufp2 = cvtbuf; - if (cd->push(cd->cd_push, - &bufp2, &bufsize, - outbuf, outbytesleft) == -1) return -1; + bufsize = SMB_ICONV_BUFSIZE; + + if (cd->pull(cd->cd_pull, + inbuf, inbytesleft, &bufp1, &bufsize) == -1 + && errno != E2BIG) return -1; + + bufsize = SMB_ICONV_BUFSIZE - bufsize; + + if (cd->push(cd->cd_push, + &bufp2, &bufsize, + outbuf, outbytesleft) == -1) return -1; + } + talloc_free(cvtbuf); } return 0; -- cgit