aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKovarththanan Rajaratnam <kovarththanan.rajaratnam@gmail.com>2009-08-16 07:29:11 +0000
committerKovarththanan Rajaratnam <kovarththanan.rajaratnam@gmail.com>2009-08-16 07:29:11 +0000
commit01abc372e6cd67d63cee4da3769ff380bbaec5b4 (patch)
tree5a42dd28dc7d8fbe2e0ab5f755627c65f569b57c
parent7cb17ecec0a219b05804722bd256f13e952006da (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.h5
-rw-r--r--epan/tvbuff.c36
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)