static void check_drange_node_sanity(gpointer data, gpointer user_data) { drange_node* drnode = data; struct check_drange_sanity_args *args = user_data; gint start_offset, end_offset, length; header_field_info *hfinfo; switch (drange_node_get_ending(drnode)) { case LENGTH: length = drange_node_get_length(drnode); if (length <= 0) { if (!args->err) { args->err = TRUE; start_offset = drange_node_get_start_offset(drnode); hfinfo = sttype_range_hfinfo(args->st); dfilter_fail("Range %d:%d specified for \"%s\" isn't valid, " "as length %d isn't positive", start_offset, length, hfinfo->abbrev, length); } } break; case OFFSET: /* * Make sure the start offset isn't beyond the end * offset. This applies to negative offsets too. */ /* XXX - [-ve - +ve] is probably pathological, but isn't * disallowed. * [+ve - -ve] is probably pathological too, and happens to be * disallowed. */ start_offset = drange_node_get_start_offset(drnode); end_offset = drange_node_get_end_offset(drnode); if (start_offset > end_offset) { if (!args->err) { args->err = TRUE; hfinfo = sttype_range_hfinfo(args->st); dfilter_fail("Range %d-%d specified for \"%s\" isn't valid, " "as %d is greater than %d", start_offset, end_offset, hfinfo->abbrev, start_offset, end_offset); } } break; case TO_THE_END: break; case UNINITIALIZED: default: g_assert_not_reached(); } }
static void slice_func(gpointer data, gpointer user_data) { drange_node *drnode = data; slice_data_t *slice_data = user_data; gint start_offset; gint length = 0; gint end_offset = 0; guint field_length; fvalue_t *fv; drange_node_end_t ending; if (slice_data->slice_failure) { return; } start_offset = drange_node_get_start_offset(drnode); ending = drange_node_get_ending(drnode); fv = slice_data->fv; field_length = fvalue_length(fv); /* Check for negative start */ if (start_offset < 0) { start_offset = field_length + start_offset; if (start_offset < 0) { slice_data->slice_failure = TRUE; return; } } /* Check the end type and set the length */ if (ending == DRANGE_NODE_END_T_TO_THE_END) { length = field_length - start_offset; if (length <= 0) { slice_data->slice_failure = TRUE; return; } } else if (ending == DRANGE_NODE_END_T_LENGTH) { length = drange_node_get_length(drnode); if (start_offset + length > (int) field_length) { slice_data->slice_failure = TRUE; return; } } else if (ending == DRANGE_NODE_END_T_OFFSET) { end_offset = drange_node_get_end_offset(drnode); if (end_offset < 0) { end_offset = field_length + end_offset; if (end_offset < start_offset) { slice_data->slice_failure = TRUE; return; } } else if (end_offset >= (int) field_length) { slice_data->slice_failure = TRUE; return; } length = end_offset - start_offset + 1; } else { g_assert_not_reached(); } g_assert(start_offset >=0 && length > 0); fv->ftype->slice(fv, slice_data->bytes, start_offset, length); }