summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKunht Kun <kunhtkun@gmail.com>2022-03-17 01:09:33 -0400
committerJohn Wiegley <johnw@newartisans.com>2022-03-17 11:22:13 -0700
commitf3fd025a35b7328f66e21db1eccfe774cae4cf70 (patch)
tree94cb564475fd02c3d084031d9a7a7779a5ab96c8
parent733bf432135388d8523b90b8f2bdcf4a94688c07 (diff)
downloadfork-ledger-f3fd025a35b7328f66e21db1eccfe774cae4cf70.tar.gz
fork-ledger-f3fd025a35b7328f66e21db1eccfe774cae4cf70.tar.bz2
fork-ledger-f3fd025a35b7328f66e21db1eccfe774cae4cf70.zip
Avoid making references to null
In `compare_items` if `sort_order` is a top level expression, it has no context and `get_context()` method returns the null pointer. To see this, run $ ledger -f test/input/demo.ledger --sort display_amount reg --debug scope.symbols and there will be many lines like [DEBUG] Binding scope 0 with ... In such case making a reference to the context is an undefined behavior (honestly the dereferencing itself feels quite problematic, but many compilers just run without any complaints) and could potentially cause segfaults. Therefore, we change to use only the grandchild scope (`left` or `right`) for `find_sort_values` here. Note that it may seem to be more appropriate to use `report` here for the parent scope. However, in `find_sort_values` which is called right after, the `report` scope is always bound to this scope. So we only use grandchild scope to avoid unnecessary operations. Fixes #2069.
-rw-r--r--src/compare.cc32
-rw-r--r--test/regress/2069.test16
2 files changed, 40 insertions, 8 deletions
diff --git a/src/compare.cc b/src/compare.cc
index 63b85154..121f3014 100644
--- a/src/compare.cc
+++ b/src/compare.cc
@@ -88,15 +88,23 @@ bool compare_items<post_t>::operator()(post_t * left, post_t * right)
post_t::xdata_t& lxdata(left->xdata());
if (! lxdata.has_flags(POST_EXT_SORT_CALC)) {
- bind_scope_t bound_scope(*sort_order.get_context(), *left);
- find_sort_values(lxdata.sort_values, bound_scope);
+ if (sort_order.get_context()) {
+ bind_scope_t bound_scope(*sort_order.get_context(), *left);
+ find_sort_values(lxdata.sort_values, bound_scope);
+ } else {
+ find_sort_values(lxdata.sort_values, *left);
+ }
lxdata.add_flags(POST_EXT_SORT_CALC);
}
post_t::xdata_t& rxdata(right->xdata());
if (! rxdata.has_flags(POST_EXT_SORT_CALC)) {
- bind_scope_t bound_scope(*sort_order.get_context(), *right);
- find_sort_values(rxdata.sort_values, bound_scope);
+ if (sort_order.get_context()) {
+ bind_scope_t bound_scope(*sort_order.get_context(), *right);
+ find_sort_values(rxdata.sort_values, bound_scope);
+ } else {
+ find_sort_values(rxdata.sort_values, *right);
+ }
rxdata.add_flags(POST_EXT_SORT_CALC);
}
@@ -111,15 +119,23 @@ bool compare_items<account_t>::operator()(account_t * left, account_t * right)
account_t::xdata_t& lxdata(left->xdata());
if (! lxdata.has_flags(ACCOUNT_EXT_SORT_CALC)) {
- bind_scope_t bound_scope(*sort_order.get_context(), *left);
- find_sort_values(lxdata.sort_values, bound_scope);
+ if (sort_order.get_context()) {
+ bind_scope_t bound_scope(*sort_order.get_context(), *left);
+ find_sort_values(lxdata.sort_values, bound_scope);
+ } else {
+ find_sort_values(lxdata.sort_values, *left);
+ }
lxdata.add_flags(ACCOUNT_EXT_SORT_CALC);
}
account_t::xdata_t& rxdata(right->xdata());
if (! rxdata.has_flags(ACCOUNT_EXT_SORT_CALC)) {
- bind_scope_t bound_scope(*sort_order.get_context(), *right);
- find_sort_values(rxdata.sort_values, bound_scope);
+ if (sort_order.get_context()) {
+ bind_scope_t bound_scope(*sort_order.get_context(), *right);
+ find_sort_values(rxdata.sort_values, bound_scope);
+ } else {
+ find_sort_values(rxdata.sort_values, *right);
+ }
rxdata.add_flags(ACCOUNT_EXT_SORT_CALC);
}
diff --git a/test/regress/2069.test b/test/regress/2069.test
new file mode 100644
index 00000000..1029644c
--- /dev/null
+++ b/test/regress/2069.test
@@ -0,0 +1,16 @@
+P 2021-01-01 EUR 1.15 USD
+
+2021-01-01 Test 1
+ A 100 USD
+ B
+
+2021-01-01 Test 2
+ A 100 EUR
+ B
+
+test -X USD --sort display_amount reg
+21-Jan-01 Test 2 B -115 USD -115 USD
+21-Jan-01 Test 1 B -100 USD -215 USD
+ A 100 USD -115 USD
+21-Jan-01 Test 2 A 115 USD 0
+end test