]> granicus.if.org Git - check/commitdiff
Do not vsnprintf expression string passed to ck_abort()
authorbrarcher <brarcher@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Wed, 30 Jul 2014 03:09:12 +0000 (03:09 +0000)
committerbrarcher <brarcher@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Wed, 30 Jul 2014 03:09:12 +0000 (03:09 +0000)
If ck_abort() detects a failure, the expression which was
evaluated is passed to _ck_assert_failed to print.
However, the previous behavior was to send the expression
to vsnprintf(), which would expect it to be properly formatted.

If the expression in ck_abort() contained % characters, such as:
   ck_abort(bar%foo == 0)
the "%f" portion would be printed as some non-existent floating
point number.

Now, if there is no message passed (and the expression is to
be used) simply report the expression as is. Only format
something with vsnprintf() if there is actual data that
expects formatting.

git-svn-id: svn+ssh://svn.code.sf.net/p/check/code/trunk@1183 64e312b2-a51f-0410-8e61-82d0ca0eb02a

NEWS
src/check.c
tests/check_check_master.c
tests/check_check_sub.c

diff --git a/NEWS b/NEWS
index 88d75b5b8740b8413286425adf6a191b89ce0348..34e25e3db98c5a2ea0220ec0078ba51ee770056a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
 In Development:
 # Mentioning Check 0.9.14 for now, to fix distcheck target until next release
 
+ * Fix issue with string formatting in ck_assert(), where using
+  the % operator would be interpreted as a string formatter. Bug #96.
 
 
 Sat July 26, 2014: Released Check 0.9.14
index 86308f50ac543eecd0820756689682b6af8a52c4..d288e6daa10b7854c01ab00e5658ff862b8350e9 100644 (file)
@@ -288,17 +288,29 @@ void _ck_assert_failed(const char *file, int line, const char *expr, ...)
     const char *msg;
     va_list ap;
     char buf[BUFSIZ];
+    const char *to_send;
 
     send_loc_info(file, line);
 
     va_start(ap, expr);
     msg = (const char *)va_arg(ap, char *);
 
-    if(msg == NULL)
-        msg = expr;
-    vsnprintf(buf, BUFSIZ, msg, ap);
+    /*
+     * If a message was passed, format it with vsnprintf.
+     * Otherwise, print the expression as is.
+     */
+    if(msg != NULL)
+    {
+        vsnprintf(buf, BUFSIZ, msg, ap);
+        to_send = buf;
+    }
+    else
+    {
+        to_send = expr;
+    }
+
     va_end(ap);
-    send_failure_info(buf);
+    send_failure_info(to_send);
     if(cur_fork_status() == CK_FORK)
     {
 #if defined(HAVE_FORK) && HAVE_FORK==1
index d29ecb41401fd354a5fb84534bbc6d547bf64f05..1fe409b388c673489a2616a8b5c02fc781699788 100644 (file)
@@ -57,6 +57,7 @@ static master_test_t master_tests[] = {
   { "Simple Tests", CK_FAILURE, "Failed" },
   { "Simple Tests", CK_FAILURE, "Assertion 'x == y' failed" },
   { "Simple Tests", CK_FAILURE, "Assertion '0' failed" },
+  { "Simple Tests", CK_FAILURE, "Assertion '1%f == 1' failed" },
   { "Simple Tests", CK_FAILURE, "Assertion 'x==y' failed: x==3, y==4" },
   { "Simple Tests", CK_FAILURE, "Assertion '3%d==2%f' failed: 3%d==1, 2%f==0" },
   { "Simple Tests", CK_FAILURE, "Assertion 'x!=y' failed: x==3, y==3" },
index ef2a6966a98672ad9774dce98ee0ffcc510d0922..6e6f3eceb496d6853d996f53c7914150adb20e83 100644 (file)
@@ -163,6 +163,14 @@ START_TEST(test_ck_assert_null)
 }
 END_TEST
 
+START_TEST(test_ck_assert_with_mod)
+{
+  int f = 1;
+  record_failure_line_num(__LINE__);
+  ck_assert(1%f == 1);
+}
+END_TEST
+
 START_TEST(test_ck_assert_int_eq)
 {
   int x = 3;
@@ -1018,6 +1026,7 @@ Suite *make_sub_suite(void)
   tcase_add_test (tc_simple, test_ck_abort_msg_null);
   tcase_add_test (tc_simple, test_ck_assert);
   tcase_add_test (tc_simple, test_ck_assert_null);
+  tcase_add_test (tc_simple, test_ck_assert_with_mod);
   tcase_add_test (tc_simple, test_ck_assert_int_eq);
   tcase_add_test (tc_simple, test_ck_assert_int_eq_with_mod);
   tcase_add_test (tc_simple, test_ck_assert_int_ne);