From c16748c703b0786c5daf4eda3a8af1da8bdf9cd8 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Tue, 23 Apr 2019 19:54:42 -0400 Subject: [PATCH] Fix: bfcr_get_sequence_length_cb(): do not set text array's length Issue ===== In `msg-iter.c`, bfcr_get_sequence_length_cb() gets called when starting the decoding of any sequence, including text sequences. However, text arrays are translated into trace IR string field classes. bfcr_get_sequence_length_cb() calls bt_field_dynamic_array_set_length() unconditionally, but its field argument can be a string field at this point. This is a precondition break. Solution ======== In bt_field_dynamic_array_set_length(), only call bt_field_dynamic_array_set_length() if the CTF IR field class is NOT a text sequence. I'm also adding an assertion to confirm that the trace IR field is a dynamic array field. Known drawbacks =============== None. Signed-off-by: Philippe Proulx --- plugins/ctf/common/msg-iter/msg-iter.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/plugins/ctf/common/msg-iter/msg-iter.c b/plugins/ctf/common/msg-iter/msg-iter.c index 0d41638e..9f3dbad9 100644 --- a/plugins/ctf/common/msg-iter/msg-iter.c +++ b/plugins/ctf/common/msg-iter/msg-iter.c @@ -2288,11 +2288,23 @@ int64_t bfcr_get_sequence_length_cb(struct ctf_field_class *fc, void *data) seq_fc->stored_length_index); seq_field = stack_top(notit->stack)->base; BT_ASSERT(seq_field); - ret = bt_field_dynamic_array_set_length(seq_field, (uint64_t) length); - if (ret) { - BT_LOGE("Cannot set dynamic array field's length field: " - "notit-addr=%p, field-addr=%p, " - "length=%" PRIu64, notit, seq_field, length); + + /* + * bfcr_get_sequence_length_cb() also gets called back for a + * text sequence, but the destination field is a string field. + * Only set the field's sequence length if the destination field + * is a sequence field. + */ + if (!seq_fc->base.is_text) { + BT_ASSERT(bt_field_get_class_type(seq_field) == + BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY); + ret = bt_field_dynamic_array_set_length(seq_field, + (uint64_t) length); + if (ret) { + BT_LOGE("Cannot set dynamic array field's length field: " + "notit-addr=%p, field-addr=%p, " + "length=%" PRIu64, notit, seq_field, length); + } } return length; -- 2.34.1