Переполнение стека (о "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-адреса ограничены символом новой строки.
fgets(url_buf,sizeof(url_buf)+1,fp)
следует изменить наfgets(url_buf,sizeof(url_buf),fp)
fgets
добавляет '\n' в конце строки. Попробуйте удалить его и посмотреть, поможет ли это.