diff options
author | sake <sake@f5534014-38df-0310-8fa8-9805f1628bb7> | 2007-12-29 09:12:29 +0000 |
---|---|---|
committer | sake <sake@f5534014-38df-0310-8fa8-9805f1628bb7> | 2007-12-29 09:12:29 +0000 |
commit | b505f6cb8403ae70d4bba7b36cfc0a94d9e966d0 (patch) | |
tree | 0c65c6da7e73eb88c9e5409ddea86180c20e0dce /epan/dfilter | |
parent | 11ae0f94dc6bb24c0f1598fe13d64fc3646e325c (diff) |
Fix for bug 2068 from Jim Young:
After a new display filter macro (dfmacro) has been defined, the first attempt
to use the dfmacro will result in a crash of Wireshark when the closing "}"
character is entered into the "Filter:" text entry field.
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@23969 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dfilter')
-rw-r--r-- | epan/dfilter/dfilter-macro.c | 167 |
1 files changed, 163 insertions, 4 deletions
diff --git a/epan/dfilter/dfilter-macro.c b/epan/dfilter/dfilter-macro.c index a865c90cd7..c27baf4864 100644 --- a/epan/dfilter/dfilter-macro.c +++ b/epan/dfilter/dfilter-macro.c @@ -51,6 +51,14 @@ static dfilter_macro_t* macros = NULL; static guint num_macros; static GHashTable* fvt_cache = NULL; +/* #define DUMP_DFILTER_MACRO */ +#ifdef DUMP_DFILTER_MACRO +void dump_dfilter_macro_t(const dfilter_macro_t *m, const char *function, const char *file, int line); +#define DUMP_MACRO(m) dump_dfilter_macro_t(m, __func__, __FILE__, __LINE__) +#else +#define DUMP_MACRO(m) +#endif + static gboolean free_value(gpointer k _U_, gpointer v, gpointer u _U_) { fvt_cache_entry_t* e = v; if (e->repr) g_free(e->repr); @@ -175,6 +183,8 @@ static gchar* dfilter_macro_resolve(gchar* name, gchar** args, const gchar** err } } + DUMP_MACRO(m); + if (args) { while(args[argc]) argc++; } @@ -386,6 +396,8 @@ static void macro_update(void* mp, const gchar** error) { int argc = 0; guint i; + DUMP_MACRO(m); + *error = NULL; for (i = 0; i < num_macros; i++) { @@ -470,12 +482,16 @@ done: macro_dump(m,NULL); + DUMP_MACRO(m); + return; } static void macro_free(void* r) { dfilter_macro_t* m = r; + DUMP_MACRO(r); + g_free(m->name); g_free(m->text); g_free(m->priv); @@ -486,24 +502,76 @@ static void macro_free(void* r) { static void* macro_copy(void* dest, const void* orig, unsigned len _U_) { dfilter_macro_t* d = dest; const dfilter_macro_t* m = orig; - guint nparts = 0; + + DUMP_MACRO(m); d->name = g_strdup(m->name); d->text = g_strdup(m->text); d->usable = m->usable; if (m->parts) { + guint nparts = 0; + + /* + * Copy the contents of m->priv (a "cooked" version + * of m->text) into d->priv. + * + * First we clone m->text into d->priv, this gets + * us a NUL terminated string of the proper length. + * + * Then we loop copying bytes from m->priv into + * d-priv. Since m->priv contains internal ACSII NULs + * we use the length of m->text to stop the copy. + */ + + d->priv = g_strdup(m->text); + { + const gchar* oldText = m->text; + const gchar* oldPriv = m->priv; + gchar* newPriv = d->priv; + while(oldText && *oldText) { + *(newPriv++) = *(oldPriv++); + oldText++; + } + } + + /* + * The contents of the m->parts array contains pointers + * into various sections of m->priv. Since it's + * an argv style array of ponters, this array is + * actually one larger than the number of parts + * to hold the final NULL terminator. + * + * The following copy clones the original m->parts + * array into d->parts but then fixes-up the pointers + * so that they point into the appropriate sections + * of the d->priv. + */ + do nparts++; while (m->parts[nparts]); - d->priv = g_strdup(m->priv); - d->parts = g_memdup(m->parts,nparts*sizeof(void*)); + d->parts = g_memdup(m->parts,(nparts+1)*sizeof(void*)); + nparts = 0; + while(m->parts[nparts]) { + if(nparts) { + d->parts[nparts] = d->parts[nparts - 1] + (m->parts[nparts] - m->parts[nparts - 1]); + } else { + d->parts[nparts] = d->priv; + } + nparts++; + } + + /* + * Clone the contents of m->args_pos into d->args_pos. + */ + d->args_pos = g_memdup(m->args_pos,(--nparts)*sizeof(int)); } + DUMP_MACRO(d); return d; } - static gboolean macro_name_chk(void* r _U_, const char* in_name, unsigned name_len, void* u1 _U_, void* u2 _U_, const char** error) { guint i; @@ -551,6 +619,97 @@ void dfilter_macro_get_uat(void** p) { *p = dfilter_macro_uat; } +#ifdef DUMP_DFILTER_MACRO +/* + * The dfilter_macro_t has several characteristics that are + * not immediattly obvious. The dump_dfilter_filter_macro_t() + * function can be used to help "visualize" the contents of + * a dfilter_macro_t. + * + * Some non-obvious components of this struct include: + * + * m->parts is an argv style array of pointers into the + * m->priv string. + * + * The last pointer of an m->parts array should contain + * NULL to indicate the end of the parts pointer array. + * + * m->priv is a "cooked" copy of the m->text string. + * Any variable substitution indicators within m->text + * ("$1", "$2", ...) will have been replaced with ASCII + * NUL characters within m->priv. + * + * The first element of m->parts array (m-parts[0]) will + * usually have the same pointer value as m->priv (unless + * the dfilter-macro starts off with a variable + * substitution indicator (e.g. "$1"). + */ + +void dump_dfilter_macro_t(const dfilter_macro_t *m, const char *function, const char *file, int line) +{ + printf("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); + + if(m == NULL) { + printf(" dfilter_macro_t * == NULL! (via: %s(): %s:%d)\n", function, file, line); + printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); + } + + printf("DUMP of dfilter_macro_t: %p (via: %s(): %s:%d)\n", m, function, file, line); + + printf(" &dfilter_macro->name == %p\n", &m->name); + if(m->name == NULL) { + printf(" ->name == NULL\n"); + } else { + printf(" ->name == %p\n", m->name); + printf(" ->name == <%s>\n", m->name); + } + + printf(" &dfilter_macro->text == %p\n", &m->text); + if(m->text == NULL) { + printf(" ->text == NULL\n"); + } else { + printf(" ->text == %p\n", m->text); + printf(" ->text == <%s>\n", m->text); + } + + printf(" &dfilter_macro->usable == %p\n", &m->usable); + printf(" ->usable == %u\n", m->usable); + printf(" &dfilter_macro->parts == %p\n", &m->parts); + if(m->parts == NULL) { + printf(" ->parts == NULL\n"); + } else { + int i = 0; + + while (m->parts[i]) { + printf(" ->parts[%d] == %p\n", i, m->parts[i]); + printf(" ->parts[%d] == <%s>\n", i, m->parts[i]); + i++; + } + printf(" ->parts[%d] == NULL\n", i); + } + + printf(" &dfilter_macro->args_pos == %p\n", &m->args_pos); + if(m->args_pos == NULL) { + printf(" ->args_pos == NULL\n"); + } else { + printf(" ->args_pos == %p\n", m->args_pos); + /*printf(" ->args_pos == <%?>\n", m->args_pos);*/ + } + + printf(" &dfilter_macro->argc == %p\n", &m->argc); + printf(" ->argc == %d\n", m->argc); + + printf(" &dfilter_macro->priv == %p\n", &m->priv); + if(m->priv == NULL) { + printf(" ->priv == NULL\n"); + } else { + printf(" ->priv == %p\n", m->priv); + printf(" ->priv == <%s>\n", (char *)m->priv); + } + + printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); +} +#endif |