Переполнение стека (о "evhttp_uri_parse")

Код реализует функцию, которая читает файл (содержит много URL-адресов), каждый URL-адрес проходит через "evhttp_uri_parse", получая хост и путь. Но есть ошибка, что evhttp_uri_parse parse fail, возвращаемое значение NULLibly. Вероятно, причина - переполнение стека.

FILE *fp=fopen(argv[1],"rb");
if(NULL==fp)
{
    printf("open url_file is error %d::%s\n",errno,strerror(errno));
    return 0;
}
char url_buf[2048];
memset(url_buf,'\0',sizeof(url_buf));

fgets(url_buf,sizeof(url_buf),fp);
while(!feof(fp))
{
    if(strlen(url_buf)>1)
    {
        printf("url_buf::%s",url_buf);
        #if 1 
        struct evhttp_uri *ev_uri=NULL;
        ev_uri=evhttp_uri_parse(url_buf);
        if(ev_uri==NULL)
        {
            printf("parse uri  error::%d,%s\n",errno,strerror(errno));
        }
        const char *host=evhttp_uri_get_host(ev_uri);
        const char *path=evhttp_uri_get_path(ev_uri);
        printf("query host::%s,path::%s\n",host,path);
        evhttp_uri_free(ev_uri);
        #endif
    }
    memset(url_buf,'\0',sizeof(url_buf));
    fgets(url_buf,sizeof(url_buf),fp);
}
fclose(fp);

2 ответа

Если ваш URL по какой-либо причине превышает 2048 символов, то fgets не полностью вернет вам URL, который вы хотели, и вернет вам его часть (с 2047 символом) с нулевым символом только в 2048-м месте.

так вот почему это плохая идея поставить sizeof(url_buf)+1, это приведет к неопределенному поведению, так как вы будете получать доступ к местоположению, которое не связано с url_buf массив.

поэтому проверьте, получили ли вы строку с символом новой строки и измените ее на нулевой символ. Если вы не получили символ новой строки в строке, то вы можете читать до тех пор, пока не получите новую строку, чтобы получить полный URL-адрес.

это применимо, только если ваши URL-адреса ограничены символом новой строки.

  1. fgets(url_buf,sizeof(url_buf)+1,fp) следует изменить на fgets(url_buf,sizeof(url_buf),fp)

  2. fgets добавляет '\n' в конце строки. Попробуйте удалить его и посмотреть, поможет ли это.

Другие вопросы по тегам