mirror of
https://github.com/mirror/wget.git
synced 2026-09-05 22:24:56 +08:00
* src/url.c (convert_fname): Fix invalid free on iconv_open() failure
Reported-by: Volkmar Klatt
This commit is contained in:
112
src/url.c
112
src/url.c
@@ -1551,13 +1551,13 @@ append_uri_pathel (const char *b, const char *e, bool escaped,
|
||||
static char *
|
||||
convert_fname (char *fname)
|
||||
{
|
||||
char *converted_fname = fname;
|
||||
char *converted_fname;
|
||||
const char *from_encoding = opt.encoding_remote;
|
||||
const char *to_encoding = opt.locale;
|
||||
iconv_t cd;
|
||||
size_t len, done, inlen, outlen;
|
||||
char *s;
|
||||
const char *orig_fname = fname;
|
||||
const char *orig_fname;
|
||||
|
||||
/* Defaults for remote and local encodings. */
|
||||
if (!from_encoding)
|
||||
@@ -1567,62 +1567,64 @@ convert_fname (char *fname)
|
||||
|
||||
cd = iconv_open (to_encoding, from_encoding);
|
||||
if (cd == (iconv_t) (-1))
|
||||
logprintf (LOG_VERBOSE, _ ("Conversion from %s to %s isn't supported\n"),
|
||||
quote (from_encoding), quote (to_encoding));
|
||||
else
|
||||
{
|
||||
inlen = strlen (fname);
|
||||
len = outlen = inlen * 2;
|
||||
converted_fname = s = xmalloc (outlen + 1);
|
||||
done = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
errno = 0;
|
||||
if (iconv (cd, (ICONV_CONST char **) &fname, &inlen, &s, &outlen) == 0
|
||||
&& iconv (cd, NULL, NULL, &s, &outlen) == 0)
|
||||
{
|
||||
*(converted_fname + len - outlen - done) = '\0';
|
||||
iconv_close (cd);
|
||||
DEBUGP (("Converted file name '%s' (%s) -> '%s' (%s)\n",
|
||||
orig_fname, from_encoding, converted_fname, to_encoding));
|
||||
xfree (orig_fname);
|
||||
return converted_fname;
|
||||
}
|
||||
|
||||
/* Incomplete or invalid multibyte sequence */
|
||||
if (errno == EINVAL || errno == EILSEQ || errno == 0)
|
||||
{
|
||||
if (errno)
|
||||
logprintf (LOG_VERBOSE,
|
||||
_ ("Incomplete or invalid multibyte sequence encountered\n"));
|
||||
else
|
||||
logprintf (LOG_VERBOSE,
|
||||
_ ("Unconvertable multibyte sequence encountered\n"));
|
||||
xfree (converted_fname);
|
||||
converted_fname = (char *) orig_fname;
|
||||
break;
|
||||
}
|
||||
else if (errno == E2BIG) /* Output buffer full */
|
||||
{
|
||||
done = len;
|
||||
len = outlen = done + inlen * 2;
|
||||
converted_fname = xrealloc (converted_fname, outlen + 1);
|
||||
s = converted_fname + done;
|
||||
}
|
||||
else /* Weird, we got an unspecified error */
|
||||
{
|
||||
logprintf (LOG_VERBOSE, _ ("Unhandled errno %d\n"), errno);
|
||||
xfree (converted_fname);
|
||||
converted_fname = (char *) orig_fname;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DEBUGP (("Failed to convert file name '%s' (%s) -> '?' (%s)\n",
|
||||
orig_fname, from_encoding, to_encoding));
|
||||
logprintf (LOG_VERBOSE, _ ("Conversion from %s to %s isn't supported\n"),
|
||||
quote (from_encoding), quote (to_encoding));
|
||||
return fname;
|
||||
}
|
||||
|
||||
iconv_close(cd);
|
||||
orig_fname = fname;
|
||||
inlen = strlen (fname);
|
||||
len = outlen = inlen * 2;
|
||||
converted_fname = s = xmalloc (outlen + 1);
|
||||
done = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
errno = 0;
|
||||
if (iconv (cd, (ICONV_CONST char **) &fname, &inlen, &s, &outlen) == 0
|
||||
&& iconv (cd, NULL, NULL, &s, &outlen) == 0)
|
||||
{
|
||||
*(converted_fname + len - outlen - done) = '\0';
|
||||
iconv_close (cd);
|
||||
DEBUGP (("Converted file name '%s' (%s) -> '%s' (%s)\n",
|
||||
orig_fname, from_encoding, converted_fname, to_encoding));
|
||||
xfree (orig_fname);
|
||||
return converted_fname;
|
||||
}
|
||||
|
||||
/* Incomplete or invalid multibyte sequence */
|
||||
if (errno == EINVAL || errno == EILSEQ || errno == 0)
|
||||
{
|
||||
if (errno)
|
||||
logprintf (LOG_VERBOSE,
|
||||
_ ("Incomplete or invalid multibyte sequence encountered\n"));
|
||||
else
|
||||
logprintf (LOG_VERBOSE,
|
||||
_ ("Unconvertable multibyte sequence encountered\n"));
|
||||
xfree (converted_fname);
|
||||
converted_fname = (char *) orig_fname;
|
||||
break;
|
||||
}
|
||||
else if (errno == E2BIG) /* Output buffer full */
|
||||
{
|
||||
done = len;
|
||||
len = outlen = done + inlen * 2;
|
||||
converted_fname = xrealloc (converted_fname, outlen + 1);
|
||||
s = converted_fname + done;
|
||||
}
|
||||
else /* Weird, we got an unspecified error */
|
||||
{
|
||||
logprintf (LOG_VERBOSE, _ ("Unhandled errno %d\n"), errno);
|
||||
xfree (converted_fname);
|
||||
converted_fname = (char *) orig_fname;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DEBUGP (("Failed to convert file name '%s' (%s) -> '?' (%s)\n",
|
||||
orig_fname, from_encoding, to_encoding));
|
||||
|
||||
iconv_close (cd);
|
||||
|
||||
return converted_fname;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user