C-执行.mp3文件时,请在strlen()周围获取细分故障



每当我尝试给出一个像/home/...../tulsaqueen.mp3之类的文件时,程序给出了分割故障。GDB说这与strlen((有关,但我无法弄清楚。为什么会发生? 我正在创建服务器,并且需要处理我的.jpg每次都可以工作,但是.mp3不行。

void *connectionThread(void *socket_desc){
    char buffer[1024];
    int newsockfd = *(int*)socket_desc;
    int n;
    magic_t myt = magic_open(MAGIC_ERROR|MAGIC_MIME_TYPE);
    magic_load(myt,NULL);
    bzero(buffer,256);
    FILE * picture;
    int size;
    char *str_size = malloc(100);
    struct stat sb;
    int fd = open("TulsaQueen.mp3", O_RDONLY );
    fstat( fd, &sb );
 while (1)
     {memset(buffer, 0, 1024);n = read(newsockfd,buffer,1024);
     if (n < 0){ printf("ERROR reading from socket"); close(newsockfd);pthread_exit(NULL);}
     printf("%s",buffer);

    char *token = strtok(buffer," ");
    if(token != NULL)
    token = strtok(NULL, " ");
    printf("%sn",token);
    if(strcmp(magic_file(myt,token),"audio/mpeg") == 0){
        write(newsockfd,"HTTP/1.1 200 OKrn",strlen("HTTP/1.1 200 OKrn"));
        write(newsockfd,"Content-Length: ",strlen("Content-Length: ")); 
        snprintf(str_size,100,"%li",sb.st_size);
        write(newsockfd,str_size,strlen(str_size));
        write(newsockfd,"rn",strlen("rn"));
        write(newsockfd,"Content-Type: ",strlen("Content-type: "));
        printf("magic output: '%s'n",magic_file(myt,token));
        write(newsockfd,magic_file(myt,token),strlen(magic_file(myt,token))); 
        write(newsockfd,"rnConnection: keep-alive",strlen("rnConnection: keep-alive"));
        write(newsockfd,"rnrn",strlen("rnrn"));
        write( newsockfd, &sb.st_size, sizeof( sb.st_size ) );
        sendfile( newsockfd, fd, 0, sb.st_size );
    }
    if(strcmp(magic_file(myt,token),"image/jpeg") == 0){
    picture = fopen (token, "r");
    fseek(picture,0,SEEK_END);
    size = ftell(picture);
    fseek(picture,0,SEEK_SET);
    char file_buf[size];
    snprintf(str_size,16,"%d",size);
    //Header for HTTP standards
    write(newsockfd,"HTTP/1.1 200 OKrn",strlen("HTTP/1.1 200 OKrn"));
    write(newsockfd,"Content-Length: ",strlen("Content-Length: "));
    write(newsockfd,str_size,strlen(str_size));
    write(newsockfd,"rn",strlen("rn"));
    write(newsockfd,"Content-Type: ",strlen("Content-type: "));
    write(newsockfd,magic_file(myt,token),strlen(magic_file(myt,token))); //get Content-type
    write(newsockfd,"rnConnection: keep-alive",strlen("rnConnection: keep-alive"));
    write(newsockfd,"rnrn",strlen("rnrn"));
    rewind(picture);
    while(!feof(picture)){
    fread(file_buf, sizeof(char), sizeof(file_buf), picture);
        write(newsockfd, file_buf, sizeof(file_buf));
    bzero(file_buf, sizeof(file_buf));
    }
    }
     }  
    close(fd);
    free(buffer);
    fclose(picture);
    close(newsockfd);
    magic_close(myt);
    pthread_exit(NULL);
    return 0;
}

这是我遇到的错误

螺纹2" a.out"接收到信号sigsegv,分割故障。 (GDB(哪里 (0(strlen((at ../sysdeps/x86_64/strlen.s:106(1( _io_puts(str = 0x0(在ioputs.c:35(2( 0x0000000000401623在连接thread(((3(0x00007fffffff7bc16ba中 start_thread(arg = 0x7ffff73b6700(at pthread_create.c:333(4( 0x00007ffff76d782d in clone((at at ../sysdeps/unix/sysv/linux/x86_64/clone.s:109

代码中的一个错误可能解释了问题,与缓冲区大小, memsetread ...

有关

缓冲区正好为1024个字节。您将所有这些字节设置为0,然后阅读最多1024个字节。

但是,当您完全读取1024字节时,末尾没有任何NUL(0(字节时会发生什么?...

...如果发生这种情况的情况比strlen在搜索NUL字节时会溢出(BYTE 1025及以上(,则结果是分段故障。

解决此特定问题的一种方法是阅读1023字节...即:

memset(buffer, 0, 1024);
n = read(newsockfd,buffer,1023);

解决此特定问题的更好方法(如注释中建议(是使用n设置NUL字节值。即:

n = read(newsockfd,buffer,1023);
if (n < 0) {
   // ...
}
buffer[n] = 0;

这样,您确保在分配的缓冲区中始终存在一个nul字节。

我应该指出,用 strtok将字符串化,以及使用str*函数来解析传入数据,这有些无效,可能会产生意外的错误/结果...

...尤其是当您处于多线程环境中...

例如, strtok不是线程安全...即使存在线程安全的变化,也不是理想的。

此外,它可能会无意中损坏传入的数据 - 毕竟,您仅使用第一个"代币",因此我认为您希望其余数据保持不变。

祝你好运!

P.S。

  • strlen(magic_file(myt,token))-如果magic_file(myt,token)是无效的字符串(即null(?

  • strlen("rnrn")总是4 ...为什么要使用函数来调用?

  • free(buffer)应该是 free(str_size)

最新更新