diff options
author | Guy Harris <guy@alum.mit.edu> | 2004-10-16 23:32:24 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2004-10-16 23:32:24 +0000 |
commit | 727ad67453a879a58ab46adeee058d2acbbe5c13 (patch) | |
tree | 9fe0f60bac0ddcee9a3c48d3ff0ca8003b3ca707 /epan/range.c | |
parent | de1bcd5d88f4ecd85df770ef5a7a0357b539ee4f (diff) | |
download | wireshark-727ad67453a879a58ab46adeee058d2acbbe5c13.tar.gz |
Remove the fixed maximum number of subranges in a range_t; dynamically
allocate them to be large enough.
Add checks that the numbers in the range fit in a guint32.
Check the validity of a range before saving or printing, and report
errors in an alert box.
Clean up white space.
svn path=/trunk/; revision=12320
Diffstat (limited to 'epan/range.c')
-rw-r--r-- | epan/range.c | 322 |
1 files changed, 191 insertions, 131 deletions
diff --git a/epan/range.c b/epan/range.c index dcfef8b548..adf1591239 100644 --- a/epan/range.c +++ b/epan/range.c @@ -39,12 +39,27 @@ #include <epan/range.h> #include <stdio.h> -/* init the range struct */ -void range_init(range_t *range) { +/* + * GLib 1.2[.x] doesn't define G_MAXUINT32; if it's not defined, we define + * it as the maximum 32-bit unsigned number. + */ +#ifndef G_MAXUINT32 +#define G_MAXUINT32 ((guint32)0xFFFFFFFFU) +#endif + +/* + * Size of the header of a range_t. + */ +#define RANGE_HDR_SIZE (sizeof (range_t) - sizeof (range_admin_t)) - range->nranges = 0; - range->ranges[range->nranges].low = 0L; - range->ranges[range->nranges].high = 0L; +/* Allocate an empty range. */ +range_t *range_empty(void) +{ + range_t *range; + + range = g_malloc(RANGE_HDR_SIZE); + range->nranges = 0; + return range; } /******************** Range Entry Parser *********************************/ @@ -54,10 +69,11 @@ void range_init(range_t *range) { * The parameter 'max_value' specifies the maximum value in a * range. * - * This function fills the array range->ranges containing low and high values - * with the number of ranges being range->nranges. After having called this - * function, the function value_is_in_range() determines whether a given - * number is within the range or not. + * This function allocates a range_t large enough to hold the number + * of ranges specified, and fills the array range->ranges containing + * low and high values with the number of ranges being range->nranges. + * After having called this function, the function value_is_in_range() + * determines whether a given number is within the range or not. * * In case of a single number, we make a range where low is equal to high. * We take care on wrongly entered ranges; opposite order will be taken @@ -72,127 +88,158 @@ void range_init(range_t *range) { * - All values */ -convert_ret_t -range_convert_str(range_t *range, const gchar *es, guint32 max_value) +convert_ret_t range_convert_str(range_t **rangep, const gchar *es, + guint32 max_value) { - const gchar *p; - char *endp; - gchar c; - guint i; - guint32 tmp; - unsigned long val; - - /* Reset the number of ranges we are going to find */ - range->nranges = 0; - range->ranges[range->nranges].low = 0L; - range->ranges[range->nranges].high = 0L; - - /* Process the ranges separately until we get a comma or end of string. - * - * We build a structure array called ranges of high and low values. After the - * following loop, we have the nranges variable which tells how many ranges - * were found. The number of individual ranges is limited to 'MaxRanges' - */ - - p = es; - for (;;) { - /* Skip white space. */ - while ((c = *p) == ' ' || c == '\t') - p++; - if (c == '\0') - break; - - /* This must be a subrange. */ - if (range->nranges == MaxRange) { - /* We've filled up the structure; no room for any more. */ - return CVT_TOO_MANY_SUBRANGES; - } - - if (c == '-') { - /* Subrange starts with 1. */ - range->ranges[range->nranges].low = 1; - } else { - /* Subrange starts with the specified number */ - val = strtol(p, &endp, 10); - if (p == endp) { - /* That wasn't a valid number. */ - return CVT_SYNTAX_ERROR; - } - p = endp; - range->ranges[range->nranges].low = val; - - /* Skip white space. */ - while ((c = *p) == ' ' || c == '\t') - p++; - } - - if (c == '-') { - /* There's a hyphen in the range. Skip past it. */ - p++; - - /* Skip white space. */ - while ((c = *p) == ' ' || c == '\t') - p++; - - if (c == ',' || c == '\0') { - /* - * End of subrange string; that means the subrange ends - * with max_value. - */ - range->ranges[range->nranges].high = max_value; - } else { - /* Subrange ends with the specified number. */ - val = strtol(p, &endp, 10); - if (p == endp) { - /* That wasn't a valid number. */ - return CVT_SYNTAX_ERROR; - } - p = endp; - range->ranges[range->nranges].high = val; - - /* Skip white space. */ - while ((c = *p) == ' ' || c == '\t') - p++; - } - } else if (c == ',' || c == '\0') { - /* - * End of subrange string; that means there's no hyphen - * in the subrange, so the start and the end are the same. - */ - range->ranges[range->nranges].high = - range->ranges[range->nranges].low; - } else { - /* Invalid character. */ - return CVT_SYNTAX_ERROR; - } - range->nranges++; - - if (c == ',') { - /* Subrange is followed by a comma; skip it. */ - p++; - } - } - - /* Now we are going through the low and high values, and check - * whether they are in a proper order. Low should be equal or lower - * than high. So, go through the loop and swap if needed. - */ - for (i=0; i < range->nranges; i++) { - if (range->ranges[i].low > range->ranges[i].high) { - tmp = range->ranges[i].low; - range->ranges[i].low = range->ranges[i].high; - range->ranges[i].high = tmp; - } - } - - /* In case we want to know what the result ranges are : - * - * for (i=0; i < range->nranges; i++) { - * printf("Function : range_convert_str L=%u \t H=%u\n",range->ranges[i].low,range->ranges[i].high); - * } - * - */ - return CVT_NO_ERROR; + range_t *range; + guint nranges; + const gchar *p; + char *endp; + gchar c; + guint i; + guint32 tmp; + unsigned long val; + + /* Allocate a range; this has room for one subrange. */ + range = g_malloc(RANGE_HDR_SIZE + sizeof (range_admin_t)); + range->nranges = 0; + nranges = 1; + + /* Process the ranges separately until we get a comma or end of string. + * + * We build a structure array called ranges of high and low values. After the + * following loop, we have the nranges variable which tells how many ranges + * were found. The number of individual ranges is limited to 'MaxRanges' + */ + + p = es; + for (;;) { + /* Skip white space. */ + while ((c = *p) == ' ' || c == '\t') + p++; + if (c == '\0') + break; + + /* This must be a subrange. Make sure we have room for it. */ + if (range->nranges >= nranges) { + /* Grow the structure. + * 4 is an arbitrarily chosen number. + * We start with 1, under the assumption that people + * will often give a single number or range, and then + * proceed to keep it a multiple of 4. + */ + if (nranges == 1) + nranges = 4; + else + nranges += 4; + range = g_realloc(range, RANGE_HDR_SIZE + + nranges*sizeof (range_admin_t)); + } + + if (c == '-') { + /* Subrange starts with 1. */ + range->ranges[range->nranges].low = 1; + } else if (isdigit((unsigned char)c)) { + /* Subrange starts with the specified number */ + val = strtol(p, &endp, 10); + if (p == endp) { + /* That wasn't a valid number. */ + g_free(range); + return CVT_SYNTAX_ERROR; + } + if (val > G_MAXUINT32) { + /* That was valid, but it's too big. */ + g_free(range); + return CVT_NUMBER_TOO_BIG; + } + p = endp; + range->ranges[range->nranges].low = val; + + /* Skip white space. */ + while ((c = *p) == ' ' || c == '\t') + p++; + } else { + /* Neither empty nor a number. */ + g_free(range); + return CVT_SYNTAX_ERROR; + } + + if (c == '-') { + /* There's a hyphen in the range. Skip past it. */ + p++; + + /* Skip white space. */ + while ((c = *p) == ' ' || c == '\t') + p++; + + if (c == ',' || c == '\0') { + /* End of subrange string; that means the subrange ends + * with max_value. + */ + range->ranges[range->nranges].high = max_value; + } else if (isdigit((unsigned char)c)) { + /* Subrange ends with the specified number. */ + val = strtoul(p, &endp, 10); + if (p == endp) { + /* That wasn't a valid number. */ + g_free(range); + return CVT_SYNTAX_ERROR; + } + if (val > G_MAXUINT32) { + /* That was valid, but it's too big. */ + g_free(range); + return CVT_NUMBER_TOO_BIG; + } + p = endp; + range->ranges[range->nranges].high = val; + + /* Skip white space. */ + while ((c = *p) == ' ' || c == '\t') + p++; + } else { + /* Neither empty nor a number. */ + g_free(range); + return CVT_SYNTAX_ERROR; + } + } else if (c == ',' || c == '\0') { + /* End of subrange string; that means there's no hyphen + * in the subrange, so the start and the end are the same. + */ + range->ranges[range->nranges].high = range->ranges[range->nranges].low; + } else { + /* Invalid character. */ + g_free(range); + return CVT_SYNTAX_ERROR; + } + range->nranges++; + + if (c == ',') { + /* Subrange is followed by a comma; skip it. */ + p++; + } + } + + /* Now we are going through the low and high values, and check + * whether they are in a proper order. Low should be equal or lower + * than high. So, go through the loop and swap if needed. + */ + for (i=0; i < range->nranges; i++) { + if (range->ranges[i].low > range->ranges[i].high) { + tmp = range->ranges[i].low; + range->ranges[i].low = range->ranges[i].high; + range->ranges[i].high = tmp; + } + } + + /* In case we want to know what the result ranges are : + * + * for (i=0; i < range->nranges; i++) { + * printf("Function : range_convert_str L=%u \t H=%u\n",range->ranges[i].low,range->ranges[i].high); + * } + * + */ + *rangep = range; + return CVT_NO_ERROR; } /* range_convert_str */ /* This function returns TRUE if a given value is within one of the ranges @@ -204,7 +251,7 @@ gboolean value_is_in_range(range_t *range, guint32 val) for (i=0; i < range->nranges; i++) { if (val >= range->ranges[i].low && val <= range->ranges[i].high) - return TRUE; + return TRUE; } return(FALSE); } @@ -240,7 +287,7 @@ range_foreach(range_t *range, void (*callback)(guint32 val)) for (i=0; i < range->nranges; i++) { for (j = range->ranges[i].low; j <= range->ranges[i].high; j++) - callback(j); + callback(j); } } @@ -265,6 +312,18 @@ range_convert_range(range_t *range, char *string) } +/* Create a copy of a range. */ +range_t *range_copy(range_t *src) +{ + range_t *dst; + size_t range_size; + + range_size = RANGE_HDR_SIZE + src->nranges*sizeof (range_admin_t); + dst = g_malloc(range_size); + memcpy(dst, src, range_size); + return dst; +} + #if 0 /* This is a debug function to check the range functionality */ static void value_is_in_range_check(range_t *range, guint32 val) @@ -280,3 +339,4 @@ static void value_is_in_range_check(range_t *range, guint32 val) } } #endif + |