]> sigrok.org Git - libsigrokdecode.git/blobdiff - decoder.c
avr_isp: Add more parts
[libsigrokdecode.git] / decoder.c
index 3e047221e844f67fd74856410d8d2670389b3094..dd3bd5ad40646b0dc81c5f24adefff076cabc2c9 100644 (file)
--- a/decoder.c
+++ b/decoder.c
@@ -199,7 +199,7 @@ static int get_channels(const struct srd_decoder *d, const char *attr,
        PyObject *py_channellist, *py_entry;
        struct srd_channel *pdch;
        GSList *pdchl;
-       ssize_t i;
+       ssize_t ch_idx;
        PyGILState_STATE gstate;
 
        gstate = PyGILState_Ensure();
@@ -222,8 +222,9 @@ static int get_channels(const struct srd_decoder *d, const char *attr,
                goto err_out;
        }
 
-       for (i = PyTuple_Size(py_channellist) - 1; i >= 0; i--) {
-               py_entry = PyTuple_GetItem(py_channellist, i);
+       ch_idx = PyTuple_Size(py_channellist);
+       while (ch_idx--) {
+               py_entry = PyTuple_GetItem(py_channellist, ch_idx);
                if (!py_entry)
                        goto except_out;
 
@@ -243,7 +244,7 @@ static int get_channels(const struct srd_decoder *d, const char *attr,
                if (py_dictitem_as_str(py_entry, "desc", &pdch->desc) != SRD_OK)
                        goto err_out;
 
-               pdch->order = offset + i;
+               pdch->order = offset + ch_idx;
        }
 
        Py_DECREF(py_channellist);
@@ -271,7 +272,7 @@ static int get_options(struct srd_decoder *d)
        GSList *options;
        struct srd_decoder_option *o;
        GVariant *gvar;
-       ssize_t opt, i;
+       ssize_t opt, val_idx;
        PyGILState_STATE gstate;
 
        gstate = PyGILState_Ensure();
@@ -351,8 +352,9 @@ static int get_options(struct srd_decoder *d)
                                goto err_out;
                        }
 
-                       for (i = PyTuple_Size(py_values) - 1; i >= 0; i--) {
-                               py_item = PyTuple_GetItem(py_values, i);
+                       val_idx = PyTuple_Size(py_values);
+                       while (val_idx--) {
+                               py_item = PyTuple_GetItem(py_values, val_idx);
                                if (!py_item)
                                        goto except_out;
 
@@ -391,14 +393,17 @@ 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;
        char **annpair;
-       ssize_t i;
+       ssize_t ann_idx;
        PyGILState_STATE gstate;
 
+       if (ret_count)
+               *ret_count = 0;
+
        gstate = PyGILState_Ensure();
 
        if (!PyObject_HasAttrString(dec->py_dec, "annotations")) {
@@ -418,14 +423,17 @@ static int get_annotations(struct srd_decoder *dec)
                goto err_out;
        }
 
-       for (i = PyTuple_Size(py_annlist) - 1; i >= 0; i--) {
-               py_ann = PyTuple_GetItem(py_annlist, i);
+       ann_idx = PyTuple_Size(py_annlist);
+       if (ret_count)
+               *ret_count = ann_idx;
+       while (ann_idx--) {
+               py_ann = PyTuple_GetItem(py_annlist, ann_idx);
                if (!py_ann)
                        goto except_out;
 
                if (!PyTuple_Check(py_ann) || PyTuple_Size(py_ann) != 2) {
                        srd_err("Protocol decoder %s annotation %zd should be a tuple with two elements.",
-                               dec->name, i + 1);
+                               dec->name, ann_idx + 1);
                        goto err_out;
                }
                if (py_strseq_to_char(py_ann, &annpair) != SRD_OK)
@@ -451,14 +459,14 @@ 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";
 
        PyObject *py_ann_rows, *py_ann_row, *py_ann_classes, *py_item;
        GSList *annotation_rows;
        struct srd_decoder_annotation_row *ann_row;
-       ssize_t i, k;
+       ssize_t row_idx, item_idx;
        size_t class_idx;
        PyGILState_STATE gstate;
 
@@ -481,8 +489,9 @@ static int get_annotation_rows(struct srd_decoder *dec)
                goto err_out;
        }
 
-       for (i = PyTuple_Size(py_ann_rows) - 1; i >= 0; i--) {
-               py_ann_row = PyTuple_GetItem(py_ann_rows, i);
+       row_idx = PyTuple_Size(py_ann_rows);
+       while (row_idx--) {
+               py_ann_row = PyTuple_GetItem(py_ann_rows, row_idx);
                if (!py_ann_row)
                        goto except_out;
 
@@ -517,8 +526,9 @@ static int get_annotation_rows(struct srd_decoder *dec)
                        goto err_out;
                }
 
-               for (k = PyTuple_Size(py_ann_classes) - 1; k >= 0; k--) {
-                       py_item = PyTuple_GetItem(py_ann_classes, k);
+               item_idx = PyTuple_Size(py_ann_classes);
+               while (item_idx--) {
+                       py_item = PyTuple_GetItem(py_ann_classes, item_idx);
                        if (!py_item)
                                goto except_out;
 
@@ -530,6 +540,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, row_idx, class_idx);
+                               goto err_out;
+                       }
 
                        ann_row->ann_classes = g_slist_prepend(ann_row->ann_classes,
                                        GSIZE_TO_POINTER(class_idx));
@@ -559,7 +574,7 @@ static int get_binary_classes(struct srd_decoder *dec)
        PyObject *py_bin_classes, *py_bin_class;
        GSList *bin_classes;
        char **bin;
-       ssize_t i;
+       ssize_t bin_idx;
        PyGILState_STATE gstate;
 
        gstate = PyGILState_Ensure();
@@ -581,8 +596,9 @@ static int get_binary_classes(struct srd_decoder *dec)
                goto err_out;
        }
 
-       for (i = PyTuple_Size(py_bin_classes) - 1; i >= 0; i--) {
-               py_bin_class = PyTuple_GetItem(py_bin_classes, i);
+       bin_idx = PyTuple_Size(py_bin_classes);
+       while (bin_idx--) {
+               py_bin_class = PyTuple_GetItem(py_bin_classes, bin_idx);
                if (!py_bin_class)
                        goto except_out;
 
@@ -815,6 +831,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 +974,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;
        }