Fix mass re-orphaning of cap-gains splits during lot scrub

xaccSplitComputeCapGains() performs a marker->source switch-over when a
gains marker split is processed before its source. The switch-over did
not resolve the source's in-memory gain status, so the source was left
with gains==UNKNOWN and gains_split==nullptr even though its forward
gains-split KVP was intact. The subsequent lookup read nullptr and the
code created a brand-new gains transaction routed to Orphaned Gains,
duplicating hundreds of already-settled gains splits on SQL books whose
history contains a stock split.

Resolve the source's gain status immediately after the switch-over so
its existing gains split is reused instead of being re-created.

This latent bug (original cap-gains code, ~2003) was exposed by the
5.17 adjusted_amount work (1e654412ab, b1efe0763c) which recomputes
already-booked gains in stock-split accounts. It is order-sensitive,
which is why it reproduces on MySQL but not SQLite.
This commit is contained in:
Brent McBride committed 2026-10-02 00:30:39 -07:00
1 parent 9414fdf546
commit 872612a26b
1 file changed
+6
+6
View File
@@ -609,6 +609,12 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
#endif
}
split = s;
/* The source reached by switch-over may not have resolved its own
* gain status yet (e.g. the marker was scrubbed before its source);
* resolve it now so its existing gains split is reused instead of
* being re-created and orphaned. */
if (GAINS_STATUS_UNKNOWN == split->gains)
xaccSplitDetermineGainStatus (split);
}
/* Note: if the value of the 'opening' split(s) has changed,