}
/* 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;
ssize_t i;
PyGILState_STATE gstate;
+ if (ret_count)
+ *ret_count = 0;
+
gstate = PyGILState_Ensure();
if (!PyObject_HasAttrString(dec->py_dec, "annotations")) {
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;
}
/* 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";
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));
int is_subclass;
const char *fail_txt;
PyGILState_STATE gstate;
+ size_t ann_cls_count;
if (!srd_check_init())
return SRD_ERR;
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;
}