From 7e8d40b57a5b1bec4555e4107e2c70f44cbda956 Mon Sep 17 00:00:00 2001 From: Lyude Date: Thu, 13 Oct 2016 13:11:43 -0400 Subject: [PATCH] libratbag-util: Add test suite for iconv helpers After learning that just using this mouse was not the greatest way of figuring out whether or not the iconv helpers worked, I decided to write a few simple tests to ensure silly things like this don't happen again. Changes since v1: - fix indentation - Fix year in copyright on test-iconv-helper.c - Use an encoding that's definitely invalid for the iconv_invalid_encoding test - Add tests for a bunch of bad utf16le strings - Add tests for converting emojis to/from utf16le. Just so we have some actually multibyte characters in here. --- test/Makefile.am | 7 +- test/test-iconv-helper.c | 178 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 test/test-iconv-helper.c diff --git a/test/Makefile.am b/test/Makefile.am index fe959edb..f7207074 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -11,7 +11,8 @@ TEST_LIBS = $(CHECK_LIBS) $(LIBEVDEV_LIBS) $(top_builddir)/src/libratbag.la run_tests = \ test-context \ - test-device + test-device \ + test-iconv-helper build_tests = \ test-build-cxx \ @@ -31,6 +32,10 @@ test_device_SOURCES = test-device.c test_device_LDADD = $(TEST_LIBS) test_device_LDFLAGS = -no-install +test_iconv_helper_SOURCES = test-iconv-helper.c +test_iconv_helper_LDADD = $(TEST_LIBS) $(top_builddir)/src/libutil.la +test_iconv_helper_LDFLAGS = -no-install + # build-test only test_build_pedantic_c99_SOURCES = build-pedantic.c test_build_pedantic_c99_CFLAGS = -std=c99 -pedantic -Werror diff --git a/test/test-iconv-helper.c b/test/test-iconv-helper.c new file mode 100644 index 00000000..cc3c9f1b --- /dev/null +++ b/test/test-iconv-helper.c @@ -0,0 +1,178 @@ +/* + * Copyright Β© 2016 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include "libratbag-util.h" + +static const char sample_utf16le[] = { 'F', '\0', 'o', '\0', 'o', '\0' }; +static const char sample_single_char_utf16le[] = { 'A', '\0' }; + +/* Sample UTF-8 string used: πŸΊπŸ––πŸ—ΊπŸ—ΉπŸ’―πŸ‘ */ +static const char sample_emoji_utf8[] = { + 0xf0, 0x9f, 0x90, 0xba, 0xf0, 0x9f, 0x96, 0x96, 0xf0, 0x9f, 0x97, 0xba, + 0xf0, 0x9f, 0x97, 0xb9, 0xf0, 0x9f, 0x92, 0xaf, 0xf0, 0x9f, 0x91, 0x8f, + 0x0a, 0x00 +}; + +static const char sample_emoji_utf16le[] = { + 0x3d, 0xd8, 0x3a, 0xdc, 0x3d, 0xd8, 0x96, 0xdd, 0x3d, 0xd8, 0xfa, 0xdd, + 0x3d, 0xd8, 0xf9, 0xdd, 0x3d, 0xd8, 0xaf, 0xdc, 0x3d, 0xd8, 0x4f, 0xdc, + 0x0a, 0x00 +}; + +START_TEST(iconv_convert_to_utf16le) +{ + char output[4096]; + ssize_t rc; + + rc = ratbag_utf8_to_enc(output, sizeof(sample_utf16le), + "UTF-16LE", "%s", "Foo"); + + ck_assert_int_eq(rc, sizeof(sample_utf16le)); + ck_assert(memcmp(output, sample_utf16le, sizeof(sample_utf16le)) == 0); + + rc = ratbag_utf8_to_enc(output, sizeof(sample_emoji_utf16le), + "UTF-16LE", "%s", sample_emoji_utf8); + + ck_assert_int_eq(rc, sizeof(sample_emoji_utf16le)); + ck_assert(memcmp(output, sample_emoji_utf16le, + sizeof(sample_emoji_utf16le)) == 0); + + rc = ratbag_utf8_to_enc(output, sizeof(sample_single_char_utf16le), + "UTF-16LE", "%s", "A"); + + ck_assert_int_eq(rc, sizeof(sample_single_char_utf16le)); + ck_assert(memcmp(output, sample_single_char_utf16le, + sizeof(sample_single_char_utf16le)) == 0); +} +END_TEST + +START_TEST(iconv_convert_from_utf16le) +{ + char input[4096]; + char *output; + ssize_t rc; + + memcpy(input, sample_utf16le, sizeof(sample_utf16le)); + rc = ratbag_utf8_from_enc(input, sizeof(sample_utf16le), + "UTF-16LE", &output); + + ck_assert_int_eq(rc, sizeof("Foo")); + ck_assert(memcmp(output, "Foo", sizeof("Foo")) == 0); + free(output); + + memcpy(input, sample_emoji_utf16le, sizeof(sample_emoji_utf16le)); + rc = ratbag_utf8_from_enc(input, sizeof(sample_emoji_utf16le), + "UTF-16LE", &output); + + ck_assert_int_eq(rc, sizeof(sample_emoji_utf8)); + ck_assert(memcmp(output, sample_emoji_utf8, + sizeof(sample_emoji_utf8)) == 0); + free(output); + + memcpy(input, sample_single_char_utf16le, + sizeof(sample_single_char_utf16le)); + rc = ratbag_utf8_from_enc(input, sizeof(sample_single_char_utf16le), + "UTF-16LE", &output); + + ck_assert_int_eq(rc, sizeof("A")); + ck_assert(memcmp(output, "A", sizeof("A")) == 0); + free(output); +} +END_TEST + +START_TEST(iconv_invalid_encoding) +{ + char output[10] = { 0 }; + ssize_t rc; + + rc = ratbag_utf8_to_enc(output, sizeof(output), + "This encoding is invalid", "%s", "Foo"); + + ck_assert_int_eq(rc, -EINVAL); +} +END_TEST + +START_TEST(iconv_bad_utf16le) +{ + char odd_numbered[] = { 'F', '\0', 'o' }; + char single_char[] = { 'F' }; + char single_null[] = { '\0' }; + char double_null[] = { 'F', '\0', '\0', 'o', '\0', 'o', '\0' }; + char *output; + ssize_t rc; + + rc = ratbag_utf8_from_enc(odd_numbered, sizeof(odd_numbered), + "UTF-16LE", &output); + ck_assert_int_eq(rc, -EINVAL); + + rc = ratbag_utf8_from_enc(single_char, sizeof(single_char), "UTF-16LE", + &output); + ck_assert_int_eq(rc, -EINVAL); + + rc = ratbag_utf8_from_enc(single_null, sizeof(single_null), "UTF-16LE", + &output); + ck_assert_int_eq(rc, -EINVAL); + + rc = ratbag_utf8_from_enc(double_null, sizeof(double_null), "UTF-16LE", + &output); + ck_assert_int_eq(rc, -EINVAL); +} +END_TEST + +static Suite * +test_context_suite(void) +{ + TCase *tc; + Suite *s; + + s = suite_create("iconv-helper"); + tc = tcase_create("iconv-helper"); + tcase_add_test(tc, iconv_convert_to_utf16le); + tcase_add_test(tc, iconv_convert_from_utf16le); + tcase_add_test(tc, iconv_invalid_encoding); + tcase_add_test(tc, iconv_bad_utf16le); + suite_add_tcase(s, tc); + + return s; +} + +int main(void) +{ + int nfailed; + Suite *s; + SRunner *sr; + + s = test_context_suite(); + sr = srunner_create(s); + + srunner_run_all(sr, CK_ENV); + nfailed = srunner_ntests_failed(sr); + srunner_free(sr); + + return (nfailed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +}