Author: brane Date: Fri May 30 22:55:53 2025 New Revision: 1925997 URL: http://svn.apache.org/viewvc?rev=1925997&view=rev Log: Compiler warning cleanup. In this chapter: silence narrowing conversion warnings and one shadowed argument.
* serf_private.h (SERF__CONV_assert): New debug-only assertion macro. (SERF__POSITIVE_TO_INT): Convert wider unsigned (or positive) values to int. Avoid typecasts that could yield a negative result. (SERF__SIGNED_TO_INT): Convert wider signed values to int. * auth/auth.h (SERF_AUTH_assert): Remove, it's only use is gone. * auth/auth.c (serf__encode_auth_header): Use SERF__POSITIVE_TO_INT. * buckets/bwtp_buckets.c (parse_status_line): Use SERF__POSITIVE_TO_INT. * buckets/response_buckets.c (parse_status_line): And again. * test/serf_bwtp.c (main): Just use casts for narrowing conversions, this is an example and must not use the private header. * test/serf_spider.c (main): Likewise. (create_request): Rename the 'c' argument to avoid a shadowing warning. Modified: serf/trunk/auth/auth.c serf/trunk/auth/auth.h serf/trunk/buckets/bwtp_buckets.c serf/trunk/buckets/response_buckets.c serf/trunk/serf_private.h serf/trunk/test/serf_bwtp.c serf/trunk/test/serf_spider.c serf/trunk/test/test_internal.c Modified: serf/trunk/auth/auth.c URL: http://svn.apache.org/viewvc/serf/trunk/auth/auth.c?rev=1925997&r1=1925996&r2=1925997&view=diff ============================================================================== --- serf/trunk/auth/auth.c (original) +++ serf/trunk/auth/auth.c Fri May 30 22:55:53 2025 @@ -389,14 +389,11 @@ void serf__encode_auth_header(const char apr_pool_t *pool) { apr_size_t encoded_len, scheme_len; + int int_data_len; char *ptr; - /* The apr_base64 functions take an integer length, not a size_t. - NOTE: There's no ""loss of integer precision"" when converting - (foo & INT_MAX) to an int, this should silence the compiler - without the need for an explicit cast. */ - const int int_data_len = data_len & INT_MAX; - SERF_AUTH_assert(int_data_len == data_len); + + SERF__POSITIVE_TO_INT(int_data_len, apr_size_t, data_len); encoded_len = apr_base64_encode_len(int_data_len); scheme_len = strlen(scheme); Modified: serf/trunk/auth/auth.h URL: http://svn.apache.org/viewvc/serf/trunk/auth/auth.h?rev=1925997&r1=1925996&r2=1925997&view=diff ============================================================================== --- serf/trunk/auth/auth.h (original) +++ serf/trunk/auth/auth.h Fri May 30 22:55:53 2025 @@ -23,13 +23,6 @@ #include "auth_spnego.h" -#ifdef _DEBUG -#include <assert.h> -#define SERF_AUTH_assert(x) assert(x) -#else -#define SERF_AUTH_assert(x) ((void)0) -#endif - #ifdef __cplusplus extern "C" { #endif Modified: serf/trunk/buckets/bwtp_buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/bwtp_buckets.c?rev=1925997&r1=1925996&r2=1925997&view=diff ============================================================================== --- serf/trunk/buckets/bwtp_buckets.c (original) +++ serf/trunk/buckets/bwtp_buckets.c Fri May 30 22:55:53 2025 @@ -26,6 +26,7 @@ #include "serf.h" #include "serf_bucket_util.h" #include "serf_bucket_types.h" +#include "serf_private.h" #include <stdlib.h> @@ -384,8 +385,9 @@ static apr_status_t parse_status_line(in ctx->type = -1; } - ctx->channel = apr_strtoi64(ctx->linebuf.line + 3, &reason, 16); - + /* The channel number is positive, so use the unsigned conversion. */ + SERF__POSITIVE_TO_INT(ctx->channel, apr_int64_t, + apr_strtoi64(reason, &reason, 16)); /* Skip leading spaces for the reason string. */ if (apr_isspace(*reason)) { reason++; Modified: serf/trunk/buckets/response_buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/response_buckets.c?rev=1925997&r1=1925996&r2=1925997&view=diff ============================================================================== --- serf/trunk/buckets/response_buckets.c (original) +++ serf/trunk/buckets/response_buckets.c Fri May 30 22:55:53 2025 @@ -188,7 +188,9 @@ static apr_status_t parse_status_line(re ctx->sl.version = SERF_HTTP_VERSION(ctx->linebuf.line[5] - '0', ctx->linebuf.line[7] - '0'); - ctx->sl.code = apr_strtoi64(ctx->linebuf.line + 8, &reason, 10); + /* HTTP status codes are positive, so use the unsigned conversion. */ + SERF__POSITIVE_TO_INT(ctx->sl.code, apr_int64_t, + apr_strtoi64(ctx->linebuf.line + 8, &reason, 10)); if (errno == ERANGE || reason == ctx->linebuf.line + 8) return SERF_ERROR_BAD_HTTP_RESPONSE; Modified: serf/trunk/serf_private.h URL: http://svn.apache.org/viewvc/serf/trunk/serf_private.h?rev=1925997&r1=1925996&r2=1925997&view=diff ============================================================================== --- serf/trunk/serf_private.h (original) +++ serf/trunk/serf_private.h Fri May 30 22:55:53 2025 @@ -89,6 +89,41 @@ typedef int serf__bool_t; /* Not _Bool * #define SERF_IO_CONN (2) #define SERF_IO_LISTENER (3) +/*** Narrowing conversions ***/ + +#if defined(_DEBUG) && !defined(SERF__TEST_INTERNAL) +#include <assert.h> +#define SERF__CONV_assert(x) assert(x) +#else +#define SERF__CONV_assert(x) ((void)0) +#endif + +#include <limits.h> +/* Convert an wider value to an int. A type cast is not good enough, + because it can produce a negative value where the original was + positive. using (original_ & INT_MAX) solves that, along with + letting the compiler know that the result can be safely truncated + to a signed int, thus avoiding narrowing warnings. */ +#define SERF__POSITIVE_TO_INT(result, type, value) \ + do { \ + const type original_ = (value); \ + const int integer_ = original_ & INT_MAX; \ + SERF__CONV_assert(original_ >= 0); \ + SERF__CONV_assert(integer_ == original_); \ + (result) = integer_; \ + } while(0) + +/* For signed conversions, on the other hand, a type cast + is exactly what we need. The sign of the narrowed value + may change, but the assertion will catch that.*/ +#define SERF__SIGNED_TO_INT(result, type, value) \ + do { \ + const type original_ = (value); \ + const int integer_ = (int)original_; \ + SERF__CONV_assert(integer_ == original_); \ + (result) = integer_; \ + } while(0) + /*** Logging facilities ***/ /* Check for the SERF_DISABLE_LOGGING define, as set by scons. */ Modified: serf/trunk/test/serf_bwtp.c URL: http://svn.apache.org/viewvc/serf/trunk/test/serf_bwtp.c?rev=1925997&r1=1925996&r2=1925997&view=diff ============================================================================== --- serf/trunk/test/serf_bwtp.c (original) +++ serf/trunk/test/serf_bwtp.c Fri May 30 22:55:53 2025 @@ -517,7 +517,7 @@ int main(int argc, const char **argv) switch (opt_c) { case 'a': - srclen = strlen(opt_arg); + srclen = (int)strlen(opt_arg); enclen = apr_base64_encode_len(srclen); authn = apr_palloc(pool, enclen + 6); strcpy(authn, "Basic "); @@ -538,7 +538,7 @@ int main(int argc, const char **argv) break; case 'n': errno = 0; - app_ctx.count = apr_strtoi64(opt_arg, NULL, 10); + app_ctx.count = (int)apr_strtoi64(opt_arg, NULL, 10); if (errno) { printf("Problem converting number of times to fetch URL (%d)\n", errno); Modified: serf/trunk/test/serf_spider.c URL: http://svn.apache.org/viewvc/serf/trunk/test/serf_spider.c?rev=1925997&r1=1925996&r2=1925997&view=diff ============================================================================== --- serf/trunk/test/serf_spider.c (original) +++ serf/trunk/test/serf_spider.c Fri May 30 22:55:53 2025 @@ -448,7 +448,7 @@ static apr_status_t create_request(const return APR_SUCCESS; } -static apr_status_t put_req(const char *c, const char *orig_path, +static apr_status_t put_req(const char *found_url, const char *orig_path, parser_baton_t *ctx, apr_pool_t *pool) { apr_status_t status; @@ -456,10 +456,10 @@ static apr_status_t put_req(const char * /* Build url */ #ifdef SERF_VERBOSE - printf("Url discovered: %s\n", c); + printf("Url discovered: %s\n", found_url); #endif - status = apr_uri_parse(pool, c, &url); + status = apr_uri_parse(pool, found_url, &url); /* We got something that was minimally useful. */ if (status == 0 && url.path) { @@ -660,7 +660,7 @@ int main(int argc, const char **argv) switch (opt_c) { case 'a': - srclen = strlen(opt_arg); + srclen = (int)strlen(opt_arg); enclen = apr_base64_encode_len(srclen); authn = apr_palloc(pool, enclen + 6); strcpy(authn, "Basic "); Modified: serf/trunk/test/test_internal.c URL: http://svn.apache.org/viewvc/serf/trunk/test/test_internal.c?rev=1925997&r1=1925996&r2=1925997&view=diff ============================================================================== --- serf/trunk/test/test_internal.c (original) +++ serf/trunk/test/test_internal.c Fri May 30 22:55:53 2025 @@ -32,6 +32,7 @@ #include "test_serf.h" /* These test cases have access to internal functions. */ +#define SERF__TEST_INTERNAL /* Disable SERF__CONV_assert() */ #include "serf_private.h" #include "serf_bucket_util.h" @@ -419,6 +420,51 @@ static void test_runtime_versions(CuTest #endif } +static void test_narrowing_conversions(CuTest *tc) +{ + int val; + + SERF__POSITIVE_TO_INT(val, apr_uint64_t, 0); + CuAssertIntEquals(tc, 0, val); + SERF__SIGNED_TO_INT(val, apr_int64_t, 0); + CuAssertIntEquals(tc, 0, val); + + SERF__POSITIVE_TO_INT(val, apr_uint64_t, 1); + CuAssertIntEquals(tc, 1, val); + SERF__SIGNED_TO_INT(val, apr_int64_t, 1); + CuAssertIntEquals(tc, 1, val); + + SERF__POSITIVE_TO_INT(val, apr_uint64_t, -1); + CuAssertIntEquals(tc, INT_MAX, val); + SERF__SIGNED_TO_INT(val, apr_int64_t, -1); + CuAssertIntEquals(tc, -1, val); + + SERF__POSITIVE_TO_INT(val, apr_uint64_t, INT_MAX); + CuAssertIntEquals(tc, INT_MAX, val); + SERF__SIGNED_TO_INT(val, apr_int64_t, INT_MAX); + CuAssertIntEquals(tc, INT_MAX, val); + + SERF__POSITIVE_TO_INT(val, apr_uint64_t, INT_MIN); + CuAssertIntEquals(tc, 0, val); + SERF__SIGNED_TO_INT(val, apr_int64_t, INT_MIN); + CuAssertIntEquals(tc, INT_MIN, val); + + SERF__POSITIVE_TO_INT(val, apr_uint64_t, APR_INT64_MAX); + CuAssertIntEquals(tc, INT_MAX, val); + SERF__SIGNED_TO_INT(val, apr_int64_t, APR_INT64_MAX); + CuAssertIntEquals(tc, -1, val); + + SERF__POSITIVE_TO_INT(val, apr_uint64_t, APR_INT64_MIN); + CuAssertIntEquals(tc, 0, val); + SERF__SIGNED_TO_INT(val, apr_int64_t, APR_INT64_MIN); + CuAssertIntEquals(tc, 0, val); + + SERF__POSITIVE_TO_INT(val, apr_uint64_t, APR_UINT64_MAX); + CuAssertIntEquals(tc, INT_MAX, val); + SERF__SIGNED_TO_INT(val, apr_int64_t, APR_UINT64_MAX); + CuAssertIntEquals(tc, -1, val); +} + CuSuite *test_internal(void) { CuSuite *suite = CuSuiteNew(); @@ -432,6 +478,7 @@ CuSuite *test_internal(void) SUITE_ADD_TEST(suite, test_config_store_remove_objects); SUITE_ADD_TEST(suite, test_header_buckets_remove); SUITE_ADD_TEST(suite, test_runtime_versions); + SUITE_ADD_TEST(suite, test_narrowing_conversions); return suite; }