日期:2014-05-16  浏览次数:20705 次

iconv的问题
[code=C/C++][/code]
C/C++ code
char charset[16] = {0};

// =?UTF-8?B?5o6i57Si56We5puy6ZqQ6JeP5Zyo6IOM5ZCO55qE56eY5a+G?=
bool decode_subject(char *subject)
{
    static char *iconvob = NULL;
    static iconv_t cd = (iconv_t)-1;

    char *p1, *p2;
    size_t insz, outsz;

    if(!strstr(subject, "=?"))
        return true;

    p1 = strchr(subject + 2, '?');
    memcpy(charset, subject + 2, p1 - subject - 2);
    charset[p1 - subject - 2] = 0;
#ifdef DEBUG
    fprintf(stderr, "charset: %s\n", charset);
#endif
    p1 += 3;

    p2 = strrchr(p1, '?');

    if(cd == (iconv_t)-1) {
        cd = iconv_open("UTF-8", charset);
        if(cd == (iconv_t)-1) {
            perror("iconv_open()");
            return false;
        }
    }
    if(!iconvob) {
        iconvob = (char *)malloc(256);
        if(!iconvob) {
            fprintf(stderr, "malloc() failed\n");
            return false;
        }
    }
    memset(iconvob, 0, 256);
    insz = p2 - p1;
    if(iconv(cd, &p1, &insz, &iconvob, &outsz) == (size_t)-1) {
        iconv_close(cd);
        perror("iconv()");
        return false;
    }

    strcpy(subject, iconvob);

    return true;
}
[code=C/C++][/code]

参数subject意指email的标题,形如“=?UTF-8?B?5o6i57Si56We5puy6ZqQ6JeP5Zyo6IOM5ZCO55qE56eY5a+G?=”,根据MIME,“=?UTF-8?B?”和结尾的“?=”都是固定的部分。

decode_subject函数,想解析出编码(如UTF-8),并把经iconv转换后的数据(NULL-terminated C string)再存入subject参数所指的空间。

错误是:
Program terminated with signal 6, Aborted.
#0 0xb7719424 in __kernel_vsyscall ()

以上的函数,有什么问题呢?我看不出来。bt看,一定是这个函数的问题,但不单步的话,也定位不了问题。

------解决方案--------------------
哥, 这是base64后的utf8,请你先base64_decode后再iconv。
------解决方案--------------------
你的函数第一遍调用不会core,第二次调用会core掉,因为iconv修改了size参数,也就是修改了iconvob里存的地址,调用完iconv后iconvob还没用光,iconvob被修改指向了某个buffer内的位置,因为你之前memset过,所以strcpy可能没有问题。

第二次调用为什么会core? 因为第一次Iconvob已经被改到buffer很后面的位置了,第二次你判断iconvob的确非空,于是继续iconv,此时iconvob可不够用了就非法操作了。

另外,你代码本来就有问题,outsz根本没初始化,你起码也应该赋值它为256.