Repository: lucy-clownfish Updated Branches: refs/heads/master dba8fd508 -> 9f31a790e
Disallow invalid code points in CB_Cat_Char Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/ca3809d7 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/ca3809d7 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/ca3809d7 Branch: refs/heads/master Commit: ca3809d7fb99d8905c83dcbf90221dca2c69bc41 Parents: dba8fd5 Author: Nick Wellnhofer <wellnho...@aevum.de> Authored: Tue Aug 2 18:06:02 2016 +0200 Committer: Nick Wellnhofer <wellnho...@aevum.de> Committed: Tue Aug 2 18:06:02 2016 +0200 ---------------------------------------------------------------------- runtime/core/Clownfish/CharBuf.c | 6 +++ runtime/test/Clownfish/Test/TestCharBuf.c | 67 +++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/ca3809d7/runtime/core/Clownfish/CharBuf.c ---------------------------------------------------------------------- diff --git a/runtime/core/Clownfish/CharBuf.c b/runtime/core/Clownfish/CharBuf.c index 8661c7b..2dbae91 100644 --- a/runtime/core/Clownfish/CharBuf.c +++ b/runtime/core/Clownfish/CharBuf.c @@ -280,6 +280,12 @@ CB_Yield_String_IMP(CharBuf *self) { void CB_Cat_Char_IMP(CharBuf *self, int32_t code_point) { + if (code_point < 0 + || (code_point >= 0xD800 && code_point < 0xE000) + || code_point >= 0x110000 + ) { + THROW(ERR, "Invalid code point: 0x%x32", (uint32_t)code_point); + } const size_t MAX_UTF8_BYTES = 4; size_t old_size = self->size; SI_add_grow_and_oversize(self, old_size, MAX_UTF8_BYTES); http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/ca3809d7/runtime/test/Clownfish/Test/TestCharBuf.c ---------------------------------------------------------------------- diff --git a/runtime/test/Clownfish/Test/TestCharBuf.c b/runtime/test/Clownfish/Test/TestCharBuf.c index 4329987..0782ce2 100644 --- a/runtime/test/Clownfish/Test/TestCharBuf.c +++ b/runtime/test/Clownfish/Test/TestCharBuf.c @@ -32,6 +32,7 @@ #include "Clownfish/Test.h" #include "Clownfish/TestHarness/TestBatchRunner.h" #include "Clownfish/TestHarness/TestUtils.h" +#include "Clownfish/Util/StringHelper.h" #include "Clownfish/Class.h" static char smiley[] = { (char)0xE2, (char)0x98, (char)0xBA, 0 }; @@ -102,6 +103,68 @@ test_Cat(TestBatchRunner *runner) { } static void +test_roundtrip(TestBatchRunner *runner) { + CharBuf *cb = CB_new(0); + int32_t code_point; + + for (code_point = 0; code_point <= 0x10FFFF; code_point++) { + if (code_point >= 0xD800 && code_point <= 0xDFFF) { continue; } + + CB_Cat_Char(cb, code_point); + String *str = CB_Yield_String(cb); + const char *start = Str_Get_Ptr8(str); + size_t size = Str_Get_Size(str); + + // Verify that utf8_valid agrees. + if (!StrHelp_utf8_valid(start, size)) { + break; + } + + // Verify round trip of encode/decode. + if (Str_Code_Point_At(str, 0) != code_point) { + break; + } + + DECREF(str); + } + if (code_point == 0x110000) { + PASS(runner, "Successfully round tripped 0 - 0x10FFFF"); + } + else { + FAIL(runner, "Failed round trip at 0x%04X", (unsigned)code_point); + } +} + +typedef struct { + CharBuf *cb; + int32_t code_point; +} CatCharContext; + +static void +S_cat_invalid_char(void *vcontext) { + CatCharContext *context = (CatCharContext*)vcontext; + CB_Cat_Char(context->cb, context->code_point); +} + +static void +test_invalid_chars(TestBatchRunner *runner) { + static const int32_t cps[] = { -1, 0xD800, 0xDFFF, 0x110000 }; + size_t num_cps = sizeof(cps) / sizeof(cps[0]); + CatCharContext context; + context.cb = CB_new(0); + + for (size_t i = 0; i < num_cps; i++) { + context.code_point = cps[i]; + Err *error = Err_trap(S_cat_invalid_char, &context); + TEST_TRUE(runner, error != NULL, "Cat_Char with invalid code point %d", + (int)cps[i]); + DECREF(error); + } + + DECREF(context.cb); +} + +static void test_Clone(TestBatchRunner *runner) { String *wanted = S_get_str("foo"); CharBuf *wanted_cb = S_get_cb("foo"); @@ -368,7 +431,7 @@ test_Get_Size(TestBatchRunner *runner) { void TestCB_Run_IMP(TestCharBuf *self, TestBatchRunner *runner) { - TestBatchRunner_Plan(runner, (TestBatch*)self, 41); + TestBatchRunner_Plan(runner, (TestBatch*)self, 46); test_vcatf_percent(runner); test_vcatf_s(runner); test_vcatf_s_invalid_utf8(runner); @@ -386,6 +449,8 @@ TestCB_Run_IMP(TestCharBuf *self, TestBatchRunner *runner) { test_vcatf_x32(runner); test_vcatf_invalid(runner); test_Cat(runner); + test_roundtrip(runner); + test_invalid_chars(runner); test_Clone(runner); test_Clear(runner); test_Grow(runner);