diff options
author | Guy Harris <guy@alum.mit.edu> | 2003-06-12 08:33:32 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2003-06-12 08:33:32 +0000 |
commit | ee97ce31966f61de148ad85cb229e76a88801b02 (patch) | |
tree | 22f7363da150c57eb593a2e5871033e8b8585437 /epan/tvbuff.c | |
parent | 04a87185285865ae91f903662c4bc721f66c8d88 (diff) |
Add new routines:
tvb_get_string() - takes a tvbuff, an offset, and a length as
arguments, allocates a buffer big enough to hold a string with
the specified number of bytes plus an added null terminator
(i.e., length+1), copies the specified number of bytes from the
tvbuff, at the specified offset, to that buffer and puts in a
null terminator, and returns a pointer to that buffer (or throws
an exception before allocating the buffer if that many bytes
aren't available in the tvbuff);
tvb_get_stringz() - takes a tvbuff, an offset, and a pointer to
a "gint" as arguments, gets the size of the null-terminated
string starting at the specified offset in the tvbuff (throwing
an exception if the null terminator isn't found), allocates a
buffer big enough to hold that string, copies the string to that
buffer, and returns a pointer to that buffer and stores the
length of the string (including the terminating null) in the
variable pointed to by the "gint" pointer.
Replace many pieces of code allocating a buffer and copying a string
with calls to "tvb_get_string()" (for one thing, "tvb_get_string()"
doesn't require you to remember that the argument to
"tvb_get_nstringz0()" is the size of the buffer into which you're
copying the string, which might be the length of the string to be copied
*plus 1*).
Don't use fixed-length buffers for null-terminated strings (even if the
code that generates those packets has a #define to limit the length of
the string). Use "tvb_get_stringz()", instead.
In some cases where a value is fetched but is only used to pass an
argument to a "proto_tree_add_XXX" routine, use "proto_tree_add_item()"
instead.
svn path=/trunk/; revision=7859
Diffstat (limited to 'epan/tvbuff.c')
-rw-r--r-- | epan/tvbuff.c | 73 |
1 files changed, 63 insertions, 10 deletions
diff --git a/epan/tvbuff.c b/epan/tvbuff.c index ec66db45d7..3961868723 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -9,7 +9,7 @@ * the data of a backing tvbuff, or can be a composite of * other tvbuffs. * - * $Id: tvbuff.c,v 1.46 2003/06/09 07:27:42 guy Exp $ + * $Id: tvbuff.c,v 1.47 2003/06/12 08:33:31 guy Exp $ * * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu> * @@ -107,6 +107,10 @@ struct tvbuff { }; static guint8* +ensure_contiguous_no_exception(tvbuff_t *tvb, gint offset, gint length, + int *exception); + +static guint8* ensure_contiguous(tvbuff_t *tvb, gint offset, gint length); /* We dole out tvbuff's from this memchunk. */ @@ -804,7 +808,8 @@ tvb_raw_offset(tvbuff_t *tvb) } static guint8* -composite_ensure_contiguous(tvbuff_t *tvb, guint abs_offset, guint abs_length) +composite_ensure_contiguous_no_exception(tvbuff_t *tvb, guint abs_offset, + guint abs_length) { guint i, num_members; tvb_comp_t *composite; @@ -831,8 +836,11 @@ composite_ensure_contiguous(tvbuff_t *tvb, guint abs_offset, guint abs_length) if (check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i], abs_length, &member_offset, &member_length, NULL)) { + /* + * The range is, in fact, contiguous within member_tvb. + */ g_assert(!tvb->real_data); - return ensure_contiguous(member_tvb, member_offset, member_length); + return ensure_contiguous_no_exception(member_tvb, member_offset, member_length, NULL); } else { tvb->real_data = tvb_memdup(tvb, 0, -1); @@ -854,6 +862,10 @@ ensure_contiguous_no_exception(tvbuff_t *tvb, gint offset, gint length, return NULL; } + /* + * We know that all the data is present in the tvbuff, so + * no exceptions should be thrown. + */ if (tvb->real_data) { return tvb->real_data + abs_offset; } @@ -862,11 +874,11 @@ ensure_contiguous_no_exception(tvbuff_t *tvb, gint offset, gint length, case TVBUFF_REAL_DATA: g_assert_not_reached(); case TVBUFF_SUBSET: - return ensure_contiguous(tvb->tvbuffs.subset.tvb, + return ensure_contiguous_no_exception(tvb->tvbuffs.subset.tvb, abs_offset - tvb->tvbuffs.subset.offset, - abs_length); + abs_length, NULL); case TVBUFF_COMPOSITE: - return composite_ensure_contiguous(tvb, abs_offset, abs_length); + return composite_ensure_contiguous_no_exception(tvb, abs_offset, abs_length); } } @@ -1021,10 +1033,9 @@ tvb_memcpy(tvbuff_t *tvb, guint8* target, gint offset, gint length) * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies * data to it. * - * Does anything depend on this routine treating -1 as meaning "to the - * end of the buffer"? If so, perhaps we need two routines, one that - * treats -1 as such, and one that checks for -1 and then calls this - * routine. + * "composite_ensure_contiguous_no_exception()" depends on -1 not being + * an error; does anything else depend on this routine treating -1 as + * meaning "to the end of the buffer"? */ guint8* tvb_memdup(tvbuff_t *tvb, gint offset, gint length) @@ -1687,6 +1698,48 @@ tvb_format_text(tvbuff_t *tvb, gint offset, gint size) } +/* + * Given a tvbuff, an offset, and a length, allocate a buffer big enough + * to hold a non-null-terminated string of that length at that offset, + * plus a trailing '\0', copy the string into it, and return a pointer + * to the string. + * + * Throws an exception if the tvbuff ends before the string does. + */ +guint8 * +tvb_get_string(tvbuff_t *tvb, gint offset, gint length) +{ + guint8 *ptr, *strbuf; + + ptr = ensure_contiguous(tvb, offset, length); + strbuf = g_malloc(length + 1); + if (length != 0) + memcpy(strbuf, ptr, length); + strbuf[length] = '\0'; + return strbuf; +} + +/* + * Given a tvbuff and an offset, with the offset assumed to refer to + * a null-terminated string, find the length of that string (and throw + * an exception if the tvbuff ends before we find the null), allocate + * a buffer big enough to hold the string, copy the string into it, + * and return a pointer to the string. Also return the length of the + * string (including the terminating null) through a pointer. + */ +guint8 * +tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp) +{ + guint size; + guint8 *strptr; + + size = tvb_strsize(tvb, offset); + strptr = g_malloc(size); + tvb_memcpy(tvb, strptr, offset, size); + *lengthp = size; + return strptr; +} + /* Looks for a stringz (NUL-terminated string) in tvbuff and copies * no more than bufsize number of bytes, including terminating NUL, to buffer. * Returns length of string (not including terminating NUL), or -1 if the string was |