diff options
author | Thomas Markwalder <tmark@isc.org> | 2014-11-19 10:56:17 -0500 |
---|---|---|
committer | Thomas Markwalder <tmark@isc.org> | 2014-11-19 10:56:17 -0500 |
commit | d9b2a590e835ec9d27f4c059ee07893b1acca110 (patch) | |
tree | 538d4aa08c64eb745c9d392f42f457b17700ba1e /common | |
parent | 21d3034757a2e33cfea31f93b8585b20e8a22bbe (diff) | |
download | isc-dhcp-d9b2a590e835ec9d27f4c059ee07893b1acca110.tar.gz |
[master] Host declaration name can now be used in DNS forward name
Merges in rt21323.
Diffstat (limited to 'common')
-rw-r--r-- | common/alloc.c | 64 | ||||
-rw-r--r-- | common/tests/test_alloc.c | 104 |
2 files changed, 166 insertions, 2 deletions
diff --git a/common/alloc.c b/common/alloc.c index 0280cbc4..a55f4712 100644 --- a/common/alloc.c +++ b/common/alloc.c @@ -1253,6 +1253,70 @@ int binding_scope_reference (ptr, bp, file, line) return 1; } +/*! + * \brief Constructs a null-terminated data_string from a char* and length. + * + * Allocates a data_string and copies into it the given length of bytes + * from the given source, adding a terminating null if not present in the source + * at length-1. + * + * \param new_string pointer to the data_string to construct. Cannot be + * NULL. Note that its contents will be overwritten. Passing in the address + * of an allocated data_string will result in memory leaks. + * \param src data to be copied. Cannot be NULL. + * \param len length of the data to copied + * + * \return 1 - if the data_string is constructed successfully, 0 if + * target data_struct is NULL or the buffer allocation fails. + */ +int +data_string_new(struct data_string *new_string, + const char *src, unsigned int len, + const char *file, int line) +{ + unsigned int copy_len = 0; + + if (new_string == NULL) { + log_error("data_string_new: new_string cannot be NULL %s(%d)", + file, line); + return (0); + } + + if (src == NULL) { + log_error("data_string_new: src cannot be NULL %s(%d)", + file, line); + return (0); + } + + memset(new_string, 0, sizeof (struct data_string)); + + /* If we already have a NULL back off length by one. This lets + * us always just add a NULL at the end. */ + copy_len = (len > 0 && src[len - 1 ] == 0) ? len - 1 : len; + + /* Allocate the buffer, accounting for terminating null */ + if (!buffer_allocate(&(new_string->buffer), copy_len + 1, MDL)) { + log_error("data_string_new: No memory %s(%d)", file, line); + return (0); + } + + /* Only copy if there's something to copy */ + if (copy_len > 0) { + memcpy(new_string->buffer->data, src, copy_len); + } + + /* Always tack on the null */ + new_string->buffer->data[copy_len + 1] = 0; + + /* Update data_string accessor values. Note len does NOT include + * the NULL. */ + new_string->data = new_string->buffer->data; + new_string->len = copy_len; + new_string->terminated = 1; + + return (1); +} + /* Make a copy of the data in data_string, upping the buffer reference count if there's a buffer. */ diff --git a/common/tests/test_alloc.c b/common/tests/test_alloc.c index d941c8fb..9e082135 100644 --- a/common/tests/test_alloc.c +++ b/common/tests/test_alloc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007,2009,2012 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2007,2009-2014 by Internet Systems Consortium, Inc. ("ISC") * * We test the functions provided in alloc.c here. These are very * basic functions, and it is very important that they work correctly. @@ -27,6 +27,8 @@ #include <atf-c.h> #include "dhcpd.h" +static const char* checkString (struct data_string* ds, const char *src); + ATF_TC(buffer_allocate); ATF_TC_HEAD(buffer_allocate, tc) { @@ -187,7 +189,7 @@ ATF_TC_BODY(buffer_dereference, tc) { if (!buffer_reference(&b, a, MDL)) { atf_tc_fail("buffer_reference() failed"); } - a->refcnt = 0; /* purposely set to invalid value */ + a->refcnt = 0; /* purposely set to invalid value */ if (buffer_dereference(&a, MDL)) { atf_tc_fail("buffer_dereference() succeeded on error input"); } @@ -387,6 +389,103 @@ ATF_TC_BODY(data_string_copy_nobuf, tc) { } + +ATF_TC(data_string_new); + +ATF_TC_HEAD(data_string_new, tc) { + atf_tc_set_md_var(tc, "descr", "data_string_new test, " + "exercises data_string_new function"); +} + +ATF_TC_BODY(data_string_new, tc) { + struct data_string new_string; + const char *src = "Really? Latin? ... geeks"; + int len_arg = 0; + const char *error; + + /* Case 1: Call with an invalid data_string pointer, should fail */ + if (data_string_new(NULL, src, len_arg, MDL)) { + atf_tc_fail("case 1: call should have failed"); + } + + /* Case 2: Passing in NULL src should fail */ + if (data_string_new(&new_string, NULL, 10, MDL)) { + atf_tc_fail("case 2: did not return success"); + } + + /* Case 3: Call with valid params, length includes NULL */ + len_arg = strlen(src) + 1; + if (data_string_new(&new_string, src, len_arg, MDL) == 0) { + atf_tc_fail("case 3: did not return success"); + } + + error = checkString(&new_string, src); + ATF_REQUIRE_MSG((error == NULL), "case 3: %s", error); + data_string_forget(&new_string, MDL); + + + /* Case 4: Call with valid params, length does not include NULL */ + len_arg = 7; + if (data_string_new(&new_string, src, len_arg, MDL) == 0) { + atf_tc_fail("case 4: did not return success"); + } + + error = checkString(&new_string, "Really?"); + ATF_REQUIRE_MSG((error == NULL), "case 4: %s", error); + data_string_forget(&new_string, MDL); + + + /* Case 5: Call with valid params, source string is "" */ + len_arg = 0; + if (data_string_new(&new_string, "", len_arg, MDL) == 0) { + atf_tc_fail("case 5: did not return success"); + } + + error = checkString(&new_string, ""); + ATF_REQUIRE_MSG((error == NULL), "case 4: %s", error); + data_string_forget(&new_string, MDL); + + +} + +/* Helper function which tests validity of a data_string +* +* Verifies that the given data_string contains a null-terminated string +* equal to a given string. +* +* \param string data_string to test +* \param src text content string should contain +* \return returns NULL if data_string is validate or an error message +* describing why it is invalid +*/ +const char* checkString (struct data_string* string, + const char* src) { + int src_len = strlen(src); + + if (string->buffer == NULL) { + return ("buffer is NULL"); + } + + if (string->data != string->buffer->data) { + return ("data not set to buffer->data"); + } + + if (string->len != src_len) { + return ("len is wrong "); + } + + if (string->terminated != 1) { + return ("terminated flag not set"); + } + + if (memcmp(string->data, src, src_len + 1)) { + return ("data content wrong"); + } + + return (NULL); +} + + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, buffer_allocate); @@ -396,6 +495,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, data_string_forget_nobuf); ATF_TP_ADD_TC(tp, data_string_copy); ATF_TP_ADD_TC(tp, data_string_copy_nobuf); + ATF_TP_ADD_TC(tp, data_string_new); return (atf_no_error()); } |