summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorThomas Markwalder <tmark@isc.org>2014-11-19 10:56:17 -0500
committerThomas Markwalder <tmark@isc.org>2014-11-19 10:56:17 -0500
commitd9b2a590e835ec9d27f4c059ee07893b1acca110 (patch)
tree538d4aa08c64eb745c9d392f42f457b17700ba1e /common
parent21d3034757a2e33cfea31f93b8585b20e8a22bbe (diff)
downloadisc-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.c64
-rw-r--r--common/tests/test_alloc.c104
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());
}