プログラミング iconv 恐ろしいバグ
本当に偶然、恐ろしいバグ?を発見した。
報告しておく。
convert1: Invalid argument
が出たので調べていたら見つけた。
こんなのわかるわけないよ。
#include <stdio.h> #include <iconv.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> size_t convert(char *inbuf, char *outbuf, int byteread); int main(){ size_t ret_val; int src; FILE *dst; int byteread; char inbuf[21701]; char *outbuf = (char *)malloc(86243); if(outbuf == NULL) { perror("maloc"); exit(EXIT_FAILURE); } src = open("hoge", O_RDONLY); if(!src){ perror("open"); exit(EXIT_FAILURE); } dst = fopen("utf8.txt", "w"); if(!dst){ perror("open"); exit(EXIT_FAILURE); } while(1){ byteread = read(src, inbuf, sizeof(inbuf)); if (byteread > 0){ ret_val = convert(inbuf, outbuf, byteread); fwrite(outbuf, sizeof(char), ret_val, dst); } else { break; } } fclose(dst); close(src); return 0; } size_t convert(char *inbuf, char *outbuf, int byteread){ iconv_t icd; size_t inbyteleft; size_t outbyteleft; size_t ret; char *inchar; char *outchar; if ((icd = iconv_open("UTF-8", "Shift_JIS")) == (iconv_t)-1) { perror("iconv_open"); exit(EXIT_FAILURE); } inchar = inbuf; outchar = outbuf; inbyteleft = byteread; outbyteleft = (byteread * 2); ret = iconv(icd, &inchar, &inbyteleft, &outchar, &outbyteleft); if ((ret == -1) && (errno == EINVAL)) { perror("convert1"); exit(EXIT_FAILURE); } if ((ret == -1) && (errno == EILSEQ)) { perror("convert2"); exit(EXIT_FAILURE); } if ((ret == -1) && (errno == E2BIG)) { perror("convert3"); exit(EXIT_FAILURE); } return outbyteleft; }
このコードをコンパイルしても、convert1: Invalid argumentで失敗する。
でも、
char inbuf[21702]にすると成功する。
原因はわからない。
iconvの変なバグに悩ませられている人はお試しあれ。