diff options
| author | Marcel Holtmann <marcel@holtmann.org> | 2007-11-26 11:52:16 +0000 | 
|---|---|---|
| committer | Marcel Holtmann <marcel@holtmann.org> | 2007-11-26 11:52:16 +0000 | 
| commit | 48ce703ca92056265f6f036f42c8f8843700d15f (patch) | |
| tree | eaac749caa4d2071c4fd3d79cb588d0ccd5e81a4 | |
| parent | 6dda5e4081749ace9d58aae0b416f9ac86ef9f70 (diff) | |
Fix key search function to honor the mmap area size
| -rw-r--r-- | common/textfile.c | 54 | 
1 files changed, 40 insertions, 14 deletions
| diff --git a/common/textfile.c b/common/textfile.c index ea7e80bb..88e783a8 100644 --- a/common/textfile.c +++ b/common/textfile.c @@ -28,6 +28,7 @@  #define _GNU_SOURCE  #include <stdio.h>  #include <errno.h> +#include <ctype.h>  #include <fcntl.h>  #include <unistd.h>  #include <malloc.h> @@ -78,7 +79,8 @@ int create_file(const char *filename, const mode_t mode)  	int fd;  	umask(S_IWGRP | S_IWOTH); -	create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); +	create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | +					S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);  	fd = open(filename, O_RDWR | O_CREAT, mode);  	if (fd < 0) @@ -94,19 +96,42 @@ int create_name(char *buf, size_t size, const char *path, const char *address, c  	return snprintf(buf, size, "%s/%s/%s", path, address, name);  } -static inline char *find_key(char *map, const char *key, size_t len, int icase) +static inline char *find_key(char *map, size_t size, const char *key, size_t len, int icase)  { -	char *off = (icase) ? strcasestr(map, key) : strstr(map, key); - -	while (off && ((off > map && *(off - 1) != '\r' && -				*(off - 1) != '\n') || *(off + len) != ' ')) { -		if (icase) -			off = strcasestr(off + len, key); -		else -			off = strstr(off + len, key); +	char *ptr = map; +	size_t ptrlen = size; + +	while (ptrlen > len + 1) { +		int cmp = (icase) ? strncasecmp(ptr, key, len) : strncmp(ptr, key, len); +		if (cmp == 0) { +			if (ptr == map) +				return ptr; + +			if ((*(ptr - 1) == '\r' || *(ptr - 1) == '\n') && +							*(ptr + len) == ' ') +				return ptr; +		} + +		if (icase) { +			char *p1 = memchr(ptr + 1, tolower(*key), ptrlen - 1); +			char *p2 = memchr(ptr + 1, toupper(*key), ptrlen - 1); + +			if (!p1) +				ptr = p2; +			else if (!p2) +				ptr = p1; +			else +				ptr = (p1 < p2) ? p1 : p2; +		} else +			ptr = memchr(ptr + 1, *key, ptrlen - 1); + +		if (!ptr) +			return NULL; + +		ptrlen = size - (ptr - map);  	} -	return off; +	return NULL;  }  static inline int write_key_value(int fd, const char *key, const char *value) @@ -162,14 +187,15 @@ static int write_key(const char *pathname, const char *key, const char *value, i  		goto unlock;  	} -	map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED, fd, 0); +	map = mmap(NULL, size, PROT_READ | PROT_WRITE, +					MAP_PRIVATE | MAP_LOCKED, fd, 0);  	if (!map || map == MAP_FAILED) {  		err = errno;  		goto unlock;  	}  	len = strlen(key); -	off = find_key(map, key, len, icase); +	off = find_key(map, size, key, len, icase);  	if (!off) {  		if (value) {  			munmap(map, size); @@ -281,7 +307,7 @@ static char *read_key(const char *pathname, const char *key, int icase)  	}  	len = strlen(key); -	off = find_key(map, key, len, icase); +	off = find_key(map, size, key, len, icase);  	if (!off) {  		err = EILSEQ;  		goto unmap; | 
