Domanda

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);
È stato utile?

Soluzione

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.

Altri suggerimenti

It would appear that you have a configuration where sizeof(long) == 4 (i.e. 32-bit long). You might want to look into strtoull()/strtoll() instead of strtoul()/strtol(), and use [unsigned] long long variables instead...

Edit: actually, never mind the [unsigned] long long bit, as you already have uint64_t...

It seems that strtol is out of range (0xffffffff or greater is ULONG_MAX according to limits.h and the definition of strtol). Although the passed value (8105b4a5) is smaller than 0xffffffff it is bigger than LONG_MAX (system dependent), which is somehow the biggest number strtol can deal with.

Due to the fact that you are using unsigned longs the function strtoul (see definition) might be the more appropriate candidate.

To ensure that it is because of this range problem, please check your local limit.h.

Hope that works.

*Jost

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top