tests: add port group for wc_port.c MC/DC

Covers the argument guards of wc_FileLoad, wc_ReadDirFirst/Next,
wc_strtok, wc_strsep, wc_strlcpy's truncation arm and wolfSSL_NewThread.
wc_port.c had no test group of its own.

Builds clean under --enable-all, default and --enable-singlethreaded.
pull/11039/head
Daniele Lacamera 2026-08-03 10:34:09 +02:00
parent e260a8e103
commit 28f4440dd0
5 changed files with 213 additions and 0 deletions

View File

@ -4406,6 +4406,7 @@ if(WOLFSSL_EXAMPLES)
tests/api/test_random.c
tests/api/test_wolfentropy.c
tests/api/test_wolfevent.c
tests/api/test_port.c
tests/api/test_wolfmath.c
tests/api/test_rsa.c
tests/api/test_dsa.c

View File

@ -237,6 +237,7 @@
#include <tests/api/test_random.h>
#include <tests/api/test_wolfentropy.h>
#include <tests/api/test_wolfevent.h>
#include <tests/api/test_port.h>
#include <tests/api/test_wolfmath.h>
#include <tests/api/test_rsa.h>
#include <tests/api/test_dsa.h>
@ -38681,6 +38682,7 @@ TEST_CASE testCases[] = {
TEST_RANDOM_DECLS,
TEST_WOLFENTROPY_DECLS,
TEST_WOLFEVENT_DECLS,
TEST_PORT_DECLS,
/* Public key */
/* wolfmath MP API tests */

View File

@ -44,6 +44,7 @@ tests_unit_test_SOURCES += tests/api/test_error.c
tests_unit_test_SOURCES += tests/api/test_random.c
tests_unit_test_SOURCES += tests/api/test_wolfentropy.c
tests_unit_test_SOURCES += tests/api/test_wolfevent.c
tests_unit_test_SOURCES += tests/api/test_port.c
# MP
tests_unit_test_SOURCES += tests/api/test_wolfmath.c
# Public Key Algorithm
@ -177,6 +178,7 @@ EXTRA_DIST += tests/api/test_error.h
EXTRA_DIST += tests/api/test_random.h
EXTRA_DIST += tests/api/test_wolfentropy.h
EXTRA_DIST += tests/api/test_wolfevent.h
EXTRA_DIST += tests/api/test_port.h
EXTRA_DIST += tests/api/test_wolfmath.h
EXTRA_DIST += tests/api/test_rsa.h
EXTRA_DIST += tests/api/test_dsa.h

View File

@ -0,0 +1,176 @@
/* test_port.c
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <tests/unit.h>
#include <wolfssl/wolfcrypt/wc_port.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <tests/api/api.h>
#include <tests/api/test_port.h>
/*
* MC/DC decision coverage for the portability layer (wolfcrypt/src/wc_port.c):
* the file/directory helpers and the wolfCrypt string helpers, whose argument
* guards are multi-operand ORs that no other module's tests reach.
*
* Residuals left uncovered on purpose: wc_open_cloexec / wc_accept_cloexec's
* "fd < 0 && errno == EINVAL" and "errno != ENOSYS && errno != EINVAL" arms are
* the fallback for kernels without O_CLOEXEC / SOCK_CLOEXEC, unreachable on any
* host the campaign runs on.
*/
#ifndef SINGLE_THREADED
static THREAD_RETURN WOLFSSL_THREAD test_port_thread_cb(void* arg)
{
(void)arg;
WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif
int test_wc_PortDecisionCoverage(void)
{
EXPECT_DECLS;
#ifndef NO_FILESYSTEM
{
unsigned char* fbuf = NULL;
size_t fbufLen = 0;
/* wc_FileLoad: "fname == NULL || buf == NULL || bufLen == NULL",
* one operand true per call so each independence pair is shown. */
ExpectIntEQ(wc_FileLoad(NULL, &fbuf, &fbufLen, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_FileLoad("./certs/server-cert.pem", NULL, &fbufLen, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_FileLoad("./certs/server-cert.pem", &fbuf, NULL, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* all three operands false: the guard is passed and the call is
* decided by the filesystem, not by the argument check. */
ExpectIntNE(wc_FileLoad("./certs/no-such-file.der", &fbuf, &fbufLen,
NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
if (fbuf != NULL) {
XFREE(fbuf, NULL, DYNAMIC_TYPE_FILE);
fbuf = NULL;
}
}
#endif /* !NO_FILESYSTEM */
#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
{
ReadDirCtx dirCtx;
char* dirName = NULL;
XMEMSET(&dirCtx, 0, sizeof(dirCtx));
/* wc_ReadDirFirst / wc_ReadDirNext: "ctx == NULL || path == NULL",
* each operand flipped independently. */
ExpectIntEQ(wc_ReadDirFirst(NULL, "./certs", &dirName),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_ReadDirFirst(&dirCtx, NULL, &dirName),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_ReadDirNext(NULL, "./certs", &dirName),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_ReadDirNext(&dirCtx, NULL, &dirName),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* both operands false on a directory that always exists in-tree. */
if (wc_ReadDirFirst(&dirCtx, "./certs", &dirName) == 0) {
(void)wc_ReadDirNext(&dirCtx, "./certs", &dirName);
wc_ReadDirClose(&dirCtx);
}
}
#endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
#ifdef USE_WOLF_STRTOK
{
char tokBuf[] = "a,b";
char* tokNext = NULL;
/* "str == NULL && nextp": nextp NULL is the operand's false half, and
* the same call then takes "str == NULL || *str == '\0'" true on its
* first operand. */
ExpectNull(wc_strtok(NULL, ",", NULL));
/* str non-NULL: first operand false, and the second guard decided by
* *str instead. */
ExpectNotNull(wc_strtok(tokBuf, ",", &tokNext));
}
#endif /* USE_WOLF_STRTOK */
#ifdef USE_WOLF_STRSEP
{
char sepBuf[] = "a,b";
char* sepp = sepBuf;
char* sepNull = NULL;
/* "stringp == NULL || *stringp == NULL", one operand true per call. */
ExpectNull(wc_strsep(NULL, ","));
ExpectNull(wc_strsep(&sepNull, ","));
/* both false */
ExpectNotNull(wc_strsep(&sepp, ","));
}
#endif /* USE_WOLF_STRSEP */
#ifndef SINGLE_THREADED
{
THREAD_TYPE portThread;
XMEMSET(&portThread, 0, sizeof(portThread));
/* wolfSSL_NewThread: "thread == NULL || cb == NULL", each operand
* flipped independently, then both false on a thread that is created
* and joined. */
ExpectIntEQ(wolfSSL_NewThread(NULL, test_port_thread_cb, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_NewThread(&portThread, NULL, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
if (EXPECT_SUCCESS()) {
int thrRet = wolfSSL_NewThread(&portThread, test_port_thread_cb,
NULL);
ExpectIntEQ(thrRet, 0);
if (thrRet == 0) {
ExpectIntEQ(wolfSSL_JoinThread(portThread), 0);
}
}
}
#endif /* !SINGLE_THREADED */
#ifdef USE_WOLF_STRLCPY
{
char lcpyDst[4];
/* "i < (dstSize - 1) && *src != '\0'": a source longer than the
* destination ends the loop on the size operand rather than on the
* terminator, which is that operand's uncovered half. */
XMEMSET(lcpyDst, 0, sizeof(lcpyDst));
ExpectIntEQ((int)wc_strlcpy(lcpyDst, "abcdef", 3), 2);
ExpectIntEQ(XSTRNCMP(lcpyDst, "ab", 3), 0);
/* short source: the loop ends on the terminator instead. */
XMEMSET(lcpyDst, 0, sizeof(lcpyDst));
ExpectIntEQ((int)wc_strlcpy(lcpyDst, "a", sizeof(lcpyDst)), 1);
}
#endif /* USE_WOLF_STRLCPY */
return EXPECT_RESULT();
}

View File

@ -0,0 +1,32 @@
/* test_port.h
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef WOLFCRYPT_TEST_PORT_H
#define WOLFCRYPT_TEST_PORT_H
#include <tests/api/api_decl.h>
int test_wc_PortDecisionCoverage(void);
#define TEST_PORT_DECLS \
TEST_DECL_GROUP("port", test_wc_PortDecisionCoverage)
#endif /* WOLFCRYPT_TEST_PORT_H */