I learn C and read through Learn C The Hard Way (ISBN-10: 0-321-88492-2). I am stuck in exercise 17, How to Break It.
Here is the problem from the book:
There is an error in this program since strncpy is poorly designed. Go read about strncpy, then try to figure out what happens when the name or address you specify is more than 512 bytes. Fix this by simply forcing the last character "\ 0" so that it always sets (which strncpy should do).
I read strncpy and understand that it is unsafe because it does not add a null byte to the end of the line. However, I do not know how to pass functions to a large number of bytes, and I am not sure how to fix a problem with a zero byte.
Below is a function using strncpy, MAX_DATA
- 512.
void Database_set(struct Connection *conn, int id, const char *name, const char *email) { struct Address *addr = &conn->db->rows[id]; if(addr->set) die("Already set, delete it first"); addr->set = 1;
How to break it - CHANGE
The following is an example of how to break strncpy:
void Database_set(struct Connection *conn, int id, const char *name, const char *email) { struct Address *addr = &conn->db->rows[id]; if(addr->set) die("Already set, delete it first"); addr->set = 1; // WARNING: bug, read the "How To Break It" and fix this char name2[] = { 'a', 's', 't', 'r', 'i', 'n', 'g' }; char *res = strncpy(addr->name, name2, MAX_DATA); // demonstrate the strncpy bug if(!res) die("Name copy failed"); res = strncpy(addr->email, email, MAX_DATA); if(!res) die("Email copy failed"); }
To fix, add a null byte to the end of the line. change name2
as follows:
char name2[] = { 'a', 's', 't', 'r', 'i', 'n', 'g', '\0' };
or, add the following line above the strncpy function call
names2[sizeof(names2)-1] = '\0';