summaryrefslogtreecommitdiff
path: root/epan/dfilter
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2007-05-03 16:11:18 +0000
committerGerald Combs <gerald@wireshark.org>2007-05-03 16:11:18 +0000
commit5713fbc9b90fb46d949f6590662aef547cc64665 (patch)
tree31a5f623fa9c8ddece779ddd20c50f67d570cfa1 /epan/dfilter
parent3ecac7ddd1b6536c2a8ef696471cd35d19f57fc1 (diff)
downloadwireshark-5713fbc9b90fb46d949f6590662aef547cc64665.tar.gz
Handle cases where our macro doesn't have any arguments. We should
probably provide feedback to the user, but at least we don't crash now. Fixes Coverity CID 232. svn path=/trunk/; revision=21664
Diffstat (limited to 'epan/dfilter')
-rw-r--r--epan/dfilter/dfilter-macro.c153
1 files changed, 77 insertions, 76 deletions
diff --git a/epan/dfilter/dfilter-macro.c b/epan/dfilter/dfilter-macro.c
index bfd9497c97..dc079da590 100644
--- a/epan/dfilter/dfilter-macro.c
+++ b/epan/dfilter/dfilter-macro.c
@@ -5,17 +5,17 @@
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 2001 Gerald Combs
- *
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
@@ -44,7 +44,7 @@ static guint num_macros;
void dfilter_macro_foreach(dfilter_macro_cb_t cb, void* data) {
guint i;
-
+
for (i = 0; i < num_macros; i++) {
cb(&(macros[i]),data);
}
@@ -53,22 +53,22 @@ void dfilter_macro_foreach(dfilter_macro_cb_t cb, void* data) {
static void macro_fprint(dfilter_macro_t* m, void* ud) {
FILE* f = ud;
-
+
fprintf(f,"%s\t%s\n",m->name,m->text);
}
void dfilter_macro_save(const gchar* filename, gchar** error) {
FILE* f = fopen(filename,"w");
-
+
if (!f) {
*error = ep_strdup_printf("Could not open file: '%s', error: %s\n", filename, strerror(errno) );
return;
}
-
+
dfilter_macro_foreach(macro_fprint, f);
-
+
fclose(f);
-
+
return;
}
@@ -79,10 +79,10 @@ static void macro_dump(dfilter_macro_t* m _U_, void* ud _U_) {
printf("\n->%s\t%s\t%d [%d]\n\t'%s'\n",
m->name, m->text, m->argc, m->usable, *(part++));
-
+
while (*part) {
printf("\t$%d '%s'\n",*args_pos,*part);
-
+
args_pos++;
part++;
}
@@ -105,7 +105,7 @@ static gchar* dfilter_macro_resolve(gchar* name, gchar** args, const gchar** err
gchar** parts;
gchar* ret;
guint i;
-
+
for (i = 0; i < num_macros; i++) {
dfilter_macro_t* c = &(macros[i]);
if ( c->usable && g_str_equal(c->name,name) ) {
@@ -113,37 +113,39 @@ static gchar* dfilter_macro_resolve(gchar* name, gchar** args, const gchar** err
break;
}
}
-
+
if (!m) {
*error = ep_strdup_printf("macro '%s' does not exist", name);
return NULL;
}
-
+
if (args) {
while(args[argc]) argc++;
}
-
+
if (argc != m->argc) {
*error = ep_strdup_printf("wrong number of arguments for macro '%s', expecting %d instead of %d",
name, m->argc, argc);
return NULL;
}
-
+
arg_pos_p = m->args_pos;
parts = m->parts;
-
+
text = g_string_new(*(parts++));
-
- while (*parts) {
- g_string_sprintfa(text,"%s%s",
+
+ if (args) {
+ while (*parts) {
+ g_string_sprintfa(text,"%s%s",
args[*(arg_pos_p++)],
*(parts++));
+ }
}
-
+
ret = ep_strdup(text->str);
-
+
g_string_free(text,TRUE);
-
+
return ret;
}
@@ -157,14 +159,14 @@ gchar* dfilter_macro_apply(const gchar* text, guint depth, const gchar** error)
gchar c;
const gchar* r = text;
gboolean changed = FALSE;
-
+
if ( depth > 31) {
*error = "too much nesting in macros";
return NULL;
}
-
+
#define FGS(n) if (n) g_string_free(n,TRUE); n = NULL
-
+
#define FREE_ALL() \
do { \
FGS(name); \
@@ -173,13 +175,13 @@ gchar* dfilter_macro_apply(const gchar* text, guint depth, const gchar** error)
while(args->len) { void* p = g_ptr_array_remove_index_fast(args,0); if (p) g_free(p); } \
g_ptr_array_free(args,TRUE); \
args = NULL; } } while(0)
-
+
*error = NULL;
out = g_string_sized_new(64);
while(1) {
c = *r++;
-
+
switch(state) {
case OUTSIDE: {
switch(c) {
@@ -200,20 +202,20 @@ gchar* dfilter_macro_apply(const gchar* text, guint depth, const gchar** error)
args = g_ptr_array_new();
arg = g_string_sized_new(32);
name = g_string_sized_new(32);
-
+
state = NAME;
-
+
break;
} case '\0': {
g_string_append_c(out,'$');
-
+
goto finish;
} default: {
g_string_append_c(out,'$');
g_string_append_c(out,c);
-
+
state = OUTSIDE;
-
+
break;
}
}
@@ -225,22 +227,22 @@ gchar* dfilter_macro_apply(const gchar* text, guint depth, const gchar** error)
state = ARGS;
} else if ( c == '}') {
gchar* resolved;
-
+
g_ptr_array_add(args,NULL);
-
+
resolved = dfilter_macro_resolve(name->str, (gchar**)args->pdata, error);
if (*error) goto on_error;
-
+
changed = TRUE;
-
+
g_string_append(out,resolved);
-
+
FREE_ALL();
-
+
state = OUTSIDE;
} else if ( c == '\0') {
*error = "end of filter in the middle of a macro expression";
- goto on_error;
+ goto on_error;
} else {
*error = "invalid char in macro name";
goto on_error;
@@ -250,11 +252,11 @@ gchar* dfilter_macro_apply(const gchar* text, guint depth, const gchar** error)
switch(c) {
case '\0': {
*error = "end of filter in the middle of a macro expression";
- goto on_error;
+ goto on_error;
} case ';': {
g_ptr_array_add(args,arg->str);
g_string_free(arg,FALSE);
-
+
arg = g_string_sized_new(32);
break;
} case '\\': {
@@ -264,7 +266,7 @@ gchar* dfilter_macro_apply(const gchar* text, guint depth, const gchar** error)
break;
} else {
*error = "end of filter in the middle of a macro expression";
- goto on_error;
+ goto on_error;
}
} default: {
g_string_append_c(arg,c);
@@ -276,16 +278,16 @@ gchar* dfilter_macro_apply(const gchar* text, guint depth, const gchar** error)
g_string_free(arg,FALSE);
arg = NULL;
-
+
resolved = dfilter_macro_resolve(name->str, (gchar**)args->pdata, error);
if (*error) goto on_error;
-
+
changed = TRUE;
-
+
g_string_append(out,resolved);
-
+
FREE_ALL();
-
+
state = OUTSIDE;
break;
}
@@ -294,11 +296,11 @@ gchar* dfilter_macro_apply(const gchar* text, guint depth, const gchar** error)
}
}
}
-
+
finish:
{
FREE_ALL();
-
+
if (changed) {
gchar* resolved = dfilter_macro_apply(out->str, depth++, error);
g_string_free(out,TRUE);
@@ -327,29 +329,29 @@ static void macro_update(void* mp, const gchar** error) {
gchar* part;
int argc = 0;
guint i;
-
+
*error = NULL;
-
+
for (i = 0; i < num_macros; i++) {
if (m == &(macros[i])) continue;
-
+
if ( g_str_equal(m->name,macros[i].name) ) {
*error = ep_strdup_printf("macro '%s' exists already", m->name);
m->usable = FALSE;
return;
}
}
-
+
parts = g_ptr_array_new();
args_pos = g_array_new(FALSE,FALSE,sizeof(int));
m->priv = part = w = g_strdup(m->text);
r = m->text;
g_ptr_array_add(parts,part);
-
- do {
-
- switch (*r) {
+
+ while (r && *r) {
+
+ switch (*r) {
default:
*(w++) = *(r++);
break;
@@ -373,8 +375,8 @@ static void macro_update(void* mp, const gchar** error) {
} else {
break;
}
- } while(1);
-
+ } while(*r);
+
if (cnt) {
*(w++) = '\0';
r++;
@@ -388,8 +390,8 @@ static void macro_update(void* mp, const gchar** error) {
break;
}
}
-
- } while(1);
+
+ }
done:
g_ptr_array_add(parts,NULL);
@@ -397,26 +399,26 @@ done:
if (m->parts) g_free(m->parts);
m->parts = (gchar**)parts->pdata;
-
+
if (m->args_pos) g_free(m->args_pos);
-
+
m->args_pos = (int*)(void *)args_pos->data;
g_ptr_array_free(parts,FALSE);
g_array_free(args_pos,FALSE);
-
+
m->argc = argc;
-
+
m->usable = TRUE;
-
+
macro_dump(m,NULL);
-
+
return;
}
static void macro_free(void* r) {
dfilter_macro_t* m = r;
-
+
g_free(m->name);
g_free(m->text);
g_free(m->priv);
@@ -434,27 +436,27 @@ static void* macro_copy(void* dest, const void* orig, unsigned len _U_) {
d->usable = m->usable;
if (m->parts) {
- do nparts++; while (m->parts[nparts]);
+ do nparts++; while (m->parts[nparts]);
d->priv = g_strdup(m->priv);
d->parts = g_memdup(m->parts,nparts*sizeof(void*));
d->args_pos = g_memdup(m->args_pos,(--nparts)*sizeof(int));
}
-
-
+
+
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;
-
+
for (i=0; i < name_len; i++) {
if (!(in_name[i] == '_' || isalnum((int)in_name[i]) ) ) {
*error = "invalid char in name";
return FALSE;
}
}
-
+
return i > 0 ? TRUE : FALSE;
}
@@ -467,7 +469,7 @@ void dfilter_macro_init(void) {
UAT_FLD_CSTRING_ISPRINT(macro,text,"The text this macro resolves to."),
UAT_END_FIELDS
};
-
+
dfilter_macro_uat = uat_new("Display Filter Macros",
sizeof(dfilter_macro_t),
DFILTER_MACRO_FILENAME,
@@ -484,4 +486,3 @@ void dfilter_macro_init(void) {
void dfilter_macro_get_uat(void** p) {
*p = dfilter_macro_uat;
}
-