Bug#234691: sparc64 too..
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
Reply to: