From: Dotsenko Andrey Date: Sat, 3 Dec 2016 17:20:53 +0000 (+0300) Subject: ck_assert_str_*: fix segmentation fault while comparing with NULL X-Git-Tag: 0.11.0~8^2~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ae8cfeb6c17844a35c1b51e33150b354144f6cee;p=check ck_assert_str_*: fix segmentation fault while comparing with NULL --- diff --git a/src/check.h.in b/src/check.h.in index 07ecd6c..3b85fac 100644 --- a/src/check.h.in +++ b/src/check.h.in @@ -1362,18 +1362,46 @@ do { \ #define ck_assert_ldouble_nonnan(X) _ck_assert_floating_nonnan(X, long double, "L") /* String comparison macros with improved output compared to ck_assert() */ -/* OP might be any operator that can be used in '0 OP strcmp(X,Y)' comparison */ -/* The x and y parameter swap in strcmp() is needed to handle >, >=, <, <= operators */ -#define _ck_assert_str(X, OP, Y) do { \ +/* OP might be any operator that can be used in '0 OP strcmp(X,Y)' comparison. */ +/* String pointer could be compared againts NULL with == (NULLEQ = 1) and != (NULLNE = 1) operators. */ +/* The x and y parameter swap in strcmp() is needed to handle >, >=, <, <= operators. */ +/* If the x or y parameter is NULL its value will be printed without quotes. */ +#define _ck_assert_str(X, OP, Y, NULLEQ, NULLNE) do { \ const char* _ck_x = (X); \ const char* _ck_y = (Y); \ - ck_assert_msg(0 OP strcmp(_ck_y, _ck_x), \ - "Assertion '%s' failed: %s == \"%s\", %s == \"%s\"", #X" "#OP" "#Y, #X, _ck_x, #Y, _ck_y); \ + const char* _ck_x_s; \ + const char* _ck_y_s; \ + const char* _ck_x_q; \ + const char* _ck_y_q; \ + if (_ck_x != NULL) { \ + _ck_x_q = "\""; \ + _ck_x_s = _ck_x; \ + } else { \ + _ck_x_q = ""; \ + _ck_x_s = "(null)"; \ + } \ + if (_ck_y != NULL) { \ + _ck_y_q = "\""; \ + _ck_y_s = _ck_y; \ + } else { \ + _ck_y_q = ""; \ + _ck_y_s = "(null)"; \ + } \ + ck_assert_msg( \ + (NULLEQ && (_ck_x == NULL) && (_ck_y == NULL)) || \ + (NULLNE && ((_ck_x == NULL) || (_ck_y == NULL)) && (_ck_x != _ck_y)) || \ + ((_ck_x != NULL) && (_ck_y != NULL) && (0 OP strcmp(_ck_y, _ck_x))), \ + "Assertion '%s' failed: %s == %s%s%s, %s == %s%s%s", \ + #X" "#OP" "#Y, \ + #X, _ck_x_q, _ck_x_s, _ck_x_q, \ + #Y, _ck_y_q, _ck_y_s, _ck_y_q); \ } while (0) + /** * Check two strings to determine if 0==strcmp(X,Y) * - * If not 0==strcmp(X,Y), the test fails. + * If X or Y is NULL the test failes. + * If (0==strcmp(X,Y)), the test fails. * * @param X string * @param Y string to compare against X @@ -1382,10 +1410,12 @@ do { \ * * @since 0.9.6 */ -#define ck_assert_str_eq(X, Y) _ck_assert_str(X, ==, Y) +#define ck_assert_str_eq(X, Y) _ck_assert_str(X, ==, Y, 0, 0) + /** * Check two strings to determine if 0!=strcmp(X,Y) * + * If X or Y is NULL the test fails. * If not 0!=strcmp(X,Y), the test fails. * * @param X string @@ -1395,10 +1425,12 @@ do { \ * * @since 0.9.6 */ -#define ck_assert_str_ne(X, Y) _ck_assert_str(X, !=, Y) +#define ck_assert_str_ne(X, Y) _ck_assert_str(X, !=, Y, 0, 0) + /** * Check two strings to determine if 00) * + * If X or Y is NULL the test fails. * If not 0=0) * + * If X or Y is NULL the test fails. * If not 0<=strcmp(X,Y), the test fails. * * @param X string @@ -1421,10 +1455,12 @@ do { \ * * @since 0.9.10 */ -#define ck_assert_str_le(X, Y) _ck_assert_str(X, <=, Y) +#define ck_assert_str_le(X, Y) _ck_assert_str(X, <=, Y, 0, 0) + /** * Check two strings to determine if 00) * + * If X or Y is NULL the test fails. * If not 0, Y) +#define ck_assert_str_gt(X, Y) _ck_assert_str(X, >, Y, 0, 0) + /** * Check two strings to determine if 0>=strcmp(X,Y) (e.g. strcmp(X,Y)<=0) * + * If X or Y is NULL the test fails. * If not 0>=strcmp(X,Y), the test fails. * * @param X string @@ -1447,7 +1485,7 @@ do { \ * * @since 0.9.10 */ -#define ck_assert_str_ge(X, Y) _ck_assert_str(X, >=, Y) +#define ck_assert_str_ge(X, Y) _ck_assert_str(X, >=, Y, 0, 0) /* Memory location comparison macros with improved output compared to ck_assert() */ /* OP might be any operator that can be used in '0 OP memcmp(X,Y,L)' comparison */