DF-2230 / userland_unit.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | /* * DF-2230 verification rig -- USERLAND UNIT test of the SAME source file. * * This binary #includes the audited /usr/src/sys/libprop/prop_number.c * DIRECTLY, compiled in userland mode with the exact flags the stock * libprop uses (-D_LIBPROP -D_REENTRANT -I/usr/src/sys). That gives us * call access to the static parsers so we can observe, per case: * * - what _prop_number_internalize_signed() returns, * - the errno it leaves behind (the check the kernel compiles out), * - the pnv it stored. * * and run the exact dispatch block of _prop_number_internalize() * (prop_number.c lines 577-587) against the real static functions, * showing that in userland the signed parse FAILS (ERANGE) and the * unsigned fallback RUNS for decimal values in (INT64_MAX, UINT64_MAX]. * * Output lines: * DF2230|UU|in=<input>|signed_rv=<0/1>|errno=<n>|stored=<dec>|is_unsigned=<0/1> * DF2230|UD|in=<input>|dispatch=<signed|unsigned-fallback|none>|value=<dec> (0x<hex>)|is_unsigned=<0/1> */ #include <errno.h> #include <inttypes.h> #include <stdio.h> #include <string.h> /* The audited source, userland build. build.sh sha256-gates this file. */ #include "prop_number.c" static const char *df2230_vals[] = { "0", "42", "-1", "-9223372036854775808", "-9223372036854775809", "9223372036854775807", "9223372036854775808", "10000000000000000000", "18446744073709551615", "99999999999999999999", "0x7fffffffffffffff", "0x8000000000000000", "0xffffffffffffffff", "0Xffffffffffffffff", }; #define DF2230_NVALS ((int)(sizeof(df2230_vals) / sizeof(df2230_vals[0]))) static void df2230_unit(const char *v) { struct _prop_object_internalize_context ctx; struct _prop_number_value pnv; int rv; memset(&ctx, 0, sizeof(ctx)); ctx.poic_cp = v; /* parser sees the digits */ ctx.poic_tagattr = NULL; ctx.poic_is_empty_element = false; memset(&pnv, 0, sizeof(pnv)); errno = -1; /* sentinel */ rv = _prop_number_internalize_signed(&ctx, &pnv); printf("DF2230|UU|in=%s|signed_rv=%d|errno=%d|stored=%lld|" "is_unsigned=%d\n", v, rv, errno, (long long)pnv.pnv_signed, (int)pnv.pnv_is_unsigned); } /* * Replicates the dispatch of _prop_number_internalize() verbatim * (prop_number.c:577-587) using the real static parsers, so we can see * which branch wins for each input. */ static void df2230_dispatch(const char *v) { struct _prop_object_internalize_context ctx; struct _prop_number_value pnv; const char *how; uint64_t val; int isu; memset(&ctx, 0, sizeof(ctx)); ctx.poic_cp = v; ctx.poic_tagattr = NULL; ctx.poic_is_empty_element = false; memset(&pnv, 0, sizeof(pnv)); how = "none"; val = 0; isu = 0; if (ctx.poic_cp[0] == '-') { if (_prop_number_internalize_signed(&ctx, &pnv) == false) how = "signed-failed-no-obj"; else how = "signed"; } else if (ctx.poic_cp[0] == '0' && ctx.poic_cp[1] == 'x') { if (_prop_number_internalize_unsigned(&ctx, &pnv) == false) how = "unsigned-failed-no-obj"; else how = "unsigned-hex"; } else { if (_prop_number_internalize_signed(&ctx, &pnv) == false && _prop_number_internalize_unsigned(&ctx, &pnv) == false) { how = "both-failed-no-obj"; } else if (!pnv.pnv_is_unsigned) { how = "signed"; } else { how = "unsigned-fallback"; } } val = pnv.pnv_unsigned; isu = (int)pnv.pnv_is_unsigned; printf("DF2230|UD|in=%s|dispatch=%s|value=%llu (0x%llx)|" "is_unsigned=%d\n", v, how, (unsigned long long)val, (unsigned long long)val, isu); } int main(void) { int i; printf("DF2230|UU|BEGIN unit matrix (userland build of " "sys/libprop/prop_number.c)\n"); for (i = 0; i < DF2230_NVALS; i++) df2230_unit(df2230_vals[i]); printf("DF2230|UU|END\n"); printf("DF2230|UD|BEGIN dispatch matrix\n"); for (i = 0; i < DF2230_NVALS; i++) df2230_dispatch(df2230_vals[i]); printf("DF2230|UD|END\n"); return (0); } |