[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: