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
This commit is contained in:
Kovarththanan Rajaratnam 2009-08-16 07:29:11 +00:00
parent 7cb17ecec0
commit 01abc372e6
2 changed files with 19 additions and 22 deletions

View File

@ -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))

View File

@ -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;
THROW_ON(reported_length < -1, ReportedBoundsError);
tvb = tvb_new(TVBUFF_REAL_DATA);
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_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)