Commit graph

2 commits

Author SHA1 Message Date
Stephen Dennis
8808b4c375 feat(#2136): flip fargs to const UTF8 * const — and convert every site the compiler surfaced
The flip: FUNCTION/XFUNCTION/FUN::fun/delim_check and the module
interfaces take `const UTF8 * const fargs[]`.  Double-const is
load-bearing: C++ qualification conversion needs const at both pointer
levels, so builder-side `UTF8 *[]` arrays convert implicitly — the
evaluator, the JIT marshaller, and every owner site need zero casts,
and slot reassignment inside bodies becomes a compile error for free.

The conversions: the flip landed first so the compiler enumerated every
violation; this commit is that inventory worked to zero — ~250 sites
across funceval, funceval2, functions, funmath, help, mail, session,
powers, levels, predicates, conf, walkdb, stringutil, timeutil/
date_scan (regenerated, one-line diff), exp3, and mux_main, each
classified per docs/campaign-2136-const-fargs.md's four recipes.

New idioms (functions.h): trim_space_sep_n() — non-destructive trim for
(pointer, length) consumers, so trim-then-scan sites need no copy at
all; FargVec — the argv counterpart of FargCopy for CS_ARGV handlers.
countwords() and DecodeListOfIntegers() rewritten non-destructive.

The flip deleted more than it added: #2157's fun_munge list1 copy, the
engine_com help-topic copy, fun_index's in-place NUL write, and five
const_casts (process_sex x4, sha1_helper).  const_cast budget: zero
added.

Trap recorded in the brief: an old-signature definition doesn't fail
the build — it becomes a C++ overload, and the new-signature symbol
stays undefined until dlopen(RTLD_NOW).  delim_check, the conn_bridge
bridges, the dbt_spike stub, and exp3::Call were all silently shadowed;
muxscript was the only host that noticed, because netmux's own net.cpp
resolved the flat-namespace lookup.  After any signature flip, grep the
old spelling.

Verified: make test EXPECT_CONFIG="jit=yes" (35 passed / 0 failed) and
make test-scenario, including the new tests/scenario/sidefx_fargs.py
that live-probes the class-3 wrappers smoke never touches (pemit/
trigger/link/tel/wipe/destroy).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 14:34:23 -06:00
Stephen Dennis
957caeb1b0 harden(digest): back mux_sha1_digest with Windows CNG, retire homegrown SHA-1 (#1963)
The non-OpenSSL digest backend is now CNG (BCrypt) with cached
algorithm-provider handles; the FIPS-180 MUX_SHA1_* implementation is
deleted and the tree ships no cryptographic source, matching the
Schannel-for-TLS precedent.  A new generalized mux_digest(name, ...)
entry point serves sha1/sha256/sha384/sha512/md5 (case-insensitive,
hyphenated aliases), and fun_digest's non-OpenSSL branch dispatches
through it, so digest(sha256,...) et al. now work on Windows --
digest_fn.mux TC004/TC005 flip from Skipped to Succeeded there via
their existing behavior-probing guards.

Output is byte-identical across the swap: tests/digest (new, wired as
make test-digest and into test-asan) pins the surfaces whose bytes may
never change -- RFC 6455 Sec-WebSocket-Accept (single-part and the
two-part gather websocket.cpp performs), the $SHA1$ salt||password
gather and bare-password $P6H$ shapes from player.cpp, and the sha1()
softcode FIPS vectors -- with every golden value generated by the
openssl(1) CLI as an external oracle.  Verified on Windows: homegrown
== oracle == CNG on all six SHA-1 vectors, 17/17 KATs against the CNG
build, full solution build with zero new warnings, smoke ALL 1601
PASSED / 0 failed.

A non-Windows non-OpenSSL platform now hits #error by design:
configure.ac hard-errors without OpenSSL, so no shipped config lands
there, and the homegrown fallback must not silently return.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 14:01:56 -06:00