diff options
author | Russ Allbery <rra@stanford.edu> | 2012-02-23 15:34:26 -0800 |
---|---|---|
committer | Russ Allbery <rra@stanford.edu> | 2012-02-23 15:34:26 -0800 |
commit | 3e1872e35b7ddaf4f568a94353bff79af7564e9a (patch) | |
tree | 247c464c8d0c48ecfbc5960483d2beebc3df9d07 /util | |
parent | cfc54400f0e07bc3ca366eda56ad9f42c9239341 (diff) |
Fix xstrndup to not allocate too much memory and add more tests
We weren't testing copying of short strings and strings without
nul termination. Add additional tests for those.
Change-Id: I990e7a40a69bf97d8b3e976645460c1fd29c984c
Diffstat (limited to 'util')
-rw-r--r-- | util/xmalloc.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/util/xmalloc.c b/util/xmalloc.c index 839f5a0..a636941 100644 --- a/util/xmalloc.c +++ b/util/xmalloc.c @@ -165,19 +165,30 @@ x_strdup(const char *s, const char *file, int line) } +/* + * Avoid using the system strndup function since it may not exist (on Mac OS + * X, for example), and there's no need to introduce another portability + * requirement. + */ char * x_strndup(const char *s, size_t size, const char *file, int line) { - char *p; + const char *p; + size_t length; + char *copy; - p = malloc(size + 1); - while (p == NULL) { - (*xmalloc_error_handler)("strndup", size + 1, file, line); - p = malloc(size + 1); + /* Don't assume that the source string is nul-terminated. */ + for (p = s; (size_t) (p - s) < size && *p != '\0'; p++) + ; + length = p - s; + copy = malloc(length + 1); + while (copy == NULL) { + (*xmalloc_error_handler)("strndup", length + 1, file, line); + copy = malloc(length + 1); } - memcpy(p, s, size); - p[size] = '\0'; - return p; + memcpy(copy, s, length); + copy[length] = '\0'; + return copy; } |