summaryrefslogtreecommitdiff
path: root/decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'decoder.c')
-rw-r--r--decoder.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/decoder.c b/decoder.c
index 3e04722..cc0a1e1 100644
--- a/decoder.c
+++ b/decoder.c
@@ -391,7 +391,7 @@ err_out:
}
/* Convert annotation class attribute to GSList of char **. */
-static int get_annotations(struct srd_decoder *dec)
+static int get_annotations(struct srd_decoder *dec, size_t *ret_count)
{
PyObject *py_annlist, *py_ann;
GSList *annotations;
@@ -399,6 +399,9 @@ static int get_annotations(struct srd_decoder *dec)
ssize_t i;
PyGILState_STATE gstate;
+ if (ret_count)
+ *ret_count = 0;
+
gstate = PyGILState_Ensure();
if (!PyObject_HasAttrString(dec->py_dec, "annotations")) {
@@ -418,7 +421,10 @@ static int get_annotations(struct srd_decoder *dec)
goto err_out;
}
- for (i = PyTuple_Size(py_annlist) - 1; i >= 0; i--) {
+ i = PyTuple_Size(py_annlist);
+ if (ret_count)
+ *ret_count = i;
+ while (i--) {
py_ann = PyTuple_GetItem(py_annlist, i);
if (!py_ann)
goto except_out;
@@ -451,7 +457,7 @@ err_out:
}
/* Convert annotation_rows to GSList of 'struct srd_decoder_annotation_row'. */
-static int get_annotation_rows(struct srd_decoder *dec)
+static int get_annotation_rows(struct srd_decoder *dec, size_t cls_count)
{
const char *py_member_name = "annotation_rows";
@@ -530,6 +536,11 @@ static int get_annotation_rows(struct srd_decoder *dec)
class_idx = PyLong_AsSize_t(py_item);
if (PyErr_Occurred())
goto except_out;
+ if (class_idx >= cls_count) {
+ srd_err("Protocol decoder %s annotation row %zd references invalid class %zu.",
+ dec->name, i, class_idx);
+ goto err_out;
+ }
ann_row->ann_classes = g_slist_prepend(ann_row->ann_classes,
GSIZE_TO_POINTER(class_idx));
@@ -815,6 +826,7 @@ SRD_API int srd_decoder_load(const char *module_name)
int is_subclass;
const char *fail_txt;
PyGILState_STATE gstate;
+ size_t ann_cls_count;
if (!srd_check_init())
return SRD_ERR;
@@ -957,12 +969,12 @@ SRD_API int srd_decoder_load(const char *module_name)
goto err_out;
}
- if (get_annotations(d) != SRD_OK) {
+ if (get_annotations(d, &ann_cls_count) != SRD_OK) {
fail_txt = "cannot get annotations";
goto err_out;
}
- if (get_annotation_rows(d) != SRD_OK) {
+ if (get_annotation_rows(d, ann_cls_count) != SRD_OK) {
fail_txt = "cannot get annotation rows";
goto err_out;
}