Don't burn 2k of stack on every iconv, use the heap when it's a slow call.
authorJeremy Allison <jra@samba.org>
Thu, 31 Mar 2011 01:13:05 +0000 (18:13 -0700)
committerJeremy Allison <jra@samba.org>
Thu, 31 Mar 2011 02:09:09 +0000 (04:09 +0200)
Autobuild-User: Jeremy Allison <jra@samba.org>
Autobuild-Date: Thu Mar 31 04:09:09 CEST 2011 on sn-devel-104

lib/util/charset/iconv.c

index e3cdbdfc8eff9d7b1efda1775ddecee02fedbea1..24434ec809c910a22259678710b062c8386bfcb7 100644 (file)
@@ -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;