~donmcc/ood

52c85fbe6b902c0b658b9e22359fb5c617173cfe — Don McCaughey 10 months ago 3e6ca8c
Handle NULL values without segfaulting.

Test pointer arguments and return appropriate failure values.
2 files changed, 119 insertions(+), 4 deletions(-)

M src/sa/sa.c
M src/sa/sa_tests.c
M src/sa/sa.c => src/sa/sa.c +20 -4
@@ 33,6 33,8 @@ sa_alloc_from_in6_addr_and_port(struct in6_addr in6_addr, in_port_t port)
union sa_address *
sa_alloc_from_ipv4_str_and_port(char const *ipv4_str, in_port_t port)
{
    if (!ipv4_str) return NULL;

    in_addr_t in_addr;
    int result = inet_pton(AF_INET, ipv4_str, &in_addr);
    if (1 != result) return NULL;


@@ 44,6 46,8 @@ sa_alloc_from_ipv4_str_and_port(char const *ipv4_str, in_port_t port)
union sa_address *
sa_alloc_from_ipv6_str_and_port(char const *ipv6_str, in_port_t port)
{
    if (!ipv6_str) return NULL;

    struct in6_addr in6_addr;
    int result = inet_pton(AF_INET6, ipv6_str, &in6_addr);
    if (1 != result) return NULL;


@@ 59,7 63,7 @@ sa_alloc_from_path(char const *path)
    if (strlen(path) >= UNIX_PATH_MAX) return NULL;

    struct sockaddr_un local_address = {
            .sun_family = AF_UNIX,
            .sun_family=AF_UNIX,
    };
    strcpy(local_address.sun_path, path);
    return sa_alloc_from_sockaddr_un(&local_address);


@@ 69,6 73,8 @@ sa_alloc_from_path(char const *path)
union sa_address *
sa_alloc_from_sockaddr(struct sockaddr const *generic_address)
{
    if (!generic_address) return NULL;

    switch (generic_address->sa_family) {
        case AF_UNIX: return sa_alloc_from_sockaddr_un((struct sockaddr_un const *)generic_address);
        case AF_INET: return sa_alloc_from_sockaddr_in((struct sockaddr_in const *)generic_address);


@@ 81,8 87,10 @@ sa_alloc_from_sockaddr(struct sockaddr const *generic_address)
union sa_address *
sa_alloc_from_sockaddr_in(struct sockaddr_in const *ipv4_address)
{
    if (!ipv4_address) return NULL;

    union sa_address *address = calloc(1, sizeof(union sa_address));
    if (!address) goto fail;
    if (!address) return NULL;

    address->ipv4 = *ipv4_address;
    const char *wrote_address = inet_ntop(AF_INET, &ipv4_address->sin_addr,


@@ 90,7 98,7 @@ sa_alloc_from_sockaddr_in(struct sockaddr_in const *ipv4_address)
    if (!wrote_address) goto fail;

    char *s = address->ipv4_str + strlen(address->ipv4_str);
    int wrote_port = sprintf(s, ":%i",ntohs(ipv4_address->sin_port));
    int wrote_port = sprintf(s, ":%i", ntohs(ipv4_address->sin_port));
    if (wrote_port < 0) goto fail;

    return address;


@@ 105,8 113,10 @@ sa_alloc_from_sockaddr_in(struct sockaddr_in const *ipv4_address)
union sa_address *
sa_alloc_from_sockaddr_in6(struct sockaddr_in6 const *ipv6_address)
{
    if (!ipv6_address) return NULL;

    union sa_address *address = calloc(1, sizeof(union sa_address));
    if (!address) goto fail;
    if (!address) return NULL;

    address->ipv6 = *ipv6_address;



@@ 129,6 139,8 @@ sa_alloc_from_sockaddr_in6(struct sockaddr_in6 const *ipv6_address)
union sa_address *
sa_alloc_from_sockaddr_un(struct sockaddr_un const *local_address)
{
    if (!local_address) return NULL;

    union sa_address *address = calloc(1, sizeof(union sa_address));
    if (!address) return NULL;



@@ 141,6 153,8 @@ sa_alloc_from_sockaddr_un(struct sockaddr_un const *local_address)
socklen_t
sa_len(union sa_address const *address)
{
    if (!address) return 0;

    switch (address->generic.sa_family) {
        case AF_UNSPEC: return sizeof(struct sockaddr_storage);
        case AF_UNIX: return sizeof(struct sockaddr_un);


@@ 154,6 168,8 @@ sa_len(union sa_address const *address)
char const *
sa_str(union sa_address const *address)
{
    if (!address) return "(null)";

    switch (address->generic.sa_family) {
        case AF_UNSPEC: return "(unspecified)";
        case AF_UNIX: return address->local.sun_path;

M src/sa/sa_tests.c => src/sa/sa_tests.c +99 -0
@@ 66,6 66,24 @@ test_sa_alloc_from_ipv4_str_and_port(void)


static void
test_sa_alloc_from_ipv4_str_and_port_when_null(void)
{
    union sa_address *address = sa_alloc_from_ipv4_str_and_port(NULL, 8080);

    assert(!address);
}


static void
test_sa_alloc_from_ipv4_str_and_port_when_invalid(void)
{
    union sa_address *address = sa_alloc_from_ipv4_str_and_port("invalid", 8080);

    assert(!address);
}


static void
test_sa_alloc_from_ipv6_str_and_port(void)
{
    union sa_address *address = sa_alloc_from_ipv6_str_and_port("::1", 8080);


@@ 85,6 103,24 @@ test_sa_alloc_from_ipv6_str_and_port(void)


static void
test_sa_alloc_from_ipv6_str_and_port_when_null(void)
{
    union sa_address *address = sa_alloc_from_ipv6_str_and_port(NULL, 8080);

    assert(!address);
}


static void
test_sa_alloc_from_ipv6_str_and_port_when_invalid(void)
{
    union sa_address *address = sa_alloc_from_ipv6_str_and_port("invalid", 8080);

    assert(!address);
}


static void
test_sa_alloc_from_path(void)
{
    union sa_address *address = sa_alloc_from_path("/var/dood/http");


@@ 228,6 264,15 @@ test_sa_alloc_from_sockaddr_for_unsupported(void)


static void
test_sa_alloc_from_sockaddr_when_null(void)
{
    union sa_address *address = sa_alloc_from_sockaddr(NULL);

    assert(!address);
}


static void
test_sa_alloc_from_sockaddr_in(void)
{
    struct sockaddr_in ipv4 = {


@@ 255,6 300,15 @@ test_sa_alloc_from_sockaddr_in(void)


static void
test_sa_alloc_from_sockaddr_in_when_null(void)
{
    union sa_address *address = sa_alloc_from_sockaddr_in(NULL);

    assert(!address);
}


static void
test_sa_alloc_from_sockaddr_in6(void)
{
    struct sockaddr_in6 ipv6 = {


@@ 280,6 334,15 @@ test_sa_alloc_from_sockaddr_in6(void)


static void
test_sa_alloc_from_sockaddr_in6_when_null(void)
{
    union sa_address *address = sa_alloc_from_sockaddr_in6(NULL);

    assert(!address);
}


static void
test_sa_alloc_from_sockaddr_un(void)
{
    struct sockaddr_un local = {


@@ 303,6 366,15 @@ test_sa_alloc_from_sockaddr_un(void)


static void
test_sa_alloc_from_sockaddr_un_when_null(void)
{
    union sa_address *address = sa_alloc_from_sockaddr_un(NULL);

    assert(!address);
}


static void
test_sa_len_for_unspecified(void)
{
    union sa_address address = {


@@ 362,6 434,13 @@ test_sa_len_for_unsupported(void)


static void
test_sa_len_for_null(void)
{
    assert(0 == sa_len(NULL));
}


static void
test_sa_str_for_unspecified(void)
{
    union sa_address address = {


@@ 387,13 466,27 @@ test_sa_str_for_unsupported(void)
}


static void
test_sa_str_for_null(void)
{
    assert(STR_EQ("(null)", sa_str(NULL)));
}


int
main(int argc, char *argv[])
{
    test_sa_alloc_from_in_addr_and_port();
    test_sa_alloc_from_in6_addr_and_port();

    test_sa_alloc_from_ipv4_str_and_port();
    test_sa_alloc_from_ipv4_str_and_port_when_null();
    test_sa_alloc_from_ipv4_str_and_port_when_invalid();

    test_sa_alloc_from_ipv6_str_and_port();
    test_sa_alloc_from_ipv6_str_and_port_when_null();
    test_sa_alloc_from_ipv6_str_and_port_when_invalid();

    test_sa_alloc_from_path();
    test_sa_alloc_from_path_when_null();
    test_sa_alloc_from_path_when_too_long();


@@ 403,17 496,23 @@ main(int argc, char *argv[])
    test_sa_alloc_from_sockaddr_for_ipv6();
    test_sa_alloc_from_sockaddr_for_local();
    test_sa_alloc_from_sockaddr_for_unsupported();
    test_sa_alloc_from_sockaddr_when_null();

    test_sa_alloc_from_sockaddr_in();
    test_sa_alloc_from_sockaddr_in_when_null();
    test_sa_alloc_from_sockaddr_in6();
    test_sa_alloc_from_sockaddr_in6_when_null();
    test_sa_alloc_from_sockaddr_un();
    test_sa_alloc_from_sockaddr_un_when_null();

    test_sa_len_for_unspecified();
    test_sa_len_for_ipv4();
    test_sa_len_for_ipv6();
    test_sa_len_for_local();
    test_sa_len_for_unsupported();
    test_sa_len_for_null();

    test_sa_str_for_unspecified();
    test_sa_str_for_unsupported();
    test_sa_str_for_null();
}