diff options
author | John-Mark Bell <jmb@netsurf-browser.org> | 2013-01-06 22:34:18 +0000 |
---|---|---|
committer | John-Mark Bell <jmb@netsurf-browser.org> | 2013-01-06 22:34:18 +0000 |
commit | efe52d57b2e0d1cb15ce3ccea5dd7d5e0359dae4 (patch) | |
tree | 1c772e308c8f35530c52bd889ee897d71a500814 | |
parent | 097de4ee4cd1e7df6661c94b87a5389e0cf50b77 (diff) | |
download | iconv-efe52d57b2e0d1cb15ce3ccea5dd7d5e0359dae4.tar.gz iconv-efe52d57b2e0d1cb15ce3ccea5dd7d5e0359dae4.tar.bz2 |
Correct handling of trailing valid shift sequences. Previously would
erroneously report EINVAL, instead of silently accepting them.
Requires UnicodeLib 0.60.
-rw-r--r-- | doc/ChangeLog | 5 | ||||
-rw-r--r-- | src/iconv.c | 11 | ||||
-rw-r--r-- | test/INDEX | 1 | ||||
-rw-r--r-- | test/Makefile | 2 | ||||
-rw-r--r-- | test/nullable.c | 101 |
5 files changed, 117 insertions, 3 deletions
diff --git a/doc/ChangeLog b/doc/ChangeLog index 4c17511..b055aa9 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -105,3 +105,8 @@ Iconv Changelog - Toolchain used to build 0.10 turns out to have produced broken code. - Minor additions to the charset alias mapping file. +0.12 XX-XX-2013 +--------------- + + - Correct handling of trailing valid shift sequences. Previously would + erroneously report EINVAL, instead of silently accepting them. diff --git a/src/iconv.c b/src/iconv.c index 45bd15f..db47cbc 100644 --- a/src/iconv.c +++ b/src/iconv.c @@ -356,12 +356,19 @@ size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, /* Clear current write state */ e->write_state = WRITE_NONE; - if (e->in) + if (e->in) { read = encoding_read(e->in, character_callback, *inbuf, *inbytesleft, e); - else + + /* A trailing complete nullable sequence should + * result in success */ + if (e->write_state == WRITE_NONE && + !encoding_read_in_multibyte_sequence(e->in)) + e->write_state = WRITE_SUCCESS; + } else { read = iconv_eightbit_read(e, character_callback, *inbuf, *inbytesleft, e); + } /* Stop on error */ if (e->write_state != WRITE_SUCCESS) @@ -2,5 +2,6 @@ # # Test Description DataDir iconv Iconv initialisation/finalisation +nullable Handling of nullable input sequences # Regression tests diff --git a/test/Makefile b/test/Makefile index 343cd3f..89b8093 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,4 +1,4 @@ # Tests -DIR_TEST_ITEMS := iconv:iconv.c +DIR_TEST_ITEMS := iconv:iconv.c nullable:nullable.c include $(NSBUILD)/Makefile.subdir diff --git a/test/nullable.c b/test/nullable.c new file mode 100644 index 0000000..c9523f5 --- /dev/null +++ b/test/nullable.c @@ -0,0 +1,101 @@ +#include <errno.h> +#include <stdio.h> +#include <string.h> + +#include <iconv/iconv.h> +#include <iconv-internal/iconv.h> + +#include "testutils.h" + +#ifdef __riscos__ +#define ALIASES_FILE "Files.Aliases" +#else +#define ALIASES_FILE "Files/Aliases" +#endif + +typedef struct nullable_testcase { + const char *from_charset; + const char *source; + struct { + size_t retval; + int errval; + size_t remaining; + } expected; +} nullable_testcase; + +static const nullable_testcase tests[] = { + { "iso-2022-jp", "1234\x1b$@123456\x1b(B", { 0, 0, 0 } }, + { "iso-2022-jp", "1234\x1b$@123456\x1b(", { (size_t) -1, EINVAL, 2 } }, + { NULL, NULL, { 0, 0, 0 } } +}; + +static void run_test(const nullable_testcase *test) +{ + iconv_t cd; + char out[128]; + char *inp = (char *) test->source, *outp = out; + size_t inlen = strlen(inp), outlen = sizeof(out); + size_t read; + + cd = iconv_open("utf-8", test->from_charset); + assert(cd != (iconv_t) -1); + + read = iconv(cd, &inp, &inlen, &outp, &outlen); + assert(read == test->expected.retval); + + if (test->expected.retval == (size_t) -1) { + assert(errno == test->expected.errval); + assert(inlen == test->expected.remaining); + } + + iconv_close(cd); +} + +static void run_tests(void) +{ + int index; + + for (index = 0; tests[index].from_charset != NULL; index++) { + run_test(&tests[index]); + } +} + +int main(int argc, char **argv) +{ + const char *ucpath; + int alen; + char aliases[4096]; + + UNUSED(argc); + UNUSED(argv); + +#ifdef __riscos__ + ucpath = "Unicode:"; +#else + ucpath = getenv("UNICODE_DIR"); +#endif + + assert(ucpath != NULL); + + strncpy(aliases, ucpath, sizeof(aliases)); + alen = strlen(aliases); +#ifndef __riscos__ + if (aliases[alen - 1] != '/') { + strncat(aliases, "/", sizeof(aliases) - alen - 1); + alen += 1; + } +#endif + strncat(aliases, ALIASES_FILE, sizeof(aliases) - alen - 1); + aliases[sizeof(aliases) - 1] = '\0'; + + assert(iconv_initialise(aliases) == 1); + + run_tests(); + + iconv_finalise(); + + printf("PASS\n"); + + return 0; +} + |