Hi, To confirm that this problem is really glibc iconv(3) problem, I did:
(1) Extract iconv() input data passed from mkisofs. (2) Put such data into iconv(3). To check (1), I patch this patch to joliet.c (after applying dpatches). This patch creates iconv() input data to /tmp/iconvdata.??? files. You can get this patch from: http://gotom.jp/~gotom/debian/bugs/234691/patch.iconv-out-file~joliet.c --- original/cdrtools-2.0+a27/mkisofs/joliet.c 2004-05-11 01:01:59.000000000 +0900 +++ gotom/cdrtools-2.0+a27/mkisofs/joliet.c 2004-05-11 01:09:24.000000000 +0900 @@ -90,6 +90,11 @@ #include <unls.h> /* For UNICODE translation */ #include <schily.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + #ifdef USE_ICONV #include <iconv.h> #include <errno.h> @@ -263,6 +268,31 @@ size_t outleft = size; iconv(inls->iconv_d, NULL, NULL, NULL, NULL); + { + static int counter = 0; + char file[256]; + int fd; + int ret; + + snprintf(file, sizeof(file), "/tmp/iconvdat.%03d", counter); + fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0755); + if (fd == -1) { + perror("open\n"); + goto next; + } + ret = write(fd, inptr, inleft); + if (ret < 0) { + perror("write\n"); + } + if (ret != inleft) { + printf("write size mismatch!\n"); + } + if (close(fd)) { + perror("close"); + } + next: + counter++; + } if(iconv(inls->iconv_d, &inptr, &inleft, &outptr, &outleft) == (size_t)-1 && errno == EILSEQ) { fprintf(stderr, "Incorrectly encoded string (%s) " Using this patch, I got 52 files. I put such files to: http://gotom.jp/~gotom/debian/bugs/234691/iconvdata.tgz Then I use the following program, to convert throught iconv() using iconvdata files. Some parts of this program was extracted from mkisofs (+ iconv patch) joliet.c. You can get this from: http://gotom.jp/~gotom/debian/bugs/234691/repeaticonv.c #include <stdio.h> #include <string.h> #include <iconv.h> #include <stdlib.h> #include <locale.h> #include <langinfo.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> int main(int argc, char *argv[]) { iconv_t *ic; int ret; char *locale; char *charset; int i; locale = setlocale(LC_ALL, ""); if (locale == NULL) { printf("warning: locale does not set\n"); } else { printf("current locale: %s\n", locale); } charset = nl_langinfo(CODESET); if (charset == NULL) { printf("failed nl_langinfo(CODESET)\n"); } else { printf("charset: %s\n", charset); } ic = iconv_open("UCS-2BE", charset); if (ic == (iconv_t *)-1) { perror("iconv_open"); exit(1); } i = 1; while (i < argc) { struct stat statbuf; int fd; ssize_t readsize; char *inbuf, *outbuf; off_t insize, outsize; ret = stat(argv[i], &statbuf); if (ret == -1) { perror("stat error"); exit(1); } insize = statbuf.st_size; /* cur_max might be larger than the original size */ outsize = insize * 6; inbuf = malloc(insize); if (inbuf == NULL) { printf("malloc error\n"); exit(1); } outbuf = malloc(outsize); if (outbuf == NULL) { printf("malloc error\n"); exit(1); } printf("allocate: inbuf: %ld, outbuf: %ld\n", insize, outsize); fd = open(argv[i], O_RDONLY); if (fd == -1) { perror("open error"); exit(1); } readsize = read(fd, inbuf, insize); if (readsize == -1) { perror("read error"); exit(1); } else if (readsize != insize) { printf("you're lazy!\n"); exit(1); } printf("%d:%s\n", readsize, inbuf); iconv(ic, NULL, NULL, NULL, NULL); { size_t inlen = insize; size_t outlen = outsize; char *inbufp = inbuf; char *outbufp = outbuf; while (inlen > 0) { ret = iconv(ic, &inbufp, &inlen, &outbufp, &outlen); if (ret == -1) { perror("iconv"); exit(1); } printf("processing(%d): filesize %ld byte, in: %ld byte -> out: %ld byte\n", i, insize, insize - inlen, outsize - outlen); } } free(inbuf); free(outbuf); i++; } ret = iconv_close(ic); if (ret == -1) { perror("iconv_close"); exit(1); } exit(0); } Then execute: sauter:~/bugs/234691> env LANG=ja_JP.eucJP ./repeaticonv /tmp/iconvdat.0* current locale: ja_JP.eucJP charset: EUC-JP allocate: inbuf: 10, outbuf: 60 processing(1): filesize 10 byte, in: 10 byte -> out: 20 byte ... allocate: inbuf: 44, outbuf: 264 processing(52): filesize 44 byte, in: 44 byte -> out: 88 byte sauter:~/bugs/234691> echo $? 0 These programs are just quick hack, so it may have wrong parts, but I think this shows that iconv(3) works fine. This means we can not reappear this bug without using mkisofs (+ iconv patch). Is this really glibc bug? I still doubt it's mkisofs problem. Then next: dig mkisofs more. Another idea it to use valgrind; unfortunatelly, sparc does not have ltrace or valgrind, so it's good idea to confirm mkisofs using valgrind on i386 arch. Regards, -- gotom