From c4491e30dda12466dbdf455fa04b5e84b7b0a5c8 Mon Sep 17 00:00:00 2001 From: OpenAI Date: Wed, 17 Jun 2026 19:20:02 +0000 Subject: [PATCH] nwnss: extend audited library source coverage --- nwnss-audit.md | 12 ++-- tests/nwnss/guid/test_nwnss_guid.c | 21 ++++++ tests/nwnss/id/test_nwnss_id.c | 8 +++ tests/nwnss/parse/test_nwnss_parse.c | 77 ++++++++++++++++++++-- tests/nwnss/register/test_nwnss_register.c | 23 ++++++- tests/nwnss/utc/test_nwnss_utc.c | 7 ++ 6 files changed, 137 insertions(+), 11 deletions(-) diff --git a/nwnss-audit.md b/nwnss-audit.md index f5faa03..8e99b58 100644 --- a/nwnss-audit.md +++ b/nwnss-audit.md @@ -605,13 +605,13 @@ even if it already compiles or has indirect test coverage. | Status | Kind | Test coverage | File | Notes | |---|---:|---|---|---| -| AUDITED | ORIG wrapper | link smoke | `src/nwnss/library/guid/guid.c` | Wrapper for original sharedsrc `guid.c.h`; only procdefs include and local sharedsrc include path. Sharedsrc carries the userspace entropy/time fixes. | +| AUDITED | ORIG wrapper | nwnss.guid | `src/nwnss/library/guid/guid.c` | Wrapper for original sharedsrc `guid.c.h`; only procdefs include and local sharedsrc include path. Sharedsrc carries the userspace entropy/time fixes. | ### Sources: library/id | Status | Kind | Test coverage | File | Notes | |---|---:|---|---|---| -| AUDITED | ORIG+FIX | link smoke | `src/nwnss/library/id/id.c` | Compared with original `public_core/library/id/id.c`; ID allocation logic kept. Differences are Linux kernel include removal, include-path normalization, xStdlib include, and whitespace. | +| AUDITED | ORIG+FIX | nwnss.id | `src/nwnss/library/id/id.c` | Compared with original `public_core/library/id/id.c`; ID allocation logic kept. Differences are Linux kernel include removal, include-path normalization, xStdlib include, and whitespace. | ### Sources: library/latch @@ -625,14 +625,14 @@ even if it already compiles or has indirect test coverage. | Status | Kind | Test coverage | File | Notes | |---|---:|---|---|---| | AUDITED | ORIG wrapper | link smoke | `src/nwnss/library/misc/dbginit.c` | Wrapper for original sharedsrc `dbginit.c.h`; wrapper replaces local copy with sharedsrc include path. Shared debug-init implementation remains in `src/nwnss/sharedsrc/dbginit.c.h`. | -| AUDITED | ORIG+FIX | link smoke | `src/nwnss/library/misc/displayVersion.c` | Compared with original `public_core/library/misc/displayVersion.c`; formatting body kept. Differences are include-path/userspace pssmpk include fixes and whitespace. | +| AUDITED | ORIG+FIX | nwnss.register | `src/nwnss/library/misc/displayVersion.c` | Compared with original `public_core/library/misc/displayVersion.c`; formatting body kept. Differences are include-path/userspace pssmpk include fixes and whitespace. | | AUDITED | ORIG+FIX | link smoke | `src/nwnss/library/misc/format.c` | Compared with original `public_core/library/misc/format.c`; numeric formatting and NSS log type table kept. Differences are whitespace/indentation normalization only. | | AUDITED | ORIG+FIX/PORT | link smoke | `src/nwnss/library/misc/histogram.c` | Compared with original `public_core/library/misc/histogram.c`; core histogram math/registration kept. Console command/screen hooks are inert in userspace until the NSS console/admin layer exists; includes normalized. | | AUDITED | ORIG+FIX | link smoke | `src/nwnss/library/misc/lbVolume.c` | Compared with original `public_core/library/misc/lbVolume.c`; differences are whitespace/diff-check cleanup only. | | AUDITED | GENERATED ORIG | generated nssErrorTable build | `src/nwnss/library/misc/nssErrorTable.c` | No longer kept as a tracked source blob. CMake now generates this file in the build tree with the original imported `buildErrorTranslation.prl` from `include/nwnss/public/zError.h`, matching the original `Makefile.nssErrorTable` model. | | AUDITED | PORT | nwnss.rand, nwnss.namespace | `src/nwnss/library/misc/rand.c` | No original provider found beyond rand.h/libNSS.imp/callers; seed-deterministic PRNG port checked in 0700/0701/0718; also provides xStdlib.h rand/random/srand/srandom/initstate/setstate wrappers; libsodium only initializes default state before explicit seeding. | | AUDITED | PORT | nwnss.rbpTree | `src/nwnss/library/misc/rbpTree.c` | No original provider found beyond rbpTree.h/libNSS.imp/callers; CLRS-style algorithmic port checked against header contract in 0703 and strengthened in 0705 with explicit red/black, parent-link, binary-search-order, black-height, and Coin3D-style insertion/deletion stress coverage. Coin3D rbptree.cpp was checked only as an external BSD-licensed CLRS comparison and was not imported. | -| AUDITED | ORIG+FIX/PORT | link smoke | `src/nwnss/library/misc/register.c` | Compared with original `public_core/library/misc/register.c`; registration flow kept. Differences are include-path fixes, userspace no-op for kernel/private allocator free-list check, and `LB_strmcpy` mapping. | +| AUDITED | ORIG+FIX/PORT | nwnss.register | `src/nwnss/library/misc/register.c` | Compared with original `public_core/library/misc/register.c`; registration flow kept. Differences are include-path fixes, userspace no-op for kernel/private allocator free-list check, and `LB_strmcpy` mapping. | | AUDITED | ORIG wrapper | link smoke | `src/nwnss/library/misc/sysimp.c` | Wrapper for original sharedsrc `sysimp.c.h`; include path changed to `sharedsrc/`. Userspace DDS/NDPS avoidance is in the sharedsrc compat guard. | | AUDITED | ORIG wrapper | nwnss.xml | `src/nwnss/library/misc/xmlNSS.c` | Wrapper for original sharedsrc `xmlNSS.c.h`; wrapper comment plus `sharedsrc/` include path only. XML tag/attribute/CDATA paths covered by nwnss.xml. | | AUDITED | ORIG+FIX | nwnss.xml | `src/nwnss/library/misc/xmlNSS2.c` | Compared with original `public_core/library/misc/xmlNSS2.c`; XML conversion logic kept. Differences are NSS userspace stdlib/stdio/unicode includes and whitespace cleanup. | @@ -656,7 +656,7 @@ even if it already compiles or has indirect test coverage. | Status | Kind | Test coverage | File | Notes | |---|---:|---|---|---| -| AUDITED | ORIG+FIX/PORT | link smoke | `src/nwnss/library/parse/pcmdline.c` | Compared with original `public_core/library/parse/pcmdline.c`; switch parsing/validation body kept. Differences are include-path fixes, NSS LB_* function mappings, stdarg include, and userspace console/registration dependencies; parse semantics need a later dedicated command-line test. | +| AUDITED | ORIG+FIX/PORT | nwnss.parse | `src/nwnss/library/parse/pcmdline.c` | Compared with original `public_core/library/parse/pcmdline.c`; switch parsing/validation body kept. Differences are include-path fixes, NSS LB_* function mappings, stdarg include, and userspace console/registration dependencies. Tests cover named values, boolean/no-boolean, map-upper, callbacks, clamped numeric input, and unknown-switch handling. | ### Sources: library/stdio @@ -809,7 +809,7 @@ even if it already compiles or has indirect test coverage. |---|---:|---|---|---| | AUDITED | ORIG | nwnss.stdlib | `src/nwnss/sharedsrc/atoq.c.h` | Byte-identical to original `public_core/sharedsrc/atoq.c.h`; wrapped by `library/stdlib/atoq.c` and covered by nwnss.stdlib. | | AUDITED | ORIG+FIX | link smoke | `src/nwnss/sharedsrc/dbginit.c.h` | Compared with original `public_core/sharedsrc/dbginit.c.h`; differences are whitespace/diff-check cleanup only. | -| AUDITED | ORIG+FIX/PORT | link smoke | `src/nwnss/sharedsrc/guid.c.h` | Compared with original `public_core/sharedsrc/guid.c.h`; GUID logic kept. Differences are include-path fixes plus userspace time/random/node-id fallback using libc/POSIX APIs instead of kernel/NetWare providers. | +| AUDITED | ORIG+FIX/PORT | nwnss.guid | `src/nwnss/sharedsrc/guid.c.h` | Compared with original `public_core/sharedsrc/guid.c.h`; GUID logic kept. Differences are include-path fixes plus userspace time/random/node-id fallback using libc/POSIX APIs instead of kernel/NetWare providers. | | PARTIAL | ORIG+FIX | link smoke | `src/nwnss/sharedsrc/mgmt.c.h` | NDP/MNSS visibility checked; full semantic audit needs NDP harness. | | TODO | ORIG header? | not yet classified | `src/nwnss/sharedsrc/ndp_comn.c.h` | Must be compared against original source and classified. | | TODO | ORIG header? | not yet classified | `src/nwnss/sharedsrc/ndp_guids.c.h` | Must be compared against original source and classified. | diff --git a/tests/nwnss/guid/test_nwnss_guid.c b/tests/nwnss/guid/test_nwnss_guid.c index 1caf47a..6f20660 100644 --- a/tests/nwnss/guid/test_nwnss_guid.c +++ b/tests/nwnss/guid/test_nwnss_guid.c @@ -36,10 +36,30 @@ static int check_parse_and_format(void) CHECK(LB_GUIDFromUTF8((utf8_t *)"12345678-9abc-0def-8001-020304050607", &guid) == zOK); CHECK(guid.clockSeqHighAndReserved == 0x80); CHECK(guid.clockSeqLow == 0x01); + CHECK(LB_GUIDFromUTF8((utf8_t *)"12345678-9abc-0def-80-01-02030405060", &guid) == zERR_INVALID_VOLUME_ID); + CHECK(LB_GUIDFromUTF8((utf8_t *)"12345678-9abc-0def-80-01-02030405060x", &guid) == zERR_INVALID_VOLUME_ID); CHECK(LB_GUIDFromUTF8((utf8_t *)"bad", &guid) == zERR_INVALID_VOLUME_ID); return 0; } +static int check_compare_with_block(void) +{ + GUID_t a; + GUID_t b; + + CHECK(LB_GUIDFromUTF8((utf8_t *)"12345678-9abc-0def-80-01-020304050607", &a) == zOK); + b = a; + b.node[0] ^= 0x7f; + b.node[1] ^= 0x33; + b.node[2] ^= 0x22; + b.node[3] ^= 0x11; + CHECK(LB_GUIDCompare(&a, &b) != 0); + CHECK(LB_GUIDCompareWithBlock(&a, &b) == 0); + b.node[5] ^= 0x01; + CHECK(LB_GUIDCompareWithBlock(&a, &b) != 0); + return 0; +} + static int check_generate(void) { GUID_t a; @@ -60,6 +80,7 @@ static int check_generate(void) int main(void) { CHECK(check_parse_and_format() == 0); + CHECK(check_compare_with_block() == 0); CHECK(check_generate() == 0); return 0; } diff --git a/tests/nwnss/id/test_nwnss_id.c b/tests/nwnss/id/test_nwnss_id.c index 9c43ed3..655c427 100644 --- a/tests/nwnss/id/test_nwnss_id.c +++ b/tests/nwnss/id/test_nwnss_id.c @@ -40,12 +40,20 @@ int main(void) values[2] = make_id(102); missing = make_id(77); + CHECK(initIds(MAX_IDS, keys, values) == NULL); + table = initIds(3, keys, values); CHECK(table != NULL); found = findId(table, keys[0]); CHECK(LB_GUIDCompare(&found, &values[0]) == 0); found = findId(table, keys[1]); CHECK(LB_GUIDCompare(&found, &values[1]) == 0); + /* Lookup through a collision chain should move the found entry to the + * front while preserving subsequent lookups. */ + found = findId(table, keys[1]); + CHECK(LB_GUIDCompare(&found, &values[1]) == 0); + found = findId(table, keys[2]); + CHECK(LB_GUIDCompare(&found, &values[2]) == 0); found = findId(table, missing); CHECK(LB_GUIDCompare(&found, &missing) == 0); found = findId(table, zINVALID_USERID); diff --git a/tests/nwnss/parse/test_nwnss_parse.c b/tests/nwnss/parse/test_nwnss_parse.c index b366469..4c9a38d 100644 --- a/tests/nwnss/parse/test_nwnss_parse.c +++ b/tests/nwnss/parse/test_nwnss_parse.c @@ -12,11 +12,43 @@ } \ } while (0) -int main(void) +static int pre_count; +static int process_count; +static int post_count; + +static STATUS count_pre(PCLSwitchDef_s *switchDef, NINT parseOptions, void *userParm) +{ + (void)switchDef; + (void)parseOptions; + (*(NINT *)userParm)++; + pre_count++; + return zOK; +} + +static STATUS count_process(PCLSwitchDef_s *switchDef, NINT parseOptions, void *userParm) +{ + (void)switchDef; + (void)parseOptions; + (void)userParm; + process_count++; + return zOK; +} + +static STATUS count_post(PCLSwitchDef_s *switchDef, NINT parseOptions, void *userParm) +{ + (void)switchDef; + (void)parseOptions; + (void)userParm; + post_count++; + return zOK; +} + +static int check_basic_parse(void) { char value[32] = {0}; NINT flag = -1; NINT count = 0; + NINT callback_user = 0; PCLSwitchDef_s switches[] = { { @@ -25,7 +57,7 @@ int main(void) 0, 0, NULL, value, .vtype.string = {sizeof(value), 0}, - 0, 0, StructMSGNot("name value"), NULL, NULL + 0, 0, StructMSGNot("name value"), count_pre, count_post }, { "enabled", NULL, @@ -37,20 +69,57 @@ int main(void) }, { "count", NULL, - SWTYPE_VALUE | SWVAL_NINT, + SWTYPE_VALUE | SWVAL_NINT | SWOPT_HAS_NUMERIC_RANGE, 0, 0, NULL, &count, .vtype.numeric = {0, 100}, 0, 0, StructMSGNot("count value"), NULL, NULL }, + { + "upper", NULL, + SWTYPE_VALUE | SWVAL_CHAR | SWOPT_MAPUPPER, + 0, 0, count_process, + value, + .vtype.string = {sizeof(value), 0}, + 0, 0, StructMSGNot("upper value"), NULL, NULL + }, {PCMDLINE_ENDOFLIST} }; CHECK(LB_ParseCmdline(switches, POPT_AT_RUNTIME, - "/name=demo /enabled /count=42", NULL) == zOK); + "/name=demo /enabled /count=42", &callback_user) == zOK); CHECK(strcmp(value, "demo") == 0); CHECK(flag == TRUE); CHECK(count == 42); + CHECK(pre_count == 1); + CHECK(post_count == 1); + CHECK(callback_user == 1); + + CHECK(LB_ParseCmdline(switches, POPT_AT_RUNTIME, + "/upper=mars-nwe", &callback_user) == zOK); + CHECK(strcmp(value, "MARS-NWE") == 0); + CHECK(process_count == 1); + + CHECK(LB_ParseCmdline(switches, POPT_AT_RUNTIME, + "/noenabled", &callback_user) == zOK); + CHECK(flag == FALSE); + + /* The original parser accepts out-of-range numeric values unless a broader + * set-parameter validation backend is active. Keep the userspace audit + * focused on tokenization, callbacks and switch dispatch. */ + CHECK(LB_ParseCmdline(switches, POPT_AT_RUNTIME, + "/count=101", &callback_user) == zOK); + CHECK(count == 100); + CHECK(LB_ParseCmdline(switches, POPT_AT_RUNTIME, + "/unknown=1", &callback_user) == zFAILURE); + CHECK(LB_ParseCmdline(switches, POPT_AT_RUNTIME | POPT_NO_UNKNOWN_SWITCH_ERRORS, + "/unknown=1", &callback_user) == zOK); return 0; } + +int main(void) +{ + CHECK(check_basic_parse() == 0); + return 0; +} diff --git a/tests/nwnss/register/test_nwnss_register.c b/tests/nwnss/register/test_nwnss_register.c index f982a91..4800b67 100644 --- a/tests/nwnss/register/test_nwnss_register.c +++ b/tests/nwnss/register/test_nwnss_register.c @@ -4,13 +4,34 @@ #include #include +static int check_version_string(NINT major, NINT minor, NINT sub, const char *expected) +{ + VersionInformation_s vi = {major, minor, sub, 0, VERINFO_NO_PATENT}; + char version[16]; + + return strcmp(FormatVersionString(&vi, version), expected) == 0; +} + int main(void) { VersionInformation_s vi = {1, 26, 2, 0, VERINFO_NO_PATENT}; char version[16]; - if (strcmp(FormatVersionString(&vi, version), "1.26b") != 0) + if (!check_version_string(1, 26, 2, "1.26b")) return 1; + if (!check_version_string(2, 3, 0, "2.03")) + return 11; + if (!check_version_string(2, 3, 1, "2.03a")) + return 12; + if (!check_version_string(2, 3, 26, "2.03z")) + return 13; + if (!check_version_string(2, 3, 99, "2.03z")) + return 14; + if (!check_version_string(2, 3, -7, "2.03a")) + return 15; + + if (strcmp(FormatVersionString(&vi, version), "1.26b") != 0) + return 16; if (COMN_RegisterLibraryOwner("nwnss", &vi) != zOK) return 2; diff --git a/tests/nwnss/utc/test_nwnss_utc.c b/tests/nwnss/utc/test_nwnss_utc.c index 8c3e6b7..455b923 100644 --- a/tests/nwnss/utc/test_nwnss_utc.c +++ b/tests/nwnss/utc/test_nwnss_utc.c @@ -44,5 +44,12 @@ int main(void) CHECK(Str2utcTime("02-Jan-2001_03:04:06") == utc); CHECK(Str2dosDateTime("02-Jan-2001_03:04:06") == dos); + CHECK(strcmp(UTCTime2Str(utc, universal), "02-Jan-2001 03:04:06") == 0); + + CHECK(UniversalStr2utcTime("19991231235958") != INVALID_UTC_TIME); + CHECK(UniversalStr2utcTime("19991301000000") == INVALID_UTC_TIME); + CHECK(UniversalStr2utcTime("19991232000000") == INVALID_UTC_TIME); + CHECK(Str2utcTime("31-Dec-1999_23:59:58") != INVALID_UTC_TIME); + CHECK(Str2utcTime("31-Foo-1999_23:59:58") == INVALID_UTC_TIME); return 0; }