diff --git a/src/common/guac_iconv.c b/src/common/guac_iconv.c index 90b335cc..a6fd89d9 100644 --- a/src/common/guac_iconv.c +++ b/src/common/guac_iconv.c @@ -24,6 +24,7 @@ #include "guac_iconv.h" #include +#include void guac_iconv(guac_iconv_read* reader, char** input, int in_remaining, guac_iconv_write* writer, char** output, int out_remaining) { @@ -62,8 +63,19 @@ int GUAC_READ_UTF8(char** input, int remaining) { } int GUAC_READ_UTF16(char** input, int remaining) { - /* STUB */ - return 0; + + int value; + + /* Bail if not enough data */ + if (remaining < 2) + return 0; + + /* Read two bytes as integer */ + value = *((uint16_t*) *input); + *input += 2; + + return value; + } void GUAC_WRITE_UTF8(char** output, int remaining, int value) { @@ -71,6 +83,14 @@ void GUAC_WRITE_UTF8(char** output, int remaining, int value) { } void GUAC_WRITE_UTF16(char** output, int remaining, int value) { - /* STUB */ + + /* Bail if not enough data */ + if (remaining < 2) + return; + + /* Write two bytes as integer */ + *((uint16_t*) *output) = value; + *output += 2; + } diff --git a/tests/common/guac_iconv.c b/tests/common/guac_iconv.c index 67739cad..aca40e0e 100644 --- a/tests/common/guac_iconv.c +++ b/tests/common/guac_iconv.c @@ -28,21 +28,68 @@ #include #include -void test_guac_iconv() { +static void test_conversion( + guac_iconv_read* reader, unsigned char* in_string, int in_length, + guac_iconv_write* writer, unsigned char* out_string, int out_length) { char output[4096]; - char input[4096] = "hello"; + char input[4096]; - char* current_output = output; char* current_input = input; + char* current_output = output; - /* Test identity conversion of UTF8 */ - guac_iconv(GUAC_READ_UTF8, ¤t_input, 4096, - GUAC_WRITE_UTF8, ¤t_output, 4096); + memcpy(input, in_string, in_length); + guac_iconv(reader, ¤t_input, sizeof(input), + writer, ¤t_output, sizeof(output)); - CU_ASSERT_EQUAL(6, current_output - output); - CU_ASSERT_EQUAL(6, current_input - input); - CU_ASSERT_EQUAL(0, memcmp("hello", output, 6)); + /* Verify output length */ + CU_ASSERT_EQUAL(out_length, current_output - output); + + /* Verify entire input read */ + CU_ASSERT_EQUAL(in_length, current_input - input); + + /* Verify output content */ + CU_ASSERT_EQUAL(0, memcmp(output, out_string, out_length)); + +} + +void test_guac_iconv() { + + /* UTF8 for "papà è bello" */ + unsigned char test_string_utf8[] = { + 'p', 'a', 'p', 0xC3, 0xA0, ' ', + 0xC3, 0xA8, ' ', + 'b', 'e', 'l', 'l', 'o', + 0x00 + }; + + /* UTF16 for "papà è bello" */ + unsigned char test_string_utf16[] = { + 'p', 0x00, 'a', 0x00, 'p', 0x00, 0xE0, 0x00, ' ', 0x00, + 0xE8, 0x00, ' ', 0x00, + 'b', 0x00, 'e', 0x00, 'l', 0x00, 'l', 0x00, 'o', 0x00, + 0x00, 0x00 + }; + + /* UTF8 identity */ + test_conversion( + GUAC_READ_UTF8, test_string_utf8, sizeof(test_string_utf8), + GUAC_WRITE_UTF8, test_string_utf8, sizeof(test_string_utf8)); + + /* UTF16 identity */ + test_conversion( + GUAC_READ_UTF16, test_string_utf16, sizeof(test_string_utf16), + GUAC_WRITE_UTF16, test_string_utf16, sizeof(test_string_utf16)); + + /* UTF8 to UTF16 */ + test_conversion( + GUAC_READ_UTF8, test_string_utf8, sizeof(test_string_utf8), + GUAC_WRITE_UTF16, test_string_utf16, sizeof(test_string_utf16)); + + /* UTF16 to UTF8 */ + test_conversion( + GUAC_READ_UTF16, test_string_utf16, sizeof(test_string_utf16), + GUAC_WRITE_UTF8, test_string_utf8, sizeof(test_string_utf8)); }