diff options
author | Kovarththanan Rajaratnam <kovarththanan.rajaratnam@gmail.com> | 2009-08-16 07:29:11 +0000 |
---|---|---|
committer | Kovarththanan Rajaratnam <kovarththanan.rajaratnam@gmail.com> | 2009-08-16 07:29:11 +0000 |
commit | 01abc372e6cd67d63cee4da3769ff380bbaec5b4 (patch) | |
tree | 5a42dd28dc7d8fbe2e0ab5f755627c65f569b57c | |
parent | 7cb17ecec0a219b05804722bd256f13e952006da (diff) |
Remove a non thread-safe usage (useful when/if we ever support threading) of a static tvbuff in tvb_new_real_data(). The current version uses a static 'last_tvb' to keep track of the last allocated tvbuff. This is needed because some of the function we call can throw an exception. This patch improves this strategy by throwing an exception (if needed) before we try to allocate the tvbuff. This way we avoid a memleak _and_ we don't have to track the 'last_tvb' tvbuff.
svn path=/trunk/; revision=29441
-rw-r--r-- | epan/exceptions.h | 5 | ||||
-rw-r--r-- | epan/tvbuff.c | 36 |
2 files changed, 19 insertions, 22 deletions
diff --git a/epan/exceptions.h b/epan/exceptions.h index a85988398f..0b08ad6562 100644 --- a/epan/exceptions.h +++ b/epan/exceptions.h @@ -243,6 +243,11 @@ #define THROW(x) \ except_throw(XCEPT_GROUP_WIRESHARK, (x), NULL) +#define THROW_ON(cond, x) G_STMT_START { \ + if ((cond)) \ + except_throw(XCEPT_GROUP_WIRESHARK, (x), NULL); \ +} G_STMT_END + #define THROW_MESSAGE(x, y) \ except_throw(XCEPT_GROUP_WIRESHARK, (x), (y)) diff --git a/epan/tvbuff.c b/epan/tvbuff.c index 4dff958a57..c92dec415b 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -270,6 +270,15 @@ tvb_set_child_real_data_tvbuff(tvbuff_t* parent, tvbuff_t* child) add_to_used_in_list(parent, child); } +static void +tvb_set_real_data_no_exceptions(tvbuff_t* tvb, const guint8* data, guint length, gint reported_length) +{ + tvb->real_data = data; + tvb->length = length; + tvb->reported_length = reported_length; + tvb->initialized = TRUE; +} + void tvb_set_real_data(tvbuff_t* tvb, const guint8* data, guint length, gint reported_length) { @@ -277,33 +286,21 @@ tvb_set_real_data(tvbuff_t* tvb, const guint8* data, guint length, gint reported DISSECTOR_ASSERT(tvb->type == TVBUFF_REAL_DATA); DISSECTOR_ASSERT(!tvb->initialized); - if (reported_length < -1) { - THROW(ReportedBoundsError); - } + THROW_ON(reported_length < -1, ReportedBoundsError); - tvb->real_data = data; - tvb->length = length; - tvb->reported_length = reported_length; - tvb->initialized = TRUE; + tvb_set_real_data_no_exceptions(tvb, data, length, reported_length); } tvbuff_t* tvb_new_real_data(const guint8* data, guint length, gint reported_length) { - static tvbuff_t *last_tvb=NULL; tvbuff_t *tvb; - tvb = tvb_new(TVBUFF_REAL_DATA); + THROW_ON(reported_length < -1, ReportedBoundsError); - if(last_tvb){ - tvb_free(last_tvb); - } - /* remember this tvb in case we throw an exception and - * lose the pointer to it. - */ - last_tvb=tvb; + tvb = tvb_new(TVBUFF_REAL_DATA); - tvb_set_real_data(tvb, data, length, reported_length); + tvb_set_real_data_no_exceptions(tvb, data, length, reported_length); /* * This is the top-level real tvbuff for this data source, @@ -311,9 +308,6 @@ tvb_new_real_data(const guint8* data, guint length, gint reported_length) */ tvb->ds_tvb = tvb; - /* ok no exception so we dont need to remember it any longer */ - last_tvb=NULL; - return tvb; } @@ -467,10 +461,8 @@ check_offset_length(tvbuff_t *tvb, gint offset, gint length, DISSECTOR_ASSERT(exception > 0); THROW(exception); } - return; } - void tvb_set_subset(tvbuff_t *tvb, tvbuff_t *backing, gint backing_offset, gint backing_length, gint reported_length) |