rendered paste bodydiff --git a/src/lib/lightmediascanner_charset_conv.c b/src/lib/lightmediascanner_charset_conv.cindex 77b82aa..cfe3148 100644--- a/src/lib/lightmediascanner_charset_conv.c+++ b/src/lib/lightmediascanner_charset_conv.c@@ -26,7 +26,6 @@ #include <errno.h> struct lms_charset_conv {- iconv_t check; iconv_t fallback; unsigned int size; iconv_t *convs;@@ -53,16 +52,10 @@ lms_charset_conv_new(void) return NULL; } - lcc->check = iconv_open("UTF-8", "UTF-8");- if (lcc->check == (iconv_t)-1) {- perror("ERROR: could not create conversion checker");- goto error_check;- }- lcc->fallback = iconv_open("UTF-8//IGNORE", "UTF-8"); if (lcc->fallback == (iconv_t)-1) { perror("ERROR: could not create conversion fallback");- goto error_fallback;+ goto error; } lcc->size = 0;@@ -70,9 +63,7 @@ lms_charset_conv_new(void) lcc->names = NULL; return lcc; - error_fallback:- iconv_close(lcc->check);- error_check:+ error: free(lcc); return NULL;@@ -91,7 +82,6 @@ lms_charset_conv_free(lms_charset_conv_t *lcc) if (!lcc) return; - iconv_close(lcc->check); iconv_close(lcc->fallback); for (i = 0; i < lcc->size; i++) {@@ -224,51 +214,58 @@ lms_charset_conv_del(lms_charset_conv_t *lcc, const char *charset) } static int-_check(lms_charset_conv_t *lcc, const char *istr, unsigned int ilen, char *ostr, unsigned int olen)-{- char *inbuf, *outbuf;- size_t r, inlen, outlen;-- inbuf = (char *)istr;- inlen = ilen;- outbuf = ostr;- outlen = olen;-- iconv(lcc->check, NULL, NULL, NULL, NULL);- r = iconv(lcc->check, &inbuf, &inlen, &outbuf, &outlen);- if (r == (size_t)-1)- return -1;- else- return 0;-}--static int-_conv(iconv_t cd, char **p_str, unsigned int *p_len, char *ostr, unsigned int olen)+_conv(iconv_t cd, char **in, unsigned int *inlen, char **out, unsigned int *outlen) {- char *inbuf, *outbuf;- size_t r, inlen, outlen;-- inbuf = *p_str;- inlen = *p_len;- outbuf = ostr;- outlen = olen;+ char *inp, *outp;+ size_t inremain, outremain, outsize, r, used;+ int done = 0, have_error = 0;++ inp = *in;+ inremain = *inlen;+ outp = *out;+ outremain = *outlen;+ outsize = *outlen;++ while (!done && !have_error) {+ r = iconv(cd, &inp, &inremain, &outp, &outremain);+ if (r == (size_t)-1) {+ switch (errno) {+ case EINVAL:+ done = 1;+ break;+ case E2BIG:+ used = outp - *out;+ outsize *= 2;+ out = realloc(*out, outsize);+ if (!out) {+ perror("realloc");+ return -1;+ }+ outp = *out + used;+ outremain = outsize - used - 1;+ break;+ case EILSEQ:+ default:+ have_error = 1;+ break;+ }+ return -1;+ }+ else {+ break;+ }+ } - iconv(cd, NULL, NULL, NULL, NULL);- r = iconv(cd, &inbuf, &inlen, &outbuf, &outlen);- if (r == (size_t)-1)+ if (have_error) return -1; - *p_len = olen - outlen;- free(*p_str);- *p_str = ostr;+ *outp = '\0';+ *outlen = outp - *out; - outbuf = realloc(*p_str, *p_len + 1);- if (!outbuf)- perror("realloc");- else- *p_str = outbuf;+ free(*in); - (*p_str)[*p_len] = '\0';+ *inlen = inp - *in;+ *in = *out; return 0; }@@ -277,81 +274,44 @@ _conv(iconv_t cd, char **p_str, unsigned int *p_len, char *ostr, unsigned int ol * If required, do charset conversion to UTF-8. * * @param lcc existing Light Media Scanner charset conversion.- * @param p_str string to be converted.- * @param p_len string size.+ * @param in string to be converted.+ * @param inlen string size. * * @return On success 0 is returned. */ int-lms_charset_conv(lms_charset_conv_t *lcc, char **p_str, unsigned int *p_len)+lms_charset_conv(lms_charset_conv_t *lcc, char **in, unsigned int *inlen) {- char *outstr;+ char *out; int i, outlen; if (!lcc) return -1;- if (!p_str)+ if (!in) return -2;- if (!p_len)+ if (!inlen) return -3;- if (!*p_str || !*p_len)+ if (!*in || !*inlen) return 0; - outlen = 2 * *p_len;- outstr = malloc(outlen + 1);- if (!outstr) {+ outlen = 2 * *inlen;+ out = malloc(outlen + 1);+ if (!out) { perror("malloc"); return -4; } - if (_check(lcc, *p_str, *p_len, outstr, outlen) == 0) {- free(outstr);- return 0;- }- for (i = 0; i < lcc->size; i++)- if (_conv(lcc->convs[i], p_str, p_len, outstr, outlen) == 0)+ if (_conv(lcc->convs[i], in, inlen, &out, &outlen) == 0) return 0; fprintf(stderr, "WARNING: could not convert '%*s' to any charset, use fallback\n",- *p_len, *p_str);- i = _conv(lcc->fallback, p_str, p_len, outstr, outlen);+ *inlen, *in);+ i = _conv(lcc->fallback, in, inlen, &out, &outlen); if (i < 0) {- memset(*p_str, '?', *p_len);- free(outstr);+ memset(*in, '?', *inlen);+ free(out); } return i; }--/**- * Check if strings is not UTF-8 and conversion is required.- *- * @param lcc existing Light Media Scanner charset conversion.- * @param str string to be analysed.- * @param len string size.- *- * @return 0 if string is already UTF-8.- */-int-lms_charset_conv_check(lms_charset_conv_t *lcc, const char *str, unsigned int len)-{- char *outstr;- int r, outlen;-- if (!lcc)- return -1;- if (!str || !len)- return 0;-- outlen = 2 * len;- outstr = malloc(outlen);- if (!outstr) {- perror("malloc");- return -2;- }-- r = _check(lcc, str, len, outstr, outlen);- free(outstr);- return r;-}