diff options
Diffstat (limited to 'src/iconv.c')
-rw-r--r-- | src/iconv.c | 91 |
1 files changed, 49 insertions, 42 deletions
diff --git a/src/iconv.c b/src/iconv.c index dccd23b..45bd15f 100644 --- a/src/iconv.c +++ b/src/iconv.c @@ -67,6 +67,7 @@ iconv_t iconv_open(const char *tocode, const char *fromcode) char totemp[128], fromtemp[128]; const char *slash; unsigned int len; + eightbit_ret error; /* can't do anything without these */ if (!tocode || !fromcode) { @@ -184,60 +185,66 @@ iconv_t iconv_open(const char *tocode, const char *fromcode) } /* bit 30 set indicates that this is an 8bit encoding */ - if (from & (1<<30)) - e->intab = iconv_eightbit_new(from & ~(1<<30)); - else { + if (from & (1<<30)) { + error = iconv_eightbit_new(from & ~(1<<30), &e->intab); + if (error != EIGHTBIT_OK) { + free(e); + errno = (error == EIGHTBIT_NOMEM) ? ENOMEM : EINVAL; + return (iconv_t)(-1); + } + } else { e->in = encoding_new(from, encoding_READ); - if (e->in) { - /* Set encoding flags */ - unsigned int flags = 0; - if (from_force_le) - flags |= encoding_FLAG_LITTLE_ENDIAN; + if (e->in == NULL) { + free(e); + errno = ENOMEM; /* Assume memory exhaustion */ + return (iconv_t)(-1); + } - if (from == csUnicode || from_no_bom) - flags |= encoding_FLAG_NO_HEADER; + /* Set encoding flags */ + unsigned int flags = 0; + if (from_force_le) + flags |= encoding_FLAG_LITTLE_ENDIAN; - encoding_set_flags(e->in, flags, flags); + if (from == csUnicode || from_no_bom) + flags |= encoding_FLAG_NO_HEADER; - e->inflags = flags; - } - } + encoding_set_flags(e->in, flags, flags); - /* neither created => memory error or somesuch. assume ENOMEM */ - /* no table is ever generated for ASCII */ - if (!e->in && !e->intab && (from & ~(1<<30)) != csASCII) { - free(e); - errno = ENOMEM; - return (iconv_t)(-1); + e->inflags = flags; } - if (to & (1<<30)) - e->outtab = iconv_eightbit_new(to & ~(1<<30)); - else { + if (to & (1<<30)) { + error = iconv_eightbit_new(to & ~(1<<30), &e->outtab); + if (error != EIGHTBIT_OK) { + if (e->in) + encoding_delete(e->in); + iconv_eightbit_delete(e); + free(e); + errno = (error == EIGHTBIT_NOMEM) ? ENOMEM : EINVAL; + return (iconv_t)(-1); + } + } else { e->out = encoding_new(to, encoding_WRITE_STRICT); - if (e->out) { - /* Set encoding flags */ - unsigned int flags = 0; - if (to_force_le) - flags |= encoding_FLAG_LITTLE_ENDIAN; + if (e->out == NULL) { + if (e->in) + encoding_delete(e->in); + iconv_eightbit_delete(e); + free(e); + errno = ENOMEM; /* Assume memory exhaustion */ + return (iconv_t)(-1); + } - if (to == csUnicode || to_no_bom) - flags |= encoding_FLAG_NO_HEADER; + /* Set encoding flags */ + unsigned int flags = 0; + if (to_force_le) + flags |= encoding_FLAG_LITTLE_ENDIAN; - encoding_set_flags(e->out, flags, flags); + if (to == csUnicode || to_no_bom) + flags |= encoding_FLAG_NO_HEADER; - e->outflags = flags; - } - } + encoding_set_flags(e->out, flags, flags); - /* neither created => ENOMEM */ - if (!e->out && !e->outtab && (to & ~(1<<30)) != csASCII) { - if (e->in) - encoding_delete(e->in); - iconv_eightbit_delete(e); - free(e); - errno = ENOMEM; - return (iconv_t)(-1); + e->outflags = flags; } /* add to list */ |