>From 21a20775dd2cfb46c5d4acfbd2c42eb8a67e5a18 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Fri, 25 Jul 2014 10:22:59 +0200 Subject: [PATCH 2/3] UTIL: Add functions for replacing whitespaces. --- Makefile.am | 9 ++- src/tests/cmocka/test_string_utils.c | 150 +++++++++++++++++++++++++++++++++++ src/tests/cmocka/test_utils.c | 2 + src/tests/cmocka/test_utils.h | 4 + src/util/string_utils.c | 150 +++++++++++++++++++++++++++++++++++ src/util/util.h | 8 ++ 6 files changed, 320 insertions(+), 3 deletions(-) create mode 100644 src/tests/cmocka/test_string_utils.c create mode 100644 src/util/string_utils.c diff --git a/Makefile.am b/Makefile.am index 57f057633d527e75b61f4cf04c1af43c639aa608..340a85cf908b0bd6563b4043af61129c1bd0c41b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -673,7 +673,9 @@ libsss_util_la_SOURCES = \ src/util/sss_ini.c \ src/util/io.c \ src/util/util_sss_idmap.c \ - src/util/well_known_sids.c + src/util/well_known_sids.c \ + src/util/string_utils.c \ + $(NULL) libsss_util_la_CFLAGS = \ $(AM_CFLAGS) \ $(SYSTEMD_LOGIN_CFLAGS) @@ -1784,8 +1786,9 @@ test_ipa_idmap_LDADD = \ test_utils_SOURCES = \ src/tests/cmocka/test_utils.c \ - src/tests/cmocka/test_sss_ssh.c - + src/tests/cmocka/test_sss_ssh.c \ + src/tests/cmocka/test_string_utils.c \ + $(NULL) test_utils_CFLAGS = \ $(AM_CFLAGS) test_utils_LDADD = \ diff --git a/src/tests/cmocka/test_string_utils.c b/src/tests/cmocka/test_string_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..d10c3be47b83b97817e01af1e16cff987c49b2c5 --- /dev/null +++ b/src/tests/cmocka/test_string_utils.c @@ -0,0 +1,150 @@ +/* + Authors: + Lukas Slebodnik + + Copyright (C) 2014 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "util/util.h" +#include "tests/cmocka/common_mock.h" + +void test_replace_whitespaces(void **state) +{ + TALLOC_CTX *mem_ctx; + const char *input_str = "Lorem ipsum dolor sit amet"; + const char *res; + size_t i; + + struct { + const char *input; + const char *output; + const char *replace_string; + } data_set[] = { + { "", "", "-" }, + { " ", "-", "-" }, + { "\t", "-", "-" }, + { "\n", "-", "-" }, + { " \t\n ", "----", "-" }, + { "abcd", "abcd", "-" }, + { "a b c d", "a-b-c-d", "-" }, + { " a b c d ", "-a-b-c-d-", "-" }, + { " ", "^", "^" }, + { "\t", "^", "^" }, + { "\n", "^", "^" }, + { " \t\n ", "^^^^", "^" }, + { "abcd", "abcd", "^" }, + { "a b c d", "a^b^c^d", "^" }, + { " a b c d ", "^a^b^c^d^", "^" }, + { " ", "^", "^" }, + { "\t", ";-)", ";-)" }, + { "\n", ";-)", ";-)" }, + { " \t\n ", ";-);-);-);-)", ";-)" }, + { "abcd", "abcd", ";-)" }, + { "a b c d", "a;-)b;-)c;-)d", ";-)" }, + { " a b c d ", ";-)a;-)b;-)c;-)d;-)", ";-)" }, + { " ", " ", " " }, + { " ", " ", " " }, + { "abcd", "abcd", " " }, + { "a b c d", "a b c d", " " }, + { " a b c d ", " a b c d ", " " }, + { " ", " \t", " \t" }, + { " ", " \t \t \t \t", " \t" }, + { "abcd", "abcd", " \t" }, + { "a b c d", "a \tb \tc \td", " \t" }, + { " a b c d ", " \ta \tb \tc \td \t", " \t" }, + { NULL, NULL, NULL }, + }; + + mem_ctx = talloc_new(NULL); + assert_non_null(mem_ctx); + check_leaks_push(mem_ctx); + + res = sss_replace_whitespaces(mem_ctx, input_str, NULL); + assert_true(res == input_str); + + res = sss_replace_whitespaces(mem_ctx, input_str, ""); + assert_true(res == input_str); + + for (i=0; data_set[i].input != NULL; ++i) { + res = sss_replace_whitespaces(mem_ctx, data_set[i].input, + data_set[i].replace_string); + assert_non_null(res); + assert_string_equal(res, data_set[i].output); + talloc_zfree(res); + } + + assert_true(check_leaks_pop(mem_ctx) == true); + talloc_free(mem_ctx); +} + +void test_reverse_replace_whitespaces(void **state) +{ + TALLOC_CTX *mem_ctx; + char *input_str = discard_const_p(char, "Lorem ipsum dolor sit amet"); + char *res; + size_t i; + + struct { + const char *input; + const char *output; + const char *replace_string; + } data_set[] = { + { "", "", "-" }, + { "-", " ", "-" }, + { "----", " ", "-" }, + { "abcd", "abcd", "-" }, + { "a-b-c-d", "a b c d", "-" }, + { "-a-b-c-d-", " a b c d ", "-" }, + { "^", " ", "^" }, + { "^^^^", " ", "^" }, + { "abcd", "abcd", "^" }, + { "a^b^c^d", "a b c d", "^" }, + { "^a^b^c^d^", " a b c d ", "^" }, + { ";-)", " ", ";-)" }, + { ";-);-);-);-)", " ", ";-)" }, + { "abcd", "abcd", ";-)" }, + { "a;-)b;-)c;-)d", "a b c d", ";-)" }, + { ";-)a;-)b;-)c;-)d;-)", " a b c d ", ";-)" }, + { " ", " ", " " }, + { " ", " ", " " }, + { "abcd", "abcd", " " }, + { "a b c d", "a b c d", " " }, + { " a b c d ", " a b c d ", " " }, + { NULL, NULL, NULL }, + }; + + mem_ctx = talloc_new(NULL); + assert_non_null(mem_ctx); + check_leaks_push(mem_ctx); + + res = sss_reverse_replace_whitespaces(mem_ctx, input_str, NULL); + assert_true(res == input_str); + + res = sss_reverse_replace_whitespaces(mem_ctx, input_str, ""); + assert_true(res == input_str); + + for (i=0; data_set[i].input != NULL; ++i) { + input_str = discard_const_p(char, data_set[i].input); + res = sss_reverse_replace_whitespaces(mem_ctx, input_str, + data_set[i].replace_string); + assert_non_null(res); + assert_string_equal(res, data_set[i].output); + talloc_zfree(res); + } + + assert_true(check_leaks_pop(mem_ctx) == true); + talloc_free(mem_ctx); +} diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c index c1dfb66e1fb972ea45b17d65276d8c23a8a8e231..9d6cbf35f7c2e33c57b3a539b409848c22cf263e 100644 --- a/src/tests/cmocka/test_utils.c +++ b/src/tests/cmocka/test_utils.c @@ -917,6 +917,8 @@ int main(int argc, const char *argv[]) unit_test_setup_teardown(test_expand_homedir_template, setup_homedir_ctx, teardown_homedir_ctx), unit_test(test_textual_public_key), + unit_test(test_replace_whitespaces), + unit_test(test_reverse_replace_whitespaces), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ diff --git a/src/tests/cmocka/test_utils.h b/src/tests/cmocka/test_utils.h index 8f6269305d3fbea20841d00f626dc5d350e75cbd..f85ac2f2b3c50a60099970752b06adbad38b9fd1 100644 --- a/src/tests/cmocka/test_utils.h +++ b/src/tests/cmocka/test_utils.h @@ -26,4 +26,8 @@ /* from src/tests/cmocka/test_sss_ssh.c */ void test_textual_public_key(void **state); +/* from src/tests/cmocka/test_string_utils.c */ +void test_replace_whitespaces(void **state); +void test_reverse_replace_whitespaces(void **state); + #endif /* __TESTS__CMOCKA__TEST_UTILS_H__ */ diff --git a/src/util/string_utils.c b/src/util/string_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..8d878923f92060e7db57214add3280ecdea27601 --- /dev/null +++ b/src/util/string_utils.c @@ -0,0 +1,150 @@ +/* + SSSD + + Authors: + Lukas Slebodnik + + Copyright (C) 2014 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "util/util.h" + +const char * sss_replace_whitespaces(TALLOC_CTX *mem_ctx, + const char *orig_name, + const char *replace_string) +{ + char *new_name; + const char *ptr; + size_t replace_string_len; + TALLOC_CTX *tmp_ctx; + + if (replace_string == NULL || replace_string[0] == '\0') { + return orig_name; + } + + replace_string_len = strlen(replace_string); + /* faster implementations without multiple allocations */ + if (replace_string_len == 1) { + char *p; + new_name = talloc_strdup(mem_ctx, orig_name); + if (new_name == NULL) { + return NULL; + } + + for (p = new_name; *p != '\0'; ++p) { + if (isspace(*p)) { + *p = replace_string[0]; + } + } + + return new_name; + } + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return NULL; + } + + new_name = talloc_strdup(tmp_ctx, ""); + if (new_name == NULL) { + goto done; + } + + ptr = orig_name; + while (*ptr != '\0') { + if (isspace(*ptr)) { + new_name = talloc_asprintf_append(new_name, "%s", replace_string); + } else { + new_name = talloc_asprintf_append(new_name, "%c", *ptr); + } + if (new_name == NULL) { + goto done;; + } + + ++ptr; + } + + new_name = talloc_steal(mem_ctx, new_name); +done: + talloc_free(tmp_ctx); + return new_name; +} + +char * sss_reverse_replace_whitespaces(TALLOC_CTX *mem_ctx, + char *orig_name, + const char *replace_string) +{ + TALLOC_CTX *tmp_ctx; + char *substr; + char *new_name; + const char *ptr = orig_name; + size_t replace_string_len; + + if (replace_string == NULL || replace_string[0] == '\0') { + return orig_name; + } + + replace_string_len = strlen(replace_string); + /* faster implementations without multiple allocations */ + if (replace_string_len == 1) { + char *p; + new_name = talloc_strdup(mem_ctx, orig_name); + if (new_name == NULL) { + return NULL; + } + + for (p = new_name; *p != '\0'; ++p) { + if (*p == replace_string[0] ) { + *p = ' '; + } + } + + return new_name; + } + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return NULL; + } + + new_name = talloc_strdup(tmp_ctx, ""); + if (new_name == NULL) { + goto done; + } + + do { + substr = strstr(ptr, replace_string); + if (substr != NULL) { + new_name = talloc_asprintf_append(new_name, "%.*s ", + (int)(substr - ptr), ptr); + if (new_name == NULL) { + goto done; + } + ptr += substr - ptr; + ptr += replace_string_len; + } else { + new_name = talloc_asprintf_append(new_name, "%s", ptr); + if (new_name == NULL) { + goto done; + } + } + } while (substr != NULL); + + new_name = talloc_steal(mem_ctx, new_name); +done: + talloc_free(tmp_ctx); + return new_name; +} diff --git a/src/util/util.h b/src/util/util.h index cc1a38283e34e2bc25189084a9f6045357c9c935..35a8814e587d3050a265d9b82d88095fb82d4680 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -567,4 +567,12 @@ errno_t well_known_sid_to_name(const char *sid, const char **dom, errno_t name_to_well_known_sid(const char *dom, const char *name, const char **sid); +/* from string_utils.c */ +const char * sss_replace_whitespaces(TALLOC_CTX *mem_ctx, + const char *orig_name, + const char *replace_string); +char * sss_reverse_replace_whitespaces(TALLOC_CTX *mem_ctx, + char *orig_name, + const char *replace_string); + #endif /* __SSSD_UTIL_H__ */ -- 1.9.3