LCOV - code coverage report
Current view: top level - tests - util-tests.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 423 425 99.5 %
Date: 2012-11-29 Functions: 22 22 100.0 %
Branches: 50 90 55.6 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :     SSSD
       3                 :            : 
       4                 :            :     util-tests.c
       5                 :            : 
       6                 :            :     Authors:
       7                 :            :         Stephen Gallagher <sgallagh@redhat.com>
       8                 :            : 
       9                 :            :     Copyright (C) 2010 Red Hat
      10                 :            : 
      11                 :            :     This program is free software; you can redistribute it and/or modify
      12                 :            :     it under the terms of the GNU General Public License as published by
      13                 :            :     the Free Software Foundation; either version 3 of the License, or
      14                 :            :     (at your option) any later version.
      15                 :            : 
      16                 :            :     This program is distributed in the hope that it will be useful,
      17                 :            :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :     GNU General Public License for more details.
      20                 :            : 
      21                 :            :     You should have received a copy of the GNU General Public License
      22                 :            :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23                 :            : */
      24                 :            : 
      25                 :            : #include <popt.h>
      26                 :            : #include <talloc.h>
      27                 :            : #include <check.h>
      28                 :            : #include <sys/types.h>
      29                 :            : #include <sys/stat.h>
      30                 :            : #include <fcntl.h>
      31                 :            : #include "util/util.h"
      32                 :            : #include "util/sss_utf8.h"
      33                 :            : #include "util/murmurhash3.h"
      34                 :            : #include "tests/common.h"
      35                 :            : 
      36                 :            : #define FILENAME_TEMPLATE "tests-atomicio-XXXXXX"
      37                 :            : char *filename;
      38                 :            : int atio_fd;
      39                 :            : 
      40                 :          1 : START_TEST(test_add_string_to_list)
      41                 :            : {
      42                 :            :     int ret;
      43                 :            : 
      44                 :          1 :     char **list = NULL;
      45                 :            : 
      46                 :          1 :     ret = add_string_to_list(NULL, NULL, NULL);
      47                 :          1 :     fail_unless(ret == EINVAL, "NULL input accepted");
      48                 :            : 
      49                 :          1 :     ret = add_string_to_list(global_talloc_context, "ABC", &list);
      50                 :          1 :     fail_unless(ret == EOK, "Adding string to non-existing list failed.");
      51                 :          1 :     fail_unless(list != NULL, "No new list created.");
      52                 :          1 :     fail_unless(list[0] != NULL, "String not added to new list.");
      53 [ +  - ][ +  - ]:          1 :     fail_unless(strcmp(list[0], "ABC") == 0,
                 [ +  - ]
      54                 :            :                 "Wrong string added to newly created list.");
      55                 :          1 :     fail_unless(list[1] == NULL,
      56                 :            :                 "Missing terminating NULL in newly created list.");
      57                 :            : 
      58                 :          1 :     ret = add_string_to_list(global_talloc_context, "DEF", &list);
      59                 :          1 :     fail_unless(ret == EOK, "Adding string to list failed.");
      60                 :          1 :     fail_unless(list != NULL, "No list returned.");
      61 [ +  - ][ +  - ]:          1 :     fail_unless(strcmp(list[0], "ABC") == 0, "Wrong first string in new list.");
                 [ +  - ]
      62 [ +  - ][ +  - ]:          1 :     fail_unless(strcmp(list[1], "DEF") == 0, "Wrong string added to list.");
                 [ +  - ]
      63                 :          1 :     fail_unless(list[2] == NULL, "Missing terminating NULL.");
      64                 :            : 
      65                 :          1 :     list[0] = NULL;
      66                 :          1 :     ret = add_string_to_list(global_talloc_context, "ABC", &list);
      67                 :          1 :     fail_unless(ret == EOK, "Adding string to empty list failed.");
      68                 :          1 :     fail_unless(list != NULL, "No list returned.");
      69                 :          1 :     fail_unless(list[0] != NULL, "String not added to empty list.");
      70 [ +  - ][ +  - ]:          1 :     fail_unless(strcmp(list[0], "ABC") == 0,
                 [ +  - ]
      71                 :            :                 "Wrong string added to empty list.");
      72                 :          1 :     fail_unless(list[1] == NULL,
      73                 :            :                 "Missing terminating NULL in newly created list.");
      74                 :            : 
      75                 :          1 :     talloc_free(list);
      76                 :            : }
      77                 :          1 : END_TEST
      78                 :            : 
      79                 :          1 : START_TEST(test_string_in_list)
      80                 :            : {
      81                 :            :     bool is_in;
      82                 :          1 :     char *empty_list[] = {NULL};
      83                 :          1 :     char *list[] = {discard_const("ABC"),
      84                 :            :                     discard_const("DEF"),
      85                 :            :                     discard_const("GHI"),
      86                 :            :                     NULL};
      87                 :            : 
      88                 :          1 :     is_in = string_in_list(NULL, NULL, false);
      89                 :          1 :     fail_unless(!is_in, "NULL string is in NULL list.");
      90                 :            : 
      91                 :          1 :     is_in = string_in_list(NULL, empty_list, false);
      92                 :          1 :     fail_unless(!is_in, "NULL string is in empty list.");
      93                 :            : 
      94                 :          1 :     is_in = string_in_list(NULL, list, false);
      95                 :          1 :     fail_unless(!is_in, "NULL string is in list.");
      96                 :            : 
      97                 :          1 :     is_in = string_in_list("ABC", NULL, false);
      98                 :          1 :     fail_unless(!is_in, "String is in NULL list.");
      99                 :            : 
     100                 :          1 :     is_in = string_in_list("ABC", empty_list, false);
     101                 :          1 :     fail_unless(!is_in, "String is in empty list.");
     102                 :            : 
     103                 :          1 :     is_in = string_in_list("ABC", list, false);
     104                 :          1 :     fail_unless(is_in, "String is not list.");
     105                 :            : 
     106                 :          1 :     is_in = string_in_list("abc", list, false);
     107                 :          1 :     fail_unless(is_in, "String is not case in-sensitive list.");
     108                 :            : 
     109                 :          1 :     is_in = string_in_list("abc", list, true);
     110                 :          1 :     fail_unless(!is_in, "Wrong string found in case sensitive list.");
     111                 :            : 
     112                 :          1 :     is_in = string_in_list("123", list, false);
     113                 :          1 :     fail_unless(!is_in, "Wrong string found in list.");
     114                 :            : 
     115                 :            : }
     116                 :          1 : END_TEST
     117                 :            : 
     118                 :          1 : START_TEST(test_parse_args)
     119                 :            : {
     120                 :            :     struct pa_testcase {
     121                 :            :         const char *argstr;
     122                 :            :         const char **parsed;
     123                 :            :     };
     124                 :            : 
     125                 :            :     TALLOC_CTX *test_ctx;
     126                 :            :     int i, ii;
     127                 :            :     int ret;
     128                 :            :     char **parsed;
     129                 :            :     char **only_ret;
     130                 :            :     char **only_exp;
     131                 :            :     char **both;
     132                 :            : 
     133                 :          1 :     test_ctx = talloc_new(NULL);
     134                 :            : 
     135                 :            :     /* Positive tests */
     136                 :          1 :     const char *parsed1[] = { "foo", NULL };
     137                 :          1 :     const char *parsed2[] = { "foo", "a", NULL };
     138                 :          1 :     const char *parsed3[] = { "foo", "b", NULL };
     139                 :          1 :     const char *parsed4[] = { "foo", "a c", NULL };
     140                 :          1 :     const char *parsed5[] = { "foo", "a", "d", NULL };
     141                 :          1 :     const char *parsed6[] = { "foo", "a", "e", NULL };
     142                 :          1 :     const char *parsed7[] = { "foo", "a", "f", NULL };
     143                 :          1 :     const char *parsed8[] = { "foo", "a\tg", NULL };
     144                 :          1 :     struct pa_testcase tc[] = {
     145                 :            :         { "foo", parsed1 },
     146                 :            :         { "foo a", parsed2 },
     147                 :            :         { "foo  b", parsed3 },
     148                 :            :         { "foo a\\ c", parsed4 },
     149                 :            :         { "foo a d ", parsed5 },
     150                 :            :         { "foo   a   e   ", parsed6 },
     151                 :            :         { "foo     a               f       ", parsed7 },
     152                 :            :         { "foo a\\\tg", parsed8 },
     153                 :            :         { NULL, NULL }
     154                 :            :     };
     155                 :            : 
     156         [ +  + ]:          9 :     for (i=0; tc[i].argstr != NULL; i++) {
     157                 :          8 :         parsed = parse_args(tc[i].argstr);
     158 [ -  + ][ #  # ]:          8 :         fail_if(parsed == NULL && tc[i].parsed != NULL,
     159                 :            :                 "Could not parse correct argument string '%s'\n");
     160                 :            : 
     161                 :          8 :         ret = diff_string_lists(test_ctx, parsed, discard_const(tc[i].parsed),
     162                 :            :                                 &only_ret, &only_exp, &both);
     163                 :          8 :         fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
     164                 :          8 :         fail_unless(only_ret[0] == NULL, "The parser returned more data than expected\n");
     165                 :          8 :         fail_unless(only_exp[0] == NULL, "The parser returned less data than expected\n");
     166                 :            : 
     167         [ +  + ]:         34 :         for (ii = 0; parsed[ii]; ii++) free(parsed[ii]);
     168                 :          8 :         free(parsed);
     169                 :            :     }
     170                 :            : 
     171                 :          1 :     talloc_free(test_ctx);
     172                 :            : }
     173                 :          1 : END_TEST
     174                 :            : 
     175                 :          1 : START_TEST(test_diff_string_lists)
     176                 :            : {
     177                 :            :     TALLOC_CTX *test_ctx;
     178                 :            :     char **l1;
     179                 :            :     char **l2;
     180                 :            :     char **l3;
     181                 :            :     char **only_l1;
     182                 :            :     char **only_l2;
     183                 :            :     char **both;
     184                 :            :     int ret;
     185                 :            : 
     186                 :          1 :     test_ctx = talloc_new(NULL);
     187                 :            : 
     188                 :            :     /* Test with all values returned */
     189                 :          1 :     l1 = talloc_array(test_ctx, char *, 4);
     190                 :          1 :     l1[0] = talloc_strdup(l1, "a");
     191                 :          1 :     l1[1] = talloc_strdup(l1, "b");
     192                 :          1 :     l1[2] = talloc_strdup(l1, "c");
     193                 :          1 :     l1[3] = NULL;
     194                 :            : 
     195                 :          1 :     l2 = talloc_array(test_ctx, char *, 4);
     196                 :          1 :     l2[0] = talloc_strdup(l1, "d");
     197                 :          1 :     l2[1] = talloc_strdup(l1, "c");
     198                 :          1 :     l2[2] = talloc_strdup(l1, "b");
     199                 :          1 :     l2[3] = NULL;
     200                 :            : 
     201                 :          1 :     ret = diff_string_lists(test_ctx,
     202                 :            :                             l1, l2,
     203                 :            :                             &only_l1, &only_l2, &both);
     204                 :            : 
     205                 :          1 :     fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
     206         [ +  - ]:          1 :     fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1");
     207                 :          1 :     fail_unless(only_l1[1] == NULL, "only_l1 not NULL-terminated");
     208         [ +  - ]:          1 :     fail_unless(strcmp(only_l2[0], "d") == 0, "Missing \"d\" from only_l2");
     209                 :          1 :     fail_unless(only_l2[1] == NULL, "only_l2 not NULL-terminated");
     210         [ +  - ]:          1 :     fail_unless(strcmp(both[0], "c") == 0, "Missing \"c\" from both");
     211         [ +  - ]:          1 :     fail_unless(strcmp(both[1], "b") == 0, "Missing \"b\" from both");
     212                 :          1 :     fail_unless(both[2] == NULL, "both not NULL-terminated");
     213                 :            : 
     214                 :          1 :     talloc_zfree(only_l1);
     215                 :          1 :     talloc_zfree(only_l2);
     216                 :          1 :     talloc_zfree(both);
     217                 :            : 
     218                 :            :     /* Test with restricted return values */
     219                 :          1 :     ret = diff_string_lists(test_ctx,
     220                 :            :                             l1, l2,
     221                 :            :                             &only_l1, &only_l2, NULL);
     222                 :            : 
     223                 :          1 :     fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
     224         [ +  - ]:          1 :     fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1");
     225                 :          1 :     fail_unless(only_l1[1] == NULL, "only_l1 not NULL-terminated");
     226         [ +  - ]:          1 :     fail_unless(strcmp(only_l2[0], "d") == 0, "Missing \"d\" from only_l2");
     227                 :          1 :     fail_unless(only_l2[1] == NULL, "only_l2 not NULL-terminated");
     228                 :          1 :     fail_unless(both == NULL, "Nothing returned to both");
     229                 :            : 
     230                 :          1 :     talloc_zfree(only_l1);
     231                 :          1 :     talloc_zfree(only_l2);
     232                 :          1 :     talloc_zfree(both);
     233                 :            : 
     234                 :          1 :     ret = diff_string_lists(test_ctx,
     235                 :            :                             l1, l2,
     236                 :            :                             &only_l1, NULL, NULL);
     237                 :            : 
     238                 :          1 :     fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
     239         [ +  - ]:          1 :     fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1");
     240                 :          1 :     fail_unless(only_l1[1] == NULL, "only_l1 not NULL-terminated");
     241                 :          1 :     fail_unless(only_l2 == NULL, "Nothing returned to only_l2");
     242                 :          1 :     fail_unless(both == NULL, "Nothing returned to both");
     243                 :            : 
     244                 :          1 :     talloc_zfree(only_l1);
     245                 :          1 :     talloc_zfree(only_l2);
     246                 :          1 :     talloc_zfree(both);
     247                 :            : 
     248                 :          1 :     ret = diff_string_lists(test_ctx,
     249                 :            :                             l1, l2,
     250                 :            :                             NULL, &only_l2, NULL);
     251                 :            : 
     252                 :          1 :     fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
     253         [ +  - ]:          1 :     fail_unless(strcmp(only_l2[0], "d") == 0, "Missing \"d\" from only_l2");
     254                 :          1 :     fail_unless(only_l2[1] == NULL, "only_l2 not NULL-terminated");
     255                 :          1 :     fail_unless(only_l1 == NULL, "Nothing returned to only_l1");
     256                 :          1 :     fail_unless(both == NULL, "Nothing returned to both");
     257                 :            : 
     258                 :          1 :     talloc_zfree(only_l1);
     259                 :          1 :     talloc_zfree(only_l2);
     260                 :          1 :     talloc_zfree(both);
     261                 :            : 
     262                 :            :     /* Test with no overlap */
     263                 :          1 :     l3 = talloc_array(test_ctx, char *, 4);
     264                 :          1 :     l3[0] = talloc_strdup(l1, "d");
     265                 :          1 :     l3[1] = talloc_strdup(l1, "e");
     266                 :          1 :     l3[2] = talloc_strdup(l1, "f");
     267                 :          1 :     l3[3] = NULL;
     268                 :            : 
     269                 :          1 :     ret = diff_string_lists(test_ctx,
     270                 :            :                             l1, l3,
     271                 :            :                             &only_l1, &only_l2, &both);
     272                 :            : 
     273                 :          1 :     fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
     274         [ +  - ]:          1 :     fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1");
     275         [ +  - ]:          1 :     fail_unless(strcmp(only_l1[1], "b") == 0, "Missing \"b\" from only_l1");
     276         [ +  - ]:          1 :     fail_unless(strcmp(only_l1[2], "c") == 0, "Missing \"c\" from only_l1");
     277                 :          1 :     fail_unless(only_l1[3] == NULL, "only_l1 not NULL-terminated");
     278         [ +  - ]:          1 :     fail_unless(strcmp(only_l2[0], "d") == 0, "Missing \"f\" from only_l2");
     279         [ +  - ]:          1 :     fail_unless(strcmp(only_l2[1], "e") == 0, "Missing \"e\" from only_l2");
     280         [ +  - ]:          1 :     fail_unless(strcmp(only_l2[2], "f") == 0, "Missing \"d\" from only_l2");
     281                 :          1 :     fail_unless(only_l2[3] == NULL, "only_l2 not NULL-terminated");
     282                 :          1 :     fail_unless(both[0] == NULL, "both should have zero entries");
     283                 :            : 
     284                 :          1 :     talloc_zfree(only_l1);
     285                 :          1 :     talloc_zfree(only_l2);
     286                 :          1 :     talloc_zfree(both);
     287                 :            : 
     288                 :            :     /* Test with 100% overlap */
     289                 :          1 :     ret = diff_string_lists(test_ctx,
     290                 :            :                             l1, l1,
     291                 :            :                             &only_l1, &only_l2, &both);
     292                 :            : 
     293                 :          1 :     fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
     294                 :          1 :     fail_unless(only_l1[0] == NULL, "only_l1 should have zero entries");
     295                 :          1 :     fail_unless(only_l2[0] == NULL, "only_l2 should have zero entries");
     296         [ +  - ]:          1 :     fail_unless(strcmp(both[0], "a") == 0, "Missing \"a\" from both");
     297         [ +  - ]:          1 :     fail_unless(strcmp(both[1], "b") == 0, "Missing \"b\" from both");
     298         [ +  - ]:          1 :     fail_unless(strcmp(both[2], "c") == 0, "Missing \"c\" from both");
     299                 :          1 :     fail_unless(both[3] == NULL, "both is not NULL-terminated");
     300                 :            : 
     301                 :          1 :     talloc_zfree(only_l1);
     302                 :          1 :     talloc_zfree(only_l2);
     303                 :          1 :     talloc_zfree(both);
     304                 :            : 
     305                 :            :     /* Test with no second list */
     306                 :          1 :     ret = diff_string_lists(test_ctx,
     307                 :            :                             l1, NULL,
     308                 :            :                             &only_l1, &only_l2, &both);
     309                 :            : 
     310                 :          1 :     fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
     311         [ +  - ]:          1 :     fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1");
     312         [ +  - ]:          1 :     fail_unless(strcmp(only_l1[1], "b") == 0, "Missing \"b\" from only_l1");
     313         [ +  - ]:          1 :     fail_unless(strcmp(only_l1[2], "c") == 0, "Missing \"c\" from only_l1");
     314                 :          1 :     fail_unless(only_l1[3] == NULL, "only_l1 not NULL-terminated");
     315                 :          1 :     fail_unless(only_l2[0] == NULL, "only_l2 should have zero entries");
     316                 :          1 :     fail_unless(both[0] == NULL, "both should have zero entries");
     317                 :            : 
     318                 :          1 :     talloc_free(test_ctx);
     319                 :            : }
     320                 :          1 : END_TEST
     321                 :            : 
     322                 :            : 
     323                 :          1 : START_TEST(test_sss_filter_sanitize)
     324                 :            : {
     325                 :            :     errno_t ret;
     326                 :          1 :     char *sanitized = NULL;
     327                 :            : 
     328                 :          1 :     TALLOC_CTX *test_ctx = talloc_new(NULL);
     329                 :          1 :     fail_if (test_ctx == NULL, "Out of memory");
     330                 :            : 
     331                 :          1 :     const char no_specials[] = "username";
     332                 :          1 :     ret = sss_filter_sanitize(test_ctx, no_specials, &sanitized);
     333                 :          1 :     fail_unless(ret == EOK, "no_specials error [%d][%s]",
     334                 :            :                 ret, strerror(ret));
     335                 :          1 :     fail_unless(strcmp(no_specials, sanitized)==0,
     336                 :            :                 "Expected [%s], got [%s]",
     337                 :            :                 no_specials, sanitized);
     338                 :            : 
     339                 :          1 :     const char has_asterisk[] = "*username";
     340                 :          1 :     const char has_asterisk_expected[] = "\\2ausername";
     341                 :          1 :     ret = sss_filter_sanitize(test_ctx, has_asterisk, &sanitized);
     342                 :          1 :     fail_unless(ret == EOK, "has_asterisk error [%d][%s]",
     343                 :            :                 ret, strerror(ret));
     344                 :          1 :     fail_unless(strcmp(has_asterisk_expected, sanitized)==0,
     345                 :            :                 "Expected [%s], got [%s]",
     346                 :            :                 has_asterisk_expected, sanitized);
     347                 :            : 
     348                 :          1 :     const char has_lparen[] = "user(name";
     349                 :          1 :     const char has_lparen_expected[] = "user\\28name";
     350                 :          1 :     ret = sss_filter_sanitize(test_ctx, has_lparen, &sanitized);
     351                 :          1 :     fail_unless(ret == EOK, "has_lparen error [%d][%s]",
     352                 :            :                 ret, strerror(ret));
     353                 :          1 :     fail_unless(strcmp(has_lparen_expected, sanitized)==0,
     354                 :            :                 "Expected [%s], got [%s]",
     355                 :            :                 has_lparen_expected, sanitized);
     356                 :            : 
     357                 :          1 :     const char has_rparen[] = "user)name";
     358                 :          1 :     const char has_rparen_expected[] = "user\\29name";
     359                 :          1 :     ret = sss_filter_sanitize(test_ctx, has_rparen, &sanitized);
     360                 :          1 :     fail_unless(ret == EOK, "has_rparen error [%d][%s]",
     361                 :            :                 ret, strerror(ret));
     362                 :          1 :     fail_unless(strcmp(has_rparen_expected, sanitized)==0,
     363                 :            :                 "Expected [%s], got [%s]",
     364                 :            :                 has_rparen_expected, sanitized);
     365                 :            : 
     366                 :          1 :     const char has_backslash[] = "username\\";
     367                 :          1 :     const char has_backslash_expected[] = "username\\5c";
     368                 :          1 :     ret = sss_filter_sanitize(test_ctx, has_backslash, &sanitized);
     369                 :          1 :     fail_unless(ret == EOK, "has_backslash error [%d][%s]",
     370                 :            :                 ret, strerror(ret));
     371                 :          1 :     fail_unless(strcmp(has_backslash_expected, sanitized)==0,
     372                 :            :                 "Expected [%s], got [%s]",
     373                 :            :                 has_backslash_expected, sanitized);
     374                 :            : 
     375                 :          1 :     const char has_all[] = "\\(user)*name";
     376                 :          1 :     const char has_all_expected[] = "\\5c\\28user\\29\\2aname";
     377                 :          1 :     ret = sss_filter_sanitize(test_ctx, has_all, &sanitized);
     378                 :          1 :     fail_unless(ret == EOK, "has_all error [%d][%s]",
     379                 :            :                 ret, strerror(ret));
     380                 :          1 :     fail_unless(strcmp(has_all_expected, sanitized)==0,
     381                 :            :                 "Expected [%s], got [%s]",
     382                 :            :                 has_all_expected, sanitized);
     383                 :            : 
     384                 :          1 :     talloc_free(test_ctx);
     385                 :            : }
     386                 :          1 : END_TEST
     387                 :            : 
     388                 :          1 : START_TEST(test_size_t_overflow)
     389                 :            : {
     390                 :          1 :     fail_unless(!SIZE_T_OVERFLOW(1, 1), "unexpected overflow");
     391                 :          1 :     fail_unless(!SIZE_T_OVERFLOW(SIZE_T_MAX, 0), "unexpected overflow");
     392                 :          1 :     fail_unless(!SIZE_T_OVERFLOW(SIZE_T_MAX-10, 10), "unexpected overflow");
     393                 :          1 :     fail_unless(SIZE_T_OVERFLOW(SIZE_T_MAX, 1), "overflow not detected");
     394                 :          1 :     fail_unless(SIZE_T_OVERFLOW(SIZE_T_MAX, SIZE_T_MAX),
     395                 :            :                 "overflow not detected");
     396                 :          1 :     fail_unless(SIZE_T_OVERFLOW(SIZE_T_MAX, ULLONG_MAX),
     397                 :            :                 "overflow not detected");
     398                 :          1 :     fail_unless(SIZE_T_OVERFLOW(SIZE_T_MAX, -10), "overflow not detected");
     399                 :            : }
     400                 :          1 : END_TEST
     401                 :            : 
     402                 :          1 : START_TEST(test_utf8_lowercase)
     403                 :            : {
     404                 :          1 :     const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
     405                 :          1 :     const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 };
     406                 :            :     uint8_t *lcase;
     407                 :            :     size_t nlen;
     408                 :            : 
     409                 :          1 :     lcase = sss_utf8_tolower(munchen_utf8_upcase,
     410                 :            :                              strlen((const char *)munchen_utf8_upcase),
     411                 :            :                              &nlen);
     412                 :          1 :     fail_if(strlen((const char *) munchen_utf8_upcase) != nlen); /* This is not true for utf8 strings in general */
     413                 :          1 :     fail_if(memcmp(lcase, munchen_utf8_lowcase, nlen));
     414                 :          1 :     sss_utf8_free(lcase);
     415                 :            : }
     416                 :          1 : END_TEST
     417                 :            : 
     418                 :          1 : START_TEST(test_utf8_talloc_lowercase)
     419                 :            : {
     420                 :          1 :     const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
     421                 :          1 :     const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 };
     422                 :            :     uint8_t *lcase;
     423                 :            :     size_t nsize;
     424                 :            : 
     425                 :            :     TALLOC_CTX *test_ctx;
     426                 :          1 :     test_ctx = talloc_new(NULL);
     427                 :          1 :     fail_if(test_ctx == NULL);
     428                 :            : 
     429                 :          1 :     lcase = sss_tc_utf8_tolower(test_ctx, munchen_utf8_upcase,
     430                 :            :                                 strlen((const char *) munchen_utf8_upcase),
     431                 :            :                                 &nsize);
     432                 :          1 :     fail_if(memcmp(lcase, munchen_utf8_lowcase, nsize));
     433                 :          1 :     talloc_free(test_ctx);
     434                 :            : }
     435                 :          1 : END_TEST
     436                 :            : 
     437                 :          1 : START_TEST(test_utf8_talloc_str_lowercase)
     438                 :            : {
     439                 :          1 :     const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
     440                 :          1 :     const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 };
     441                 :            :     char *lcase;
     442                 :            : 
     443                 :            :     TALLOC_CTX *test_ctx;
     444                 :          1 :     test_ctx = talloc_new(NULL);
     445                 :          1 :     fail_if(test_ctx == NULL);
     446                 :            : 
     447                 :          1 :     lcase = sss_tc_utf8_str_tolower(test_ctx, (const char *) munchen_utf8_upcase);
     448                 :          1 :     fail_if(memcmp(lcase, munchen_utf8_lowcase, strlen(lcase)));
     449                 :          1 :     talloc_free(test_ctx);
     450                 :            : }
     451                 :          1 : END_TEST
     452                 :            : 
     453                 :          1 : START_TEST(test_utf8_caseeq)
     454                 :            : {
     455                 :          1 :     const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
     456                 :          1 :     const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 };
     457                 :          1 :     const uint8_t czech_utf8_lowcase[] = { 0xC4, 0x8D, 'e', 'c', 'h', 0x0 };
     458                 :          1 :     const uint8_t czech_utf8_upcase[] = { 0xC4, 0x8C, 'e', 'c', 'h', 0x0 };
     459                 :          1 :     const uint8_t czech_utf8_lowcase_neg[] = { 0xC4, 0x8E, 'e', 'c', 'h', 0x0 };
     460                 :            :     errno_t ret;
     461                 :            : 
     462                 :          1 :     ret = sss_utf8_case_eq(munchen_utf8_upcase, munchen_utf8_lowcase);
     463                 :          1 :     fail_unless(ret == EOK, "Latin 1 Supplement comparison failed\n");
     464                 :            : 
     465                 :          1 :     ret = sss_utf8_case_eq(czech_utf8_upcase, czech_utf8_lowcase);
     466                 :          1 :     fail_unless(ret == EOK, "Latin Extended A comparison failed\n");
     467                 :            : 
     468                 :          1 :     ret = sss_utf8_case_eq(czech_utf8_upcase, czech_utf8_lowcase_neg);
     469                 :          1 :     fail_if(ret == EOK, "Negative test succeeded\n");
     470                 :            : }
     471                 :          1 : END_TEST
     472                 :            : 
     473                 :          1 : START_TEST(test_utf8_check)
     474                 :            : {
     475                 :          1 :     const char *invalid = "ad\351la\357d";
     476                 :          1 :     const uint8_t valid[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
     477                 :            :     bool ret;
     478                 :            : 
     479                 :          1 :     ret = sss_utf8_check(valid, strlen((const char *) valid));
     480                 :          1 :     fail_unless(ret == true, "Positive test failed\n");
     481                 :            : 
     482                 :          1 :     ret = sss_utf8_check((const uint8_t *) invalid, strlen(invalid));
     483                 :          1 :     fail_unless(ret == false, "Negative test succeeded\n");
     484                 :            : }
     485                 :          1 : END_TEST
     486                 :            : 
     487                 :          1 : START_TEST(test_murmurhash3_check)
     488                 :            : {
     489                 :          1 :     const char *tests[6] = { "1052800007", "1052800008", "1052800000",
     490                 :            :                              "abcdefghijk", "abcdefghili", "abcdefgh000" };
     491                 :            :     uint32_t results[6];
     492                 :            :     int i, j;
     493                 :            : 
     494         [ +  + ]:          7 :     for (i = 0; i< 6; i++) {
     495                 :          6 :         results[i] = murmurhash3(tests[i],
     496                 :          6 :                                  strlen(tests[i]),
     497                 :            :                                  0xdeadbeef);
     498         [ +  + ]:         21 :         for (j = 0; j < i; j++) {
     499                 :         15 :             fail_if(results[i] == results[j]);
     500                 :            :         }
     501                 :            :     }
     502                 :            : }
     503                 :          1 : END_TEST
     504                 :            : 
     505                 :          1 : START_TEST(test_murmurhash3_random)
     506                 :            : {
     507                 :            :     char test[16];
     508                 :            :     uint32_t result1;
     509                 :            :     uint32_t result2;
     510                 :            :     unsigned int init_seed;
     511                 :            :     unsigned int seed;
     512                 :            :     size_t len;
     513                 :            :     int i;
     514                 :            : 
     515                 :            :     /* generate a random string so each time we test with different values */
     516                 :          1 :     init_seed = time(0);
     517                 :          1 :     seed = init_seed;
     518                 :            :     /* use also random length (min len = 1) */
     519                 :          1 :     len = 1 + rand_r(&seed) % 14;
     520         [ +  + ]:          7 :     for (i = 0; i < len; i++) {
     521                 :          6 :         test[i] = 1 + rand_r(&seed) % 254;
     522                 :            :     }
     523                 :          1 :     test[len] = '\0'; /* null terminate */
     524                 :            : 
     525                 :          1 :     fprintf(stdout, "test_murmurhash3_random seed: %d\n", init_seed);
     526                 :            : 
     527                 :          1 :     result1 = murmurhash3(test, len + 1, init_seed);
     528                 :          1 :     result2 = murmurhash3(test, len + 1, init_seed);
     529                 :          1 :     fail_if(result1 != result2);
     530                 :            : }
     531                 :          1 : END_TEST
     532                 :            : 
     533                 :          5 : void setup_atomicio(void)
     534                 :            : {
     535                 :            :     int ret;
     536                 :            :     mode_t old_umask;
     537                 :            : 
     538         [ +  - ]:          5 :     filename = strdup(FILENAME_TEMPLATE);
     539                 :          5 :     fail_unless(filename != NULL, "strdup failed");
     540                 :            : 
     541                 :          5 :     atio_fd = -1;
     542                 :          5 :     old_umask = umask(077);
     543                 :          5 :     ret = mkstemp(filename);
     544                 :          5 :     umask(old_umask);
     545                 :          5 :     fail_unless(ret != -1, "mkstemp failed [%d][%s]", errno, strerror(errno));
     546                 :          5 :     atio_fd = ret;
     547                 :          5 : }
     548                 :            : 
     549                 :          5 : void teardown_atomicio(void)
     550                 :            : {
     551                 :            :     int ret;
     552                 :            : 
     553         [ +  - ]:          5 :     if (atio_fd != -1) {
     554                 :          5 :         ret = close(atio_fd);
     555                 :          5 :         fail_unless(ret == 0, "close failed [%d][%s]", errno, strerror(errno));
     556                 :            :     }
     557                 :            : 
     558                 :          5 :     fail_unless(filename != NULL, "unknown filename");
     559                 :          5 :     ret = unlink(filename);
     560                 :          5 :     free(filename);
     561                 :          5 :     fail_unless(ret == 0, "unlink failed [%d][%s]", errno, strerror(errno));
     562                 :          5 : }
     563                 :            : 
     564                 :          1 : START_TEST(test_atomicio_read_from_file)
     565                 :            : {
     566                 :          1 :     const ssize_t bufsize = 64;
     567                 :            :     char buf[64];
     568                 :            :     int fd;
     569                 :            :     ssize_t numread;
     570                 :            :     errno_t ret;
     571                 :            : 
     572                 :          1 :     fd = open("/dev/zero", O_RDONLY);
     573                 :          1 :     fail_if(fd == -1, "Cannot open /dev/zero");
     574                 :            : 
     575                 :          1 :     errno = 0;
     576                 :          1 :     numread = sss_atomic_read_s(fd, buf, bufsize);
     577                 :          1 :     ret = errno;
     578                 :            : 
     579                 :          1 :     fail_unless(ret == 0, "Error %d while reading\n", ret);
     580                 :          1 :     fail_unless(numread == bufsize,
     581                 :            :                 "Read %d bytes expected %d\n", numread, bufsize);
     582                 :          1 :     close(fd);
     583                 :            : }
     584                 :          1 : END_TEST
     585                 :            : 
     586                 :          1 : START_TEST(test_atomicio_read_from_small_file)
     587                 :            : {
     588                 :          1 :     char wbuf[] = "foobar";
     589                 :          1 :     ssize_t wsize = strlen(wbuf)+1;
     590                 :            :     ssize_t numwritten;
     591                 :            :     char rbuf[64];
     592                 :            :     ssize_t numread;
     593                 :            :     errno_t ret;
     594                 :            : 
     595                 :          1 :     fail_if(atio_fd < 0, "No fd to test?\n");
     596                 :            : 
     597                 :          1 :     errno = 0;
     598                 :          1 :     numwritten = sss_atomic_write_s(atio_fd, wbuf, wsize);
     599                 :          1 :     ret = errno;
     600                 :            : 
     601                 :          1 :     fail_unless(ret == 0, "Error %d while writing\n", ret);
     602                 :          1 :     fail_unless(numwritten == wsize,
     603                 :            :                 "Wrote %d bytes expected %d\n", numwritten, wsize);
     604                 :            : 
     605                 :          1 :     fsync(atio_fd);
     606                 :          1 :     lseek(atio_fd, 0, SEEK_SET);
     607                 :            : 
     608                 :          1 :     errno = 0;
     609                 :          1 :     numread = sss_atomic_read_s(atio_fd, rbuf, 64);
     610                 :          1 :     ret = errno;
     611                 :            : 
     612                 :          1 :     fail_unless(ret == 0, "Error %d while reading\n", ret);
     613                 :          1 :     fail_unless(numread == numwritten,
     614                 :            :                 "Read %d bytes expected %d\n", numread, numwritten);
     615                 :            : }
     616                 :          1 : END_TEST
     617                 :            : 
     618                 :          1 : START_TEST(test_atomicio_read_from_large_file)
     619                 :            : {
     620                 :          1 :     char wbuf[] = "123456781234567812345678";
     621                 :          1 :     ssize_t wsize = strlen(wbuf)+1;
     622                 :            :     ssize_t numwritten;
     623                 :            :     char rbuf[8];
     624                 :            :     ssize_t numread;
     625                 :            :     ssize_t total;
     626                 :            :     errno_t ret;
     627                 :            : 
     628                 :          1 :     fail_if(atio_fd < 0, "No fd to test?\n");
     629                 :            : 
     630                 :          1 :     errno = 0;
     631                 :          1 :     numwritten = sss_atomic_write_s(atio_fd, wbuf, wsize);
     632                 :          1 :     ret = errno;
     633                 :            : 
     634                 :          1 :     fail_unless(ret == 0, "Error %d while writing\n", ret);
     635                 :          1 :     fail_unless(numwritten == wsize,
     636                 :            :                 "Wrote %d bytes expected %d\n", numwritten, wsize);
     637                 :            : 
     638                 :          1 :     fsync(atio_fd);
     639                 :          1 :     lseek(atio_fd, 0, SEEK_SET);
     640                 :            : 
     641                 :          1 :     total = 0;
     642                 :            :     do {
     643                 :          5 :         errno = 0;
     644                 :          5 :         numread = sss_atomic_read_s(atio_fd, rbuf, 8);
     645                 :          5 :         ret = errno;
     646                 :            : 
     647                 :          5 :         fail_if(numread == -1, "Read error %d: %s\n", ret, strerror(ret));
     648                 :          5 :         total += numread;
     649         [ +  + ]:          5 :     } while (numread != 0);
     650                 :            : 
     651                 :          1 :     fail_unless(ret == 0, "Error %d while reading\n", ret);
     652                 :          1 :     fail_unless(total == numwritten,
     653                 :            :                 "Read %d bytes expected %d\n", numread, numwritten);
     654                 :            : }
     655                 :          1 : END_TEST
     656                 :            : 
     657                 :          1 : START_TEST(test_atomicio_read_exact_sized_file)
     658                 :            : {
     659                 :          1 :     char wbuf[] = "12345678";
     660                 :          1 :     ssize_t wsize = strlen(wbuf)+1;
     661                 :            :     ssize_t numwritten;
     662                 :            :     char rbuf[9];
     663                 :            :     ssize_t numread;
     664                 :            :     errno_t ret;
     665                 :            : 
     666                 :          1 :     fail_if(atio_fd < 0, "No fd to test?\n");
     667                 :            : 
     668                 :          1 :     errno = 0;
     669                 :          1 :     numwritten = sss_atomic_write_s(atio_fd, wbuf, wsize);
     670                 :          1 :     ret = errno;
     671                 :            : 
     672                 :          1 :     fail_unless(ret == 0, "Error %d while writing\n", ret);
     673                 :          1 :     fail_unless(numwritten == wsize,
     674                 :            :                 "Wrote %d bytes expected %d\n", numwritten, wsize);
     675                 :            : 
     676                 :          1 :     fsync(atio_fd);
     677                 :          1 :     lseek(atio_fd, 0, SEEK_SET);
     678                 :            : 
     679                 :          1 :     errno = 0;
     680                 :          1 :     numread = sss_atomic_read_s(atio_fd, rbuf, 9);
     681                 :          1 :     ret = errno;
     682                 :            : 
     683                 :          1 :     fail_unless(ret == 0, "Error %d while reading\n", ret);
     684                 :          1 :     fail_unless(numread == numwritten,
     685                 :            :                 "Read %d bytes expected %d\n", numread, numwritten);
     686                 :            : 
     687                 :          1 :     fail_unless(rbuf[8] == '\0', "String not NULL terminated?");
     688                 :          1 :     fail_unless(strcmp(wbuf, rbuf) == 0, "Read something else than wrote?");
     689                 :            : 
     690                 :            :     /* We've reached end-of-file, next read must return 0 */
     691                 :          1 :     errno = 0;
     692                 :          1 :     numread = sss_atomic_read_s(atio_fd, rbuf, 9);
     693                 :          1 :     ret = errno;
     694                 :            : 
     695                 :          1 :     fail_unless(ret == 0, "Error %d while reading\n", ret);
     696                 :          1 :     fail_unless(numread == 0, "More data to read?");
     697                 :            : }
     698                 :          1 : END_TEST
     699                 :            : 
     700                 :          1 : START_TEST(test_atomicio_read_from_empty_file)
     701                 :            : {
     702                 :            :     char buf[64];
     703                 :            :     int fd;
     704                 :            :     ssize_t numread;
     705                 :            :     errno_t ret;
     706                 :            : 
     707                 :          1 :     fd = open("/dev/null", O_RDONLY);
     708                 :          1 :     fail_if(fd == -1, "Cannot open /dev/null");
     709                 :            : 
     710                 :          1 :     errno = 0;
     711                 :          1 :     numread = sss_atomic_read_s(fd, buf, 64);
     712                 :          1 :     ret = errno;
     713                 :            : 
     714                 :          1 :     fail_unless(ret == 0, "Error %d while reading\n", ret);
     715                 :          1 :     fail_unless(numread == 0,
     716                 :            :                 "Read %d bytes expected 0\n", numread);
     717                 :          1 :     close(fd);
     718                 :            : }
     719                 :          1 : END_TEST
     720                 :            : 
     721                 :         19 : Suite *util_suite(void)
     722                 :            : {
     723                 :         19 :     Suite *s = suite_create("util");
     724                 :            : 
     725                 :         19 :     TCase *tc_util = tcase_create("util");
     726                 :            : 
     727                 :         19 :     tcase_add_checked_fixture(tc_util,
     728                 :            :                               leak_check_setup,
     729                 :            :                               leak_check_teardown);
     730                 :         19 :     tcase_add_test (tc_util, test_diff_string_lists);
     731                 :         19 :     tcase_add_test (tc_util, test_sss_filter_sanitize);
     732                 :         19 :     tcase_add_test (tc_util, test_size_t_overflow);
     733                 :         19 :     tcase_add_test (tc_util, test_parse_args);
     734                 :         19 :     tcase_add_test (tc_util, test_add_string_to_list);
     735                 :         19 :     tcase_add_test (tc_util, test_string_in_list);
     736                 :         19 :     tcase_set_timeout(tc_util, 60);
     737                 :            : 
     738                 :         19 :     TCase *tc_utf8 = tcase_create("utf8");
     739                 :         19 :     tcase_add_test (tc_utf8, test_utf8_lowercase);
     740                 :         19 :     tcase_add_test (tc_utf8, test_utf8_talloc_lowercase);
     741                 :         19 :     tcase_add_test (tc_utf8, test_utf8_talloc_str_lowercase);
     742                 :         19 :     tcase_add_test (tc_utf8, test_utf8_caseeq);
     743                 :         19 :     tcase_add_test (tc_utf8, test_utf8_check);
     744                 :            : 
     745                 :         19 :     tcase_set_timeout(tc_utf8, 60);
     746                 :            : 
     747                 :         19 :     TCase *tc_mh3 = tcase_create("murmurhash3");
     748                 :         19 :     tcase_add_test (tc_mh3, test_murmurhash3_check);
     749                 :         19 :     tcase_add_test (tc_mh3, test_murmurhash3_random);
     750                 :         19 :     tcase_set_timeout(tc_mh3, 60);
     751                 :            : 
     752                 :         19 :     TCase *tc_atomicio = tcase_create("atomicio");
     753                 :         19 :     tcase_add_checked_fixture (tc_atomicio,
     754                 :            :                                setup_atomicio,
     755                 :            :                                teardown_atomicio);
     756                 :         19 :     tcase_add_test(tc_atomicio, test_atomicio_read_from_file);
     757                 :         19 :     tcase_add_test(tc_atomicio, test_atomicio_read_from_small_file);
     758                 :         19 :     tcase_add_test(tc_atomicio, test_atomicio_read_from_large_file);
     759                 :         19 :     tcase_add_test(tc_atomicio, test_atomicio_read_exact_sized_file);
     760                 :         19 :     tcase_add_test(tc_atomicio, test_atomicio_read_from_empty_file);
     761                 :            : 
     762                 :         19 :     suite_add_tcase (s, tc_util);
     763                 :         19 :     suite_add_tcase (s, tc_utf8);
     764                 :         19 :     suite_add_tcase (s, tc_mh3);
     765                 :         19 :     suite_add_tcase (s, tc_atomicio);
     766                 :            : 
     767                 :         19 :     return s;
     768                 :            : }
     769                 :            : 
     770                 :         19 : int main(int argc, const char *argv[])
     771                 :            : {
     772                 :            :     int opt;
     773                 :            :     int failure_count;
     774                 :            :     poptContext pc;
     775                 :         19 :     Suite *s = util_suite();
     776                 :         19 :     SRunner *sr = srunner_create (s);
     777                 :            : 
     778                 :         95 :     struct poptOption long_options[] = {
     779                 :            :         POPT_AUTOHELP
     780                 :         76 :         SSSD_MAIN_OPTS
     781                 :            :         POPT_TABLEEND
     782                 :            :     };
     783                 :            : 
     784                 :            :     /* Set debug level to invalid value so we can deside if -d 0 was used. */
     785                 :         19 :     debug_level = SSSDBG_INVALID;
     786                 :            : 
     787                 :         19 :     pc = poptGetContext(argv[0], argc, argv, long_options, 0);
     788         [ -  + ]:         19 :     while((opt = poptGetNextOpt(pc)) != -1) {
     789                 :            :         switch(opt) {
     790                 :            :         default:
     791                 :          0 :             fprintf(stderr, "\nInvalid option %s: %s\n\n",
     792                 :            :                     poptBadOption(pc, 0), poptStrerror(opt));
     793                 :          0 :             poptPrintUsage(pc, stderr, 0);
     794                 :            :             return 1;
     795                 :            :         }
     796                 :            :     }
     797                 :         19 :     poptFreeContext(pc);
     798                 :            : 
     799         [ -  + ]:         19 :     DEBUG_INIT(debug_level);
     800                 :            : 
     801                 :         19 :     tests_set_cwd();
     802                 :            : 
     803                 :         19 :     srunner_run_all(sr, CK_ENV);
     804                 :          1 :     failure_count = srunner_ntests_failed (sr);
     805                 :          1 :     srunner_free (sr);
     806         [ -  + ]:          1 :     if (failure_count == 0) {
     807                 :            :         return EXIT_SUCCESS;
     808                 :            :     }
     809                 :            :     return  EXIT_FAILURE;
     810                 :            : }

Generated by: LCOV version 1.9