...
In this noncompliant code example, the value of length
is read from a network connection and passed as an argument to a wrapper to malloc()
to allocate the appropriate data block. Provided that the size of an unsigned long
is equal to the size of an unsigned int
, and both sizes are equal to or smaller than the size of size_t
, this code runs as expected. However, if the size of an unsigned long
is greater than the size of an unsigned int
, the value stored in length
may be truncated when passed as an argument to alloc()
. Both read functions return zero on success and nonzero on failure.
Code Block | ||||
---|---|---|---|---|
| ||||
void *alloc(unsigned int blocksize) { return malloc(blocksize); } int read_counted_string(int fd) { unsigned long length; unsigned char *data; if (read_integer_from_network(fd, &length) < 0) { return -1; } data = (unsigned char*)alloc(length+1); if (data == NULL) { return -1; /* Indicate failure */ } if (read_network_data(fd, data, length) < 0) { free(data); return -1; } data[length] = '\0'; /* ... */ free( data); return 0; } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
void *alloc(rsize_t blocksize) { if (blocksize == 0 || blocksize > RSIZE_MAX) { return NULL; /* Indicate failure */ } return malloc(blocksize); } int read_counted_string(int fd) { rsize_t length; unsigned char *data; if (read_integer_from_network(fd, &length) < 0) { return -1; } data = (unsigned char*)alloc(length+1); if (data == NULL) { return -1; /* Indicate failure */ } if (read_network_data(fd, data, length) < 0) { free(data); return -1; } data[length] = '\0'; /* ... */ free( data); return 0; } |
...