common: add tal_free_if_taken() helper for common case.
What changed, and why it matters
This commit is a straightforward code cleanup: it introduces a small helper function called tal_free_if_taken() and replaces many repeated two-line patterns across the codebase with calls to that helper. The behavior of the program is unchanged; no security vulnerability is introduced or fixed.
No security action required. Treat as normal refactoring/cleanup.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change adds a static inline helper in common/utils.h that performs the exact same logic previously written inline in many places: if taken(p), then tal_free(p). It then mechanically replaces occurrences of that two-line idiom in 29 files. The helper is semantically identical to the previous inline code, so there is no functional change. No bug fixes, bounds checks, or security-sensitive logic changes are present.
Changed components
common/utils.hcommon/utils.cbitcoin/script.cbitcoin/tx.ccommon/cryptomsg.ccommon/features.ccommon/json_stream.ccommon/read_peer_msg.ccommon/sphinx.cconnectd/multiplex.cdb/utils.cdevtools/gossmap-compress.cgossipd/gossipd.clightningd/channel.clightningd/channel_gossip.clightningd/jsonrpc.clightningd/peer_htlcs.clightningd/plugin.clightningd/watch.conchaind/onchaind.conchaind/test/run-grind_feerate-bug.cplugins/bkpr/test/run-recorder.cplugins/libplugin-pay.cplugins/libplugin.cplugins/renepay/routefail.cwallet/account_migration.cwallet/invoices.cwallet/wallet.cwire/wire_sync.cInspect captured patch +55 / −92
diff --git a/bitcoin/script.c b/bitcoin/script.c
index 30cc089..3b38eae 100644
--- a/bitcoin/script.c
+++ b/bitcoin/script.c
@@ -239,8 +239,7 @@ u8 *bitcoin_scriptsig_redeem(const tal_t *ctx,
script_push_bytes(&script, redeemscript,
tal_count(redeemscript));
- if (taken(redeemscript))
- tal_free(redeemscript);
+ tal_free_if_taken(redeemscript);
return script;
}
diff --git a/bitcoin/tx.c b/bitcoin/tx.c
index 0d5d6e5..fe25b10 100644
--- a/bitcoin/tx.c
+++ b/bitcoin/tx.c
@@ -359,8 +359,7 @@ void bitcoin_tx_input_set_witness(struct bitcoin_tx *tx, int innum,
wally_psbt_input_set_final_witness(&tx->psbt->inputs[innum], stack);
tal_wally_end(tx->psbt);
- if (taken(witness))
- tal_free(witness);
+ tal_free_if_taken(witness);
}
void bitcoin_tx_input_set_script(struct bitcoin_tx *tx, int innum, u8 *script)
diff --git a/common/cryptomsg.c b/common/cryptomsg.c
index 4225fef..8fb8d34 100644
--- a/common/cryptomsg.c
+++ b/common/cryptomsg.c
@@ -4,6 +4,7 @@
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
#include <ccan/mem/mem.h>
#include <common/cryptomsg.h>
+#include <common/utils.h>
#include <sodium/crypto_aead_chacha20poly1305.h>
#include <wire/wire_io.h>
@@ -232,7 +233,6 @@ u8 *cryptomsg_encrypt_msg(const tal_t *ctx,
maybe_rotate_key(&cs->sn, &cs->sk, &cs->s_ck);
- if (taken(msg))
- tal_free(msg);
+ tal_free_if_taken(msg);
return out;
}
diff --git a/common/features.c b/common/features.c
index 7573fea..94e0167 100644
--- a/common/features.c
+++ b/common/features.c
@@ -225,8 +225,7 @@ bool feature_set_or(struct feature_set *a,
for (size_t j = 0; j < tal_bytelen(b->bits[i])*8; j++) {
if (feature_is_set(b->bits[i], j)
&& feature_offered(a->bits[i], j)) {
- if (taken(b))
- tal_free(b);
+ tal_free_if_taken(b);
return false;
}
}
@@ -239,8 +238,7 @@ bool feature_set_or(struct feature_set *a,
}
}
- if (taken(b))
- tal_free(b);
+ tal_free_if_taken(b);
return true;
}
@@ -252,8 +250,7 @@ bool feature_set_sub(struct feature_set *a,
for (size_t j = 0; j < tal_bytelen(b->bits[i])*8; j++) {
if (feature_is_set(b->bits[i], j)
&& !feature_offered(a->bits[i], j)) {
- if (taken(b))
- tal_free(b);
+ tal_free_if_taken(b);
return false;
}
}
@@ -268,8 +265,7 @@ bool feature_set_sub(struct feature_set *a,
}
- if (taken(b))
- tal_free(b);
+ tal_free_if_taken(b);
return true;
}
@@ -534,8 +530,7 @@ u8 *featurebits_or(const tal_t *ctx, const u8 *f1 TAKES, const u8 *f2 TAKES)
result[l1 - l2 + i] |= f2[i];
/* Cleanup the featurebits if we were told to do so. */
- if (taken(f2))
- tal_free(f2);
+ tal_free_if_taken(f2);
return result;
}
diff --git a/common/json_stream.c b/common/json_stream.c
index b272760..6a07460 100644
--- a/common/json_stream.c
+++ b/common/json_stream.c
@@ -190,8 +190,7 @@ void json_add_primitive(struct json_stream *js,
const char *val TAKES)
{
json_add_primitive_fmt(js, fieldname, "%s", val);
- if (taken(val))
- tal_free(val);
+ tal_free_if_taken(val);
}
void json_add_string(struct json_stream *js,
@@ -200,8 +199,7 @@ void json_add_string(struct json_stream *js,
{
if (json_filter_ok(js->filter, fieldname))
json_out_addstr(js->jout, fieldname, str);
- if (taken(str))
- tal_free(str);
+ tal_free_if_taken(str);
}
static char *json_member_direct(struct json_stream *js,
@@ -304,8 +302,7 @@ void json_add_stringn(struct json_stream *result, const char *fieldname,
const char *value TAKES, size_t value_len)
{
json_add_str_fmt(result, fieldname, "%.*s", (int)value_len, value);
- if (taken(value))
- tal_free(value);
+ tal_free_if_taken(value);
}
void json_add_bool(struct json_stream *result, const char *fieldname, bool value)
@@ -345,8 +342,7 @@ void json_add_escaped_string(struct json_stream *result, const char *fieldname,
memcpy(dest + 1, esc->s, strlen(esc->s));
dest[1+strlen(esc->s)] = '"';
}
- if (taken(esc))
- tal_free(esc);
+ tal_free_if_taken(esc);
}
void json_add_timeabs(struct json_stream *result, const char *fieldname,
@@ -607,8 +603,7 @@ void json_add_psbt(struct json_stream *stream,
const char *psbt_b64;
psbt_b64 = fmt_wally_psbt(NULL, psbt);
json_add_string(stream, fieldname, take(psbt_b64));
- if (taken(psbt))
- tal_free(psbt);
+ tal_free_if_taken(psbt);
}
void json_add_amount_msat(struct json_stream *result,
diff --git a/common/read_peer_msg.c b/common/read_peer_msg.c
index 292cc6e..c83d8f1 100644
--- a/common/read_peer_msg.c
+++ b/common/read_peer_msg.c
@@ -18,8 +18,7 @@ bool handle_peer_error_or_warning(struct per_peer_state *pps,
/* Simply log incoming warnings */
err = is_peer_warning(tmpctx, msg);
if (err) {
- if (taken(msg))
- tal_free(msg);
+ tal_free_if_taken(msg);
status_info("Received %s", err);
return true;
}
diff --git a/common/sphinx.c b/common/sphinx.c
index 5cecf68..6607429 100644
--- a/common/sphinx.c
+++ b/common/sphinx.c
@@ -165,8 +165,7 @@ void sphinx_add_hop(struct sphinx_path *path, const struct pubkey *pubkey,
size_t len = tal_bytelen(payload);
towire_bigsize(&with_len, len);
towire_u8_array(&with_len, payload, len);
- if (taken(payload))
- tal_free(payload);
+ tal_free_if_taken(payload);
if (!sphinx_add_hop_has_length(path, pubkey, take(with_len)))
abort();
diff --git a/common/utils.c b/common/utils.c
index 83c8b59..102eed7 100644
--- a/common/utils.c
+++ b/common/utils.c
@@ -171,8 +171,7 @@ char *utf8_str(const tal_t *ctx, const u8 *buf TAKES, size_t buflen)
char *ret;
if (!utf8_check(buf, buflen)) {
- if (taken(buf))
- tal_free(buf);
+ tal_free_if_taken(buf);
return NULL;
}
diff --git a/common/utils.h b/common/utils.h
index a95da84..cc378e6 100644
--- a/common/utils.h
+++ b/common/utils.h
@@ -97,6 +97,13 @@ void tal_arr_remove_(void *p, size_t elemsize, size_t n);
(*(p))[n] = (v); \
} while(0)
+/* Helper to free an ptr if it's taken() */
+static inline void tal_free_if_taken(const tal_t *p)
+{
+ if (taken(p))
+ tal_free(p);
+}
+
/* Check for valid UTF-8 */
bool utf8_check(const void *buf, size_t buflen);
diff --git a/connectd/multiplex.c b/connectd/multiplex.c
index 0c5b0e4..b81c367 100644
--- a/connectd/multiplex.c
+++ b/connectd/multiplex.c
@@ -428,8 +428,7 @@ static u8 *process_batch_elements(const tal_t *ctx, struct peer *peer, const u8
} while(plen);
- if (taken(msg))
- tal_free(msg);
+ tal_free_if_taken(msg);
return ret;
}
diff --git a/db/utils.c b/db/utils.c
index 2091111..ebe7c35 100644
--- a/db/utils.c
+++ b/db/utils.c
@@ -200,8 +200,7 @@ void db_exec_prepared_v2(struct db_stmt *stmt TAKES)
db_fatal(stmt->db, "Error executing statement: %s", stmt->error);
}
- if (taken(stmt))
- tal_free(stmt);
+ tal_free_if_taken(stmt);
}
size_t db_count_changes(struct db_stmt *stmt)
@@ -221,8 +220,7 @@ u64 db_last_insert_id_v2(struct db_stmt *stmt TAKES)
assert(stmt->executed);
id = stmt->db->config->last_insert_id_fn(stmt);
- if (taken(stmt))
- tal_free(stmt);
+ tal_free_if_taken(stmt);
return id;
}
diff --git a/devtools/gossmap-compress.c b/devtools/gossmap-compress.c
index 5c0be91..662b441 100644
--- a/devtools/gossmap-compress.c
+++ b/devtools/gossmap-compress.c
@@ -304,8 +304,7 @@ static void write_msg_to_gstore(int outfd, const u8 *msg TAKES)
|| !write_all(outfd, msg, tal_bytelen(msg))) {
err(1, "Writing gossip_store");
}
- if (taken(msg))
- tal_free(msg);
+ tal_free_if_taken(msg);
}
/* BOLT #7:
diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c
index 6c0d073..a2c6fdf 100644
--- a/gossipd/gossipd.c
+++ b/gossipd/gossipd.c
@@ -103,8 +103,7 @@ void queue_peer_msg(struct daemon *daemon,
u8 *outermsg = towire_gossipd_send_gossip(NULL, peer, msg);
daemon_conn_send(daemon->connectd, take(outermsg));
- if (taken(msg))
- tal_free(msg);
+ tal_free_if_taken(msg);
}
/*~Routines to handle gossip messages from peer, forwarded by connectd.
diff --git a/lightningd/channel.c b/lightningd/channel.c
index b15fdb2..6ca82cb 100644
--- a/lightningd/channel.c
+++ b/lightningd/channel.c
@@ -1249,8 +1249,7 @@ void channel_set_billboard(struct channel *channel, bool perm, const char *str)
if (str) {
*p = tal_fmt(channel, "%s:%s", channel_state_name(channel), str);
- if (taken(str))
- tal_free(str);
+ tal_free_if_taken(str);
}
}
diff --git a/lightningd/channel_gossip.c b/lightningd/channel_gossip.c
index cb5a42d..5daa79b 100644
--- a/lightningd/channel_gossip.c
+++ b/lightningd/channel_gossip.c
@@ -378,8 +378,7 @@ static void msg_to_peer(const struct peer *peer, const u8 *msg TAKES)
msg)));
}
- if (taken(msg))
- tal_free(msg);
+ tal_free_if_taken(msg);
}
static void addgossip_reply(struct subd *gossipd,
@@ -1110,8 +1109,7 @@ void channel_gossip_update_from_gossipd(struct channel *channel,
* when we restarted; ignore, as it will catch up soon. */
case CGOSSIP_CHANNEL_ANNOUNCED_DEAD:
case CGOSSIP_CHANNEL_ANNOUNCED_DYING:
- if (taken(channel_update))
- tal_free(channel_update);
+ tal_free_if_taken(channel_update);
return;
/* This happens: we step back a block when restarting. */
diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c
index cb73246..6d9e83a 100644
--- a/lightningd/jsonrpc.c
+++ b/lightningd/jsonrpc.c
@@ -1571,8 +1571,7 @@ struct jsonrpc_request *jsonrpc_request_start_(
} else {
r->id = tal_fmt(r, "\"cln:%s#%"PRIu64"\"", method, next_request_id);
}
- if (taken(id_prefix))
- tal_free(id_prefix);
+ tal_free_if_taken(id_prefix);
next_request_id++;
r->notify_cb = notify_cb;
r->response_cb = response_cb;
diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c
index b643375..5058039 100644
--- a/lightningd/peer_htlcs.c
+++ b/lightningd/peer_htlcs.c
@@ -277,8 +277,7 @@ void local_fail_in_htlc(struct htlc_in *hin, const u8 *failmsg TAKES)
hin->shared_secret,
failmsg);
- if (taken(failmsg))
- tal_free(failmsg);
+ tal_free_if_taken(failmsg);
fail_in_htlc(hin, take(failonion));
}
@@ -994,8 +993,7 @@ static u8 *prepend_length(const tal_t *ctx, const u8 *payload TAKES)
ret = tal_arr(ctx, u8, len + tal_bytelen(payload));
memcpy(ret, buf, len);
memcpy(ret + len, payload, tal_bytelen(payload));
- if (taken(payload))
- tal_free(payload);
+ tal_free_if_taken(payload);
return ret;
}
diff --git a/lightningd/plugin.c b/lightningd/plugin.c
index 447eb59..a9098ad 100644
--- a/lightningd/plugin.c
+++ b/lightningd/plugin.c
@@ -357,8 +357,7 @@ struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES,
"Plugin changed, needs restart.");
break;
}
- if (taken(path))
- tal_free(path);
+ tal_free_if_taken(path);
return NULL;
}
}
@@ -2454,8 +2453,7 @@ bool plugin_single_notify(struct plugin *p,
} else
interested = false;
- if (taken(n))
- tal_free(n);
+ tal_free_if_taken(n);
return interested;
}
diff --git a/lightningd/watch.c b/lightningd/watch.c
index fdc57f0..e18ea8d 100644
--- a/lightningd/watch.c
+++ b/lightningd/watch.c
@@ -315,8 +315,7 @@ void txwatch_inform(const struct chain_topology *topo,
}
/* If we don't clone above, handle take() now */
- if (taken(tx))
- tal_free(tx);
+ tal_free_if_taken(tx);
}
struct scriptpubkeywatch {
diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c
index 5f2ad78..9b9beb2 100644
--- a/onchaind/onchaind.c
+++ b/onchaind/onchaind.c
@@ -215,8 +215,7 @@ static void send_coin_mvt(struct chain_coin_mvt *mvt TAKES)
wire_sync_write(REQ_FD,
take(towire_onchaind_notify_coin_mvt(NULL, mvt)));
- if (taken(mvt))
- tal_free(mvt);
+ tal_free_if_taken(mvt);
}
static void record_channel_withdrawal(const struct bitcoin_txid *tx_txid,
diff --git a/onchaind/test/run-grind_feerate-bug.c b/onchaind/test/run-grind_feerate-bug.c
index a77627b..4854902 100644
--- a/onchaind/test/run-grind_feerate-bug.c
+++ b/onchaind/test/run-grind_feerate-bug.c
@@ -229,8 +229,7 @@ u8 *wire_sync_read(const tal_t *ctx, int fd UNNEEDED)
bool wire_sync_write(int fd UNNEEDED, const void *msg TAKES)
{
- if (taken(msg))
- tal_free(msg);
+ tal_free_if_taken(msg);
return true;
}
diff --git a/plugins/bkpr/test/run-recorder.c b/plugins/bkpr/test/run-recorder.c
index db05aae..0f3f6d0 100644
--- a/plugins/bkpr/test/run-recorder.c
+++ b/plugins/bkpr/test/run-recorder.c
@@ -118,8 +118,7 @@ struct json_out *json_out_obj(const tal_t *ctx,
json_out_start(jout, NULL, '{');
if (str)
json_out_addstr(jout, fieldname, str);
- if (taken(str))
- tal_free(str);
+ tal_free_if_taken(str);
json_out_end(jout, '}');
json_out_finished(jout);
@@ -540,8 +539,7 @@ done:
assert(json_parse_input(&parser, &toks, buf, strlen(buf), &complete));
assert(complete);
- if (taken(params))
- tal_free(params);
+ tal_free_if_taken(params);
*resp = buf;
return toks;
}
diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c
index a189560..9504950 100644
--- a/plugins/libplugin-pay.c
+++ b/plugins/libplugin-pay.c
@@ -1547,8 +1547,7 @@ static u8 *patch_channel_update(const tal_t *ctx, u8 *channel_update TAKES)
fixed = tal_arr(ctx, u8, 0);
towire_u16(&fixed, WIRE_CHANNEL_UPDATE);
towire(&fixed, channel_update, tal_bytelen(channel_update));
- if (taken(channel_update))
- tal_free(channel_update);
+ tal_free_if_taken(channel_update);
return fixed;
} else {
return tal_dup_talarr(ctx, u8, channel_update);
diff --git a/plugins/libplugin.c b/plugins/libplugin.c
index 8630593..b39058d 100644
--- a/plugins/libplugin.c
+++ b/plugins/libplugin.c
@@ -543,8 +543,7 @@ struct json_out *json_out_obj(const tal_t *ctx,
json_out_start(jout, NULL, '{');
if (str)
json_out_addstr(jout, fieldname, str);
- if (taken(str))
- tal_free(str);
+ tal_free_if_taken(str);
json_out_end(jout, '}');
json_out_finished(jout);
@@ -791,8 +790,7 @@ static const jsmntok_t *sync_req(const tal_t *ctx,
json_out_start(jout, "params", '{');
json_out_end(jout, '}');
}
- if (taken(params))
- tal_free(params);
+ tal_free_if_taken(params);
/* If we're past init, we may need a new fd (the old one
* is being used for async comms). */
diff --git a/plugins/renepay/routefail.c b/plugins/renepay/routefail.c
index 4f450c6..a6df2c2 100644
--- a/plugins/renepay/routefail.c
+++ b/plugins/renepay/routefail.c
@@ -73,8 +73,7 @@ static u8 *patch_channel_update(const tal_t *ctx, u8 *channel_update TAKES)
fixed = tal_arr(ctx, u8, 0);
towire_u16(&fixed, WIRE_CHANNEL_UPDATE);
towire(&fixed, channel_update, tal_bytelen(channel_update));
- if (taken(channel_update))
- tal_free(channel_update);
+ tal_free_if_taken(channel_update);
return fixed;
} else {
return tal_dup_talarr(ctx, u8, channel_update);
diff --git a/wallet/account_migration.c b/wallet/account_migration.c
index 812b4d6..f913c14 100644
--- a/wallet/account_migration.c
+++ b/wallet/account_migration.c
@@ -184,8 +184,7 @@ static struct chain_event **find_chain_events(const tal_t *ctx,
tal_arr_expand(&results, e);
}
- if (taken(stmt))
- tal_free(stmt);
+ tal_free_if_taken(stmt);
return results;
}
diff --git a/wallet/invoices.c b/wallet/invoices.c
index 085618c..3da3904 100644
--- a/wallet/invoices.c
+++ b/wallet/invoices.c
@@ -278,10 +278,8 @@ bool invoices_create(struct invoices *invoices,
u64 now = clock_time().ts.tv_sec;
if (invoices_find_by_label(invoices, inv_dbid, label)) {
- if (taken(msat))
- tal_free(msat);
- if (taken(label))
- tal_free(label);
+ tal_free_if_taken(msat);
+ tal_free_if_taken(label);
return false;
}
@@ -335,10 +333,8 @@ bool invoices_create(struct invoices *invoices,
install_expiration_timer(invoices);
}
- if (taken(msat))
- tal_free(msat);
- if (taken(label))
- tal_free(label);
+ tal_free_if_taken(msat);
+ tal_free_if_taken(label);
return true;
}
diff --git a/wallet/wallet.c b/wallet/wallet.c
index d2a3e21..bfdf31e 100644
--- a/wallet/wallet.c
+++ b/wallet/wallet.c
@@ -6922,8 +6922,7 @@ static u64 insert_channel_mvt(struct lightningd *ld,
db_exec_prepared_v2(take(stmt));
notify_channel_mvt(ld, chan_mvt, id);
- if (taken(chan_mvt))
- tal_free(chan_mvt);
+ tal_free_if_taken(chan_mvt);
return id;
}
@@ -7115,8 +7114,7 @@ void wallet_save_chain_mvt(struct lightningd *ld,
id = insert_chain_mvt(ld, ld->wallet->db, chain_mvt);
notify_chain_mvt(ld, chain_mvt, id);
out:
- if (taken(chain_mvt))
- tal_free(chain_mvt);
+ tal_free_if_taken(chain_mvt);
}
static void db_cols_account(struct db_stmt *stmt,
diff --git a/wire/wire_sync.c b/wire/wire_sync.c
index ce2107b..9545151 100644
--- a/wire/wire_sync.c
+++ b/wire/wire_sync.c
@@ -1,6 +1,7 @@
#include "config.h"
#include <assert.h>
#include <ccan/read_write_all/read_write_all.h>
+#include <common/utils.h>
#include <errno.h>
#include <wire/wire_io.h>
#include <wire/wire_sync.h>
@@ -14,8 +15,7 @@ bool wire_sync_write(int fd, const void *msg TAKES)
ret = write_all(fd, &hdr, sizeof(hdr))
&& write_all(fd, msg, tal_count(msg));
- if (taken(msg))
- tal_free(msg);
+ tal_free_if_taken(msg);
return ret;
}
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.