update-mocks: make handling of mocks in nested files deterministic.
What changed, and why it matters
This commit fixes a build-tool quirk that could pick the wrong function prototype when generating test mock stubs for deeply nested source directories. The wrong prototype would produce a test stub with mismatched function parameters, which could cause test compilation to fail or tests to behave incorrectly. It is a build/test reliability fix, not a directly exploitable security vulnerability in running software.
Treat as a normal reliability/build fix. No urgent security action is required. If backporting, include it to avoid flaky or incorrect test builds in deeply nested plugin tests.
Security signals we found
Build/test tooling correctness fix
Potential wrong function prototype selection in generated mocks
Determinism issue in mock generation due to directory ordering
No runtime code path affected; only unit-test stub generation
Evidence from the diff
tools/mockup.sh generates stub implementations for mocked symbols during unit-test builds. It searches headers for a symbol’s prototype, preferring headers in the parent directory and then any /.h. For plugins/bkpr/test/run-currencyrate_str.c, the symbol jsonrpc_request_start_ exists in both lightningd/ and libplugin/. Because the test file sits three directories deep (plugins/bkpr/test), the previous search did not look at the grandparent directory (libplugin), so it could randomly pick lightningd’s prototype. The patch adds “$UPDIRNAME”/../.h to the search path so the correct, nearer libplugin prototype is found deterministically. The regenerated stub in run-currencyrate_str.c drops an erroneous UNNEEDED annotation on the void arg parameter, matching the libplugin prototype.
Changed components
tools/mockup.shplugins/bkpr/test/run-currencyrate_str.cInspect captured patch +3 / −3
diff --git a/plugins/bkpr/test/run-currencyrate_str.c b/plugins/bkpr/test/run-currencyrate_str.c
index b19a5ba3..7902d0fc 100644
--- a/plugins/bkpr/test/run-currencyrate_str.c
+++ b/plugins/bkpr/test/run-currencyrate_str.c
@@ -101,7 +101,6 @@ void command_log(struct command *cmd UNNEEDED, enum log_level level UNNEEDED,
{ fprintf(stderr, "command_log called!\n"); abort(); }
/* Generated stub for command_param_failed */
struct command_result *command_param_failed(void)
-
{ fprintf(stderr, "command_param_failed called!\n"); abort(); }
/* Generated stub for command_set_usage */
void command_set_usage(struct command *cmd UNNEEDED, const char *usage UNNEEDED)
@@ -260,7 +259,8 @@ struct out_req *jsonrpc_request_start_(struct command *cmd UNNEEDED,
const char *buf UNNEEDED,
const jsmntok_t *result UNNEEDED,
void *arg) UNNEEDED,
- void *arg UNNEEDED)
+ void *arg)
+
{ fprintf(stderr, "jsonrpc_request_start_ called!\n"); abort(); }
/* Generated stub for jsonrpc_request_sync */
const jsmntok_t *jsonrpc_request_sync(const tal_t *ctx UNNEEDED,
diff --git a/tools/mockup.sh b/tools/mockup.sh
index c98215c7..ab479922 100755
--- a/tools/mockup.sh
+++ b/tools/mockup.sh
@@ -44,7 +44,7 @@ for SYMBOL; do
# If there are multiple declarations, pick first (eg. common/memleak.h
# has notleak_ as a declaration, and then an inline).
# Also, prefer local headers over generic ones.
- WHERE=$(shopt -s nullglob; grep -nH "^[a-zA-Z0-9_ (),]* [*]*$SYMBOL(" "$UPDIRNAME"/*.h ./*/*.h | head -n1)
+ WHERE=$(shopt -s nullglob; grep -nH "^[a-zA-Z0-9_ (),]* [*]*$SYMBOL(" "$UPDIRNAME"/*.h "$UPDIRNAME"/../*.h ./*/*.h | head -n1)
if [ -z "$WHERE" ]; then
WHERE=$(shopt -s nullglob; grep -nH "^extern [a-zA-Z0-9_ (),]* [*]*$SYMBOL;" "$UPDIRNAME"/*.h ./*/*.h | head -n1)
STUB=";"
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.