LCOV - code coverage report
Current view: top level - tests - safe-format-tests.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 52 55 94.5 %
Date: 2015-10-19 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :  * This file originated in realmd
       3             :  *
       4             :  * Copyright 2012 Red Hat Inc
       5             :  *
       6             :  * This program is free software: you can redistribute it and/or modify
       7             :  * it under the terms of the GNU Lesser General Public License as published
       8             :  * by the Free Software Foundation; either version 2 of the licence or (at
       9             :  * your option) any later version.
      10             :  *
      11             :  * See the included COPYING file for more information.
      12             :  *
      13             :  * Author: Stef Walter <stefw@redhat.com>
      14             :  */
      15             : 
      16             : #include "config.h"
      17             : 
      18             : #include "src/util/safe-format-string.h"
      19             : 
      20             : #include <check.h>
      21             : #include <popt.h>
      22             : #include <string.h>
      23             : #include <talloc.h>
      24             : 
      25             : #ifndef ck_assert_int_ge
      26             : #define ck_assert_int_ge(X, Y) _ck_assert_int(X, >=, Y)
      27             : #endif
      28             : 
      29             : #ifndef ck_assert_int_lt
      30             : #define ck_assert_int_lt(X, Y) _ck_assert_int(X, <, Y)
      31             : #endif
      32             : 
      33             : typedef struct {
      34             :     const char *format;
      35             :     const char *args[8];
      36             :     const char *result;
      37             : } Fixture;
      38             : 
      39             : static const Fixture fixtures[] = {
      40             :     {
      41             :       /* Just a bog standard string */
      42             :       "%s", { "blah", NULL, },
      43             :       "blah"
      44             :     },
      45             :     {
      46             :       /* Empty to print */
      47             :       "%s", { "", NULL, },
      48             :       ""
      49             :     },
      50             :     {
      51             :       /* Nothing to print */
      52             :       "", { "blah", NULL, },
      53             :       ""
      54             :     },
      55             :     {
      56             :       /* Width right aligned */
      57             :       "%8s", { "blah", NULL, },
      58             :       "    blah"
      59             :     },
      60             :     {
      61             :       /* Width left aligned */
      62             :       "whoop %-8s doo", { "dee", NULL, },
      63             :       "whoop dee      doo"
      64             :     },
      65             :     {
      66             :       /* Width space aligned (ignored) */
      67             :       "whoop % 8s doo", { "dee", NULL, },
      68             :       "whoop      dee doo"
      69             :     },
      70             :     {
      71             :       /* Width left space aligned (ignored) */
      72             :       "whoop % -8s doo", { "dee", NULL, },
      73             :       "whoop dee      doo"
      74             :     },
      75             :     {
      76             :       /* Precision 1 digit */
      77             :       "whoop %.3s doo", { "deedle-dee", NULL, },
      78             :       "whoop dee doo"
      79             :     },
      80             :     {
      81             :       /* Precision, N digits */
      82             :       "whoop %.10s doo", { "deedle-dee-deedle-do-deedle-dum", NULL, },
      83             :       "whoop deedle-dee doo"
      84             :     },
      85             :     {
      86             :       /* Precision, zero digits */
      87             :       "whoop %.s doo", { "deedle", NULL, },
      88             :       "whoop  doo"
      89             :     },
      90             :     {
      91             :       /* Multiple simple arguments */
      92             :       "space %s %s", { "man", "dances", NULL, },
      93             :       "space man dances"
      94             :     },
      95             :     {
      96             :       /* Literal percent */
      97             :       "100%% of space folk dance", { NULL, },
      98             :       "100% of space folk dance"
      99             :     },
     100             :     {
     101             :       /* Multiple simple arguments */
     102             :       "space %2$s %1$s", { "dances", "man", NULL, },
     103             :       "space man dances"
     104             :     },
     105             :     {
     106             :       /* Skipping an argument (not supported by standard printf) */
     107             :       "space %2$s dances", { "dances", "man", NULL, },
     108             :       "space man dances"
     109             :     },
     110             : 
     111             :     /* Failures start here */
     112             : 
     113             :     {
     114             :       /* Unsupported conversion */
     115             :       "%x", { "blah", NULL, },
     116             :       NULL
     117             :     },
     118             :     {
     119             :       /* Bad positional argument */
     120             :       "space %55$s dances", { "dances", "man", NULL, },
     121             :       NULL
     122             :     },
     123             :     {
     124             :       /* Zero positional argument */
     125             :       "space %0$s dances", { "dances", "man", NULL, },
     126             :       NULL
     127             :     },
     128             :     {
     129             :       /* Too many args used */
     130             :       "%s %s dances", { "space", NULL, },
     131             :       NULL
     132             :     },
     133             :     {
     134             :       /* Too many digits used */
     135             :       "%1234567890s dances", { "space", NULL, },
     136             :       NULL
     137             :     },
     138             : };
     139             : 
     140             : 
     141             : static void
     142          43 : callback(void *data, const char *piece, size_t len)
     143             : {
     144          43 :     char **str = data;
     145          43 :     *str = talloc_strndup_append(*str, piece, len);
     146          43 : }
     147             : 
     148          19 : START_TEST(test_safe_format_string_cb)
     149             : {
     150             :     const Fixture *fixture;
     151             :     char *out;
     152             :     int num_args;
     153             :     int ret;
     154             :     void *mem_ctx;
     155             : 
     156          19 :     fixture = &fixtures[_i];
     157          19 :     mem_ctx = talloc_init("safe-printf");
     158             : 
     159          61 :     for (num_args = 0; fixture->args[num_args] != NULL; )
     160          23 :         num_args++;
     161             : 
     162          19 :     out = talloc_strdup(mem_ctx, "");
     163          19 :     ret = safe_format_string_cb(callback, &out, fixture->format,
     164          19 :                                 (const char * const*)fixture->args, num_args);
     165          19 :     if (fixture->result) {
     166          14 :         ck_assert_int_ge(ret, 0);
     167          14 :         ck_assert_str_eq(out, fixture->result);
     168          14 :         ck_assert_int_eq(ret, strlen(out));
     169             :     } else {
     170           5 :         ck_assert_int_lt(ret, 0);
     171             :     }
     172             : 
     173          19 :     talloc_free(mem_ctx);
     174             : }
     175          19 : END_TEST
     176             : 
     177           1 : START_TEST(test_safe_format_string)
     178             : {
     179             :     char buffer[8];
     180             :     int ret;
     181             : 
     182           1 :     ret = safe_format_string(buffer, 8, "%s", "space", "man", NULL);
     183           1 :     ck_assert_int_eq(ret, 5);
     184           1 :     ck_assert_str_eq(buffer, "space");
     185             : 
     186           1 :     ret = safe_format_string(buffer, 8, "", "space", "man", NULL);
     187           1 :     ck_assert_int_eq(ret, 0);
     188           1 :     ck_assert_str_eq(buffer, "");
     189             : 
     190           1 :     ret = safe_format_string(buffer, 8, "the %s %s dances away", "space", "man", NULL);
     191           1 :     ck_assert_int_eq(ret, 25);
     192           1 :     ck_assert_str_eq(buffer, "the spa");
     193             : 
     194           1 :     ret = safe_format_string(NULL, 0, "the %s %s dances away", "space", "man", NULL);
     195           1 :     ck_assert_int_eq(ret, 25);
     196             : 
     197           1 :     ret = safe_format_string(buffer, 8, "%5$s", NULL);
     198           1 :     ck_assert_int_lt(ret, 0);
     199             : }
     200           1 : END_TEST
     201             : 
     202             : static Suite *
     203           1 : create_safe_format_suite(void)
     204             : {
     205           1 :     Suite *s = suite_create("safe-format");
     206           1 :     TCase *tc_format = tcase_create("safe-format-string");
     207             : 
     208             :     /* One for each fixture */
     209           1 :     tcase_add_loop_test(tc_format, test_safe_format_string_cb, 0,
     210             :                         (sizeof (fixtures) / sizeof (fixtures[0])));
     211             : 
     212           1 :     tcase_add_test(tc_format, test_safe_format_string);
     213             : 
     214           1 :     suite_add_tcase(s, tc_format);
     215             : 
     216           1 :     return s;
     217             : }
     218             : 
     219             : int
     220           1 : main(int argc, const char *argv[])
     221             : {
     222             :     int opt;
     223             :     poptContext pc;
     224             :     int failure_count;
     225             :     Suite *suite;
     226             :     SRunner *sr;
     227             : 
     228           1 :     struct poptOption long_options[] = {
     229             :         POPT_AUTOHELP
     230             :         POPT_TABLEEND
     231             :     };
     232             : 
     233           1 :     pc = poptGetContext(argv[0], argc, argv, long_options, 0);
     234           1 :     while((opt = poptGetNextOpt(pc)) != -1) {
     235             :         switch(opt) {
     236             :         default:
     237           0 :             fprintf(stderr, "\nInvalid option %s: %s\n\n",
     238             :                     poptBadOption(pc, 0), poptStrerror(opt));
     239           0 :             poptPrintUsage(pc, stderr, 0);
     240           0 :             return 1;
     241             :         }
     242             :     }
     243           1 :     poptFreeContext(pc);
     244             : 
     245           1 :     suite = create_safe_format_suite();
     246           1 :     sr = srunner_create(suite);
     247             :     /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
     248           1 :     srunner_run_all(sr, CK_ENV);
     249           1 :     failure_count = srunner_ntests_failed(sr);
     250           1 :     srunner_free(sr);
     251           1 :     return (failure_count==0 ? EXIT_SUCCESS : EXIT_FAILURE);
     252             : }

Generated by: LCOV version 1.10