summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2009-07-25 15:45:50 (GMT)
committer John Mark Bell <jmb@netsurf-browser.org>2009-07-25 15:45:50 (GMT)
commitd398997c9328e1a32bb37084f8c45fee6a2557ee (patch)
treeb4fd3fd8d6fbd84ad730e93f089dd3ceba549ef8
parentf27eb11e3f225d71d6fba59e3ca31cd68e420238 (diff)
downloadlibwapcaplet-d398997c9328e1a32bb37084f8c45fee6a2557ee.tar.gz
libwapcaplet-d398997c9328e1a32bb37084f8c45fee6a2557ee.tar.bz2
Guarantee to NUL-terminate interned strings.
svn path=/trunk/libwapcaplet/; revision=8784
-rw-r--r--include/libwapcaplet/libwapcaplet.h2
-rw-r--r--src/libwapcaplet.c6
-rw-r--r--test/basictests.c34
3 files changed, 39 insertions, 3 deletions
diff --git a/include/libwapcaplet/libwapcaplet.h b/include/libwapcaplet/libwapcaplet.h
index e896fc5..420f8c3 100644
--- a/include/libwapcaplet/libwapcaplet.h
+++ b/include/libwapcaplet/libwapcaplet.h
@@ -64,6 +64,8 @@ extern void lwc_context_unref(lwc_context *ctx);
* Intern a string.
*
* If the string was already present, its reference count is incremented.
+ *
+ * The returned string is guaranteed to be NUL-terminated.
*/
extern lwc_error lwc_context_intern(lwc_context *ctx,
const char *s, size_t slen,
diff --git a/src/libwapcaplet.c b/src/libwapcaplet.c
index 58ebf6b..87704bd 100644
--- a/src/libwapcaplet.c
+++ b/src/libwapcaplet.c
@@ -150,7 +150,8 @@ __lwc_context_intern(lwc_context *ctx,
str = str->next;
}
- *ret = str = LWC_ALLOC(sizeof(lwc_string) + slen);
+ /* Add one for the additional NUL. */
+ *ret = str = LWC_ALLOC(sizeof(lwc_string) + slen + 1);
if (str == NULL)
return lwc_error_oom;
@@ -167,6 +168,9 @@ __lwc_context_intern(lwc_context *ctx,
str->insensitive = NULL;
copy(STR_OF(str), s, slen);
+
+ /* Guarantee NUL termination */
+ STR_OF(str)[slen] = '\0';
return lwc_error_ok;
}
diff --git a/test/basictests.c b/test/basictests.c
index 80d3d38..290a56c 100644
--- a/test/basictests.c
+++ b/test/basictests.c
@@ -176,7 +176,7 @@ END_TEST
START_TEST (test_lwc_string_hash_value_aborts)
{
- lwc_string_hash_value(NULL);
+ lwc_string_hash_value(NULL);
}
END_TEST
@@ -389,7 +389,35 @@ END_TEST
START_TEST (test_lwc_string_hash_value_ok)
{
- lwc_string_hash_value(intern_one);
+ lwc_string_hash_value(intern_one);
+}
+END_TEST
+
+START_TEST (test_lwc_string_is_nul_terminated)
+{
+ lwc_string *new_ONE;
+
+ fail_unless(lwc_context_intern(shared_ctx, "ONE", 3, &new_ONE) == lwc_error_ok,
+ "Failure interning 'ONE'");
+
+ fail_unless(lwc_string_data(new_ONE)[lwc_string_length(new_ONE)] == '\0',
+ "Interned string isn't NUL terminated");
+}
+END_TEST
+
+START_TEST (test_lwc_substring_is_nul_terminated)
+{
+ lwc_string *new_ONE;
+ lwc_string *new_O;
+
+ fail_unless(lwc_context_intern(shared_ctx, "ONE", 3, &new_ONE) == lwc_error_ok,
+ "Failure interning 'ONE'");
+
+ fail_unless(lwc_context_intern_substring(shared_ctx, new_ONE, 0, 1, &new_O) == lwc_error_ok,
+ "Failure interning substring 'O'");
+
+ fail_unless(lwc_string_data(new_O)[lwc_string_length(new_O)] == '\0',
+ "Interned substring isn't NUL terminated");
}
END_TEST
@@ -487,6 +515,8 @@ lwc_basic_suite(SRunner *sr)
tcase_add_test(tc_basic, test_lwc_context_string_caseless_isequal_ok);
tcase_add_test(tc_basic, test_lwc_extract_data_ok);
tcase_add_test(tc_basic, test_lwc_string_hash_value_ok);
+ tcase_add_test(tc_basic, test_lwc_string_is_nul_terminated);
+ tcase_add_test(tc_basic, test_lwc_substring_is_nul_terminated);
suite_add_tcase(s, tc_basic);
srunner_add_suite(sr, s);