cparsingstrtol

Using strtol() to Parse Long Values out of Lines of a File


When I use strtol function to parse long values out of such lines of a file,

ffffffff8105b4a5 t send_signal

it just returns ffffffff instead of ffffffff8105b4a5!!!

Here's the code:

 uint64_t value1;
 uint64_t value2;
 char *temp = (char *) malloc(100);
fgets(temp,512, fp);
strncpy(line1,temp,16);
value1 = strtol(line1,NULL,16);
printf("str_hex1 = %x\n",value1);
printf("str_hex2 = %x\n",value2);

Solution

  • I made an answer from my comment following Chrono's suggestion:

    Buffer overflow vulnerability

    If you allocate 100 bytes as I/O buffer, you should tell that to the function filling it:

    char *temp = malloc(100);
    fgets(temp, 100, fp);
    

    or if you discard that buffer before returning:

    char temp[100];
    fgets(temp, sizeof(temp), fp);
    

    Unnecessary copy

    Why not simply

    strtol(temp, NULL, 16);
    

    Use fscanf(3) and format strings to parse streams

    To parse lines like

    ffffffff8105b4a5 t send_signal
    

    I would write something similar to

    #include <inttypes.h>
    
    int rv;
    uint64_t col1;
    char col2;
    char col3[64];
    
    rv = fscanf(fp, "%"SCNx64" %c %63s", &col1, &col2, col3);
    if (rv != 3) {
        /* error treatment */
    }
    

    This is a lot more concise than a series of fgets, strtoul and strcpy. It also saves a few memory copy operations, because it operates directly on the FILE* buffer.

    Furthermore, for situations as with col3, GNU (and upcoming POSIX.1) *scanf has a conversion format extension "%ms" that allocates the necessary buffer for strings so you don't have to (and don't run into buffer overflows). Remember calling free() on that though.