aboutsummaryrefslogtreecommitdiffstats
path: root/epan/wslua/wslua_pinfo.c
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2008-07-26 23:41:31 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2008-07-26 23:41:31 +0000
commit006e41af1227d23fa30b8ad540603303e6e96bff (patch)
treecede1b6e4568e7ebd148b7542dc91c5140236b93 /epan/wslua/wslua_pinfo.c
parent5ad5441634bd440d99db9db76a207862e3af459d (diff)
From Balint Reczey
Fix for https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=2453 The patch fixes the problem by extending the original "outstanding stuff" approach. Now the pointer itself won't be NULLified, instead we track the pointers with their expiry state in structs in the outstanding_stuff list. The Lua objects refers to those structs instead of the actual pointers and checks the expiry state of the pointers before accessing them. The pointers are marked expired when the dissection of the frame is finished and the allocated struct is freed by Lua's garbage collector. If the garbage collector hits the struct when it holds a not expired pointer, it marks it as expired (that means we don't have any object in Lua referring to the pointer) and the struct will be freed at the end of the dissection of the frame. this is for the 1.0 branch svn path=/trunk/; revision=25845
Diffstat (limited to 'epan/wslua/wslua_pinfo.c')
-rw-r--r--epan/wslua/wslua_pinfo.c218
1 files changed, 167 insertions, 51 deletions
diff --git a/epan/wslua/wslua_pinfo.c b/epan/wslua/wslua_pinfo.c
index 07d85bd352..44b3ba53fd 100644
--- a/epan/wslua/wslua_pinfo.c
+++ b/epan/wslua/wslua_pinfo.c
@@ -4,6 +4,7 @@
* Wireshark's interface to the Lua Programming Language
*
* (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
+ * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
*
* $Id$
*
@@ -36,29 +37,31 @@
/*
- * NULLify lua userdata to avoid crashing when trying to
- * access saved copies of invalid stuff.
- *
- * see comment on lua_tvb.c
+ * Track pointers to wireshark's structures.
+ * see comment on wslua_tvb.c
*/
-static GPtrArray* outstanding_stuff = NULL;
-
-void clear_outstanding_pinfos(void) {
- while (outstanding_stuff->len) {
- void** p = (void**)g_ptr_array_remove_index_fast(outstanding_stuff,0);
- *p = NULL;
+static GPtrArray* outstanding_Pinfo = NULL;
+static GPtrArray* outstanding_Column = NULL;
+static GPtrArray* outstanding_Columns = NULL;
+
+CLEAR_OUTSTANDING(Pinfo,expired, TRUE)
+CLEAR_OUTSTANDING(Column,expired, TRUE)
+CLEAR_OUTSTANDING(Columns,expired, TRUE)
+
+Pinfo* push_Pinfo(lua_State* L, packet_info* ws_pinfo) {
+ Pinfo pinfo = NULL;
+ if (ws_pinfo) {
+ pinfo = g_malloc(sizeof(struct _wslua_pinfo));
+ pinfo->ws_pinfo = ws_pinfo;
+ pinfo->expired = FALSE;
+ g_ptr_array_add(outstanding_Pinfo,pinfo);
}
+ return pushPinfo(L,pinfo);
}
-void* push_Pinfo(lua_State* L, Pinfo pinfo) {
- void** p = (void**)pushPinfo(L,pinfo);
- g_ptr_array_add(outstanding_stuff,p);
- return p;
-}
-
-#define PUSH_COLUMN(L,c) g_ptr_array_add(outstanding_stuff,pushColumn(L,c))
-#define PUSH_COLUMNS(L,c) g_ptr_array_add(outstanding_stuff,pushColumns(L,c))
+#define PUSH_COLUMN(L,c) {g_ptr_array_add(outstanding_Column,c);pushColumn(L,c);}
+#define PUSH_COLUMNS(L,c) {g_ptr_array_add(outstanding_Columns,c);pushColumns(L,c);}
WSLUA_CLASS_DEFINE(Address,NOP,NOP); /* Represents an address */
@@ -377,6 +380,20 @@ WSLUA_METAMETHOD Column__tostring(lua_State *L) {
WSLUA_RETURN(1); /* A string representing the column */
}
+WSLUA_METAMETHOD Column__gc(lua_State* L) {
+ Column col = checkColumn(L,1);
+
+ if (!col) return 0;
+
+ if (!col->expired)
+ col->expired = TRUE;
+ else
+ g_free(col);
+
+ return 0;
+
+}
+
WSLUA_METHOD Column_clear(lua_State *L) {
/* Clears a Column */
Column c = checkColumn(L,1);
@@ -452,6 +469,7 @@ WSLUA_METHODS Column_methods[] = {
WSLUA_META Column_meta[] = {
{"__tostring", Column__tostring },
+ {"__gc", Column__gc },
{0,0}
};
@@ -485,14 +503,18 @@ WSLUA_METAMETHOD Columns__newindex(lua_State *L) {
const char* text;
if (!cols) return 0;
+ if (cols->expired) {
+ luaL_error(L,"expired column");
+ return 0;
+ }
colname = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_COLUMN);
text = luaL_checkstring(L,WSLUA_ARG_Columns__newindex_TEXT);
for(cn = colnames; cn->name; cn++) {
if( g_str_equal(cn->name,colname) ) {
- if (check_col(cols, cn->id))
- col_set_str(cols, cn->id, text);
+ if (check_col(cols->cinfo, cn->id))
+ col_set_str(cols->cinfo, cn->id, text);
return 0;
}
}
@@ -508,23 +530,29 @@ WSLUA_METAMETHOD Columns_index(lua_State *L) {
const char* colname = luaL_checkstring(L,2);
if (!cols) {
- Column c = ep_alloc(sizeof(struct _wslua_col_info));
+ Column c = g_malloc(sizeof(struct _wslua_col_info));
c->cinfo = NULL;
c->col = col_name_to_id(colname);
+ c->expired = FALSE;
PUSH_COLUMN(L,c);
return 1;
}
+ if (cols->expired) {
+ luaL_error(L,"expired column");
+ return 0;
+ }
if (!colname) return 0;
for(cn = colnames; cn->name; cn++) {
if( g_str_equal(cn->name,colname) ) {
- Column c = ep_alloc(sizeof(struct _wslua_col_info));
- c->cinfo = cols;
+ Column c = g_malloc(sizeof(struct _wslua_col_info));
+ c->cinfo = cols->cinfo;
c->col = col_name_to_id(colname);
+ c->expired = FALSE;
PUSH_COLUMN(L,c);
return 1;
@@ -534,11 +562,26 @@ WSLUA_METAMETHOD Columns_index(lua_State *L) {
return 0;
}
+WSLUA_METAMETHOD Columns_gc(lua_State* L) {
+ Columns cols = checkColumns(L,1);
+
+ if (!cols) return 0;
+
+ if (!cols->expired)
+ cols->expired = TRUE;
+ else
+ g_free(cols);
+
+ return 0;
+
+}
+
static const luaL_reg Columns_meta[] = {
{"__tostring", Columns__tostring },
{"__newindex", Columns__newindex },
{"__index", Columns_index},
+ {"__gc", Columns_gc},
{ NULL, NULL }
};
@@ -557,6 +600,10 @@ static int Pinfo_tostring(lua_State *L) { lua_pushstring(L,"a Pinfo"); return 1;
#define PINFO_GET_NUMBER(name,val) static int name(lua_State *L) { \
Pinfo pinfo = checkPinfo(L,1); \
if (!pinfo) return 0;\
+ if (pinfo->expired) { \
+ luaL_error(L,"expired_pinfo"); \
+ return 0; \
+ } \
lua_pushnumber(L,(lua_Number)(val));\
return 1;\
}
@@ -565,6 +612,10 @@ static int Pinfo_tostring(lua_State *L) { lua_pushstring(L,"a Pinfo"); return 1;
Pinfo pinfo = checkPinfo(L,1); \
const gchar* value; \
if (!pinfo) return 0; \
+ if (pinfo->expired) { \
+ luaL_error(L,"expired_pinfo"); \
+ return 0; \
+ } \
value = val; \
if (value) lua_pushstring(L,(const char*)(value)); else lua_pushnil(L); \
return 1; \
@@ -574,25 +625,29 @@ static int Pinfo_tostring(lua_State *L) { lua_pushstring(L,"a Pinfo"); return 1;
Pinfo pinfo = checkPinfo(L,1); \
Address addr = g_malloc(sizeof(address)); \
if (!pinfo) return 0; \
- COPY_ADDRESS(addr, &(pinfo->role)); \
+ if (pinfo->expired) { \
+ luaL_error(L,"expired_pinfo"); \
+ return 0; \
+ } \
+ COPY_ADDRESS(addr, &(pinfo->ws_pinfo->role)); \
pushAddress(L,addr); \
return 1; \
}
-PINFO_GET_NUMBER(Pinfo_number,pinfo->fd->num)
-PINFO_GET_NUMBER(Pinfo_len,pinfo->fd->pkt_len)
-PINFO_GET_NUMBER(Pinfo_caplen,pinfo->fd->cap_len)
-PINFO_GET_NUMBER(Pinfo_abs_ts,(((double)pinfo->fd->abs_ts.secs) + (((double)pinfo->fd->abs_ts.nsecs) / 1000000000.0) ))
-PINFO_GET_NUMBER(Pinfo_rel_ts,(((double)pinfo->fd->rel_ts.secs) + (((double)pinfo->fd->rel_ts.nsecs) / 1000000000.0) ))
-PINFO_GET_NUMBER(Pinfo_delta_ts,(((double)pinfo->fd->del_cap_ts.secs) + (((double)pinfo->fd->del_cap_ts.nsecs) / 1000000000.0) ))
-PINFO_GET_NUMBER(Pinfo_delta_dis_ts,(((double)pinfo->fd->del_dis_ts.secs) + (((double)pinfo->fd->del_dis_ts.nsecs) / 1000000000.0) ))
-PINFO_GET_NUMBER(Pinfo_ipproto,pinfo->ipproto)
-PINFO_GET_NUMBER(Pinfo_circuit_id,pinfo->circuit_id)
-PINFO_GET_NUMBER(Pinfo_ptype,pinfo->ptype)
-PINFO_GET_NUMBER(Pinfo_src_port,pinfo->srcport)
-PINFO_GET_NUMBER(Pinfo_dst_port,pinfo->destport)
+PINFO_GET_NUMBER(Pinfo_number,pinfo->ws_pinfo->fd->num)
+PINFO_GET_NUMBER(Pinfo_len,pinfo->ws_pinfo->fd->pkt_len)
+PINFO_GET_NUMBER(Pinfo_caplen,pinfo->ws_pinfo->fd->cap_len)
+PINFO_GET_NUMBER(Pinfo_abs_ts,(((double)pinfo->ws_pinfo->fd->abs_ts.secs) + (((double)pinfo->ws_pinfo->fd->abs_ts.nsecs) / 1000000000.0) ))
+PINFO_GET_NUMBER(Pinfo_rel_ts,(((double)pinfo->ws_pinfo->fd->rel_ts.secs) + (((double)pinfo->ws_pinfo->fd->rel_ts.nsecs) / 1000000000.0) ))
+PINFO_GET_NUMBER(Pinfo_delta_ts,(((double)pinfo->ws_pinfo->fd->del_cap_ts.secs) + (((double)pinfo->ws_pinfo->fd->del_cap_ts.nsecs) / 1000000000.0) ))
+PINFO_GET_NUMBER(Pinfo_delta_dis_ts,(((double)pinfo->ws_pinfo->fd->del_dis_ts.secs) + (((double)pinfo->ws_pinfo->fd->del_dis_ts.nsecs) / 1000000000.0) ))
+PINFO_GET_NUMBER(Pinfo_ipproto,pinfo->ws_pinfo->ipproto)
+PINFO_GET_NUMBER(Pinfo_circuit_id,pinfo->ws_pinfo->circuit_id)
+PINFO_GET_NUMBER(Pinfo_ptype,pinfo->ws_pinfo->ptype)
+PINFO_GET_NUMBER(Pinfo_src_port,pinfo->ws_pinfo->srcport)
+PINFO_GET_NUMBER(Pinfo_dst_port,pinfo->ws_pinfo->destport)
-PINFO_GET_STRING(Pinfo_curr_proto,pinfo->current_proto)
+PINFO_GET_STRING(Pinfo_curr_proto,pinfo->ws_pinfo->current_proto)
PINFO_GET_ADDRESS(Pinfo_net_src,net_src)
PINFO_GET_ADDRESS(Pinfo_net_dst,net_dst)
@@ -604,7 +659,11 @@ PINFO_GET_ADDRESS(Pinfo_dst,dst)
static int Pinfo_visited(lua_State *L) {
Pinfo pinfo = checkPinfo(L,1);
if (!pinfo) return 0;
- lua_pushboolean(L,pinfo->fd->flags.visited);
+ if (pinfo->expired) {
+ luaL_error(L,"expired_pinfo");
+ return 0;
+ }
+ lua_pushboolean(L,pinfo->ws_pinfo->fd->flags.visited);
return 1;
}
@@ -613,25 +672,39 @@ static int Pinfo_match(lua_State *L) {
Pinfo pinfo = checkPinfo(L,1);
if (!pinfo) return 0;
+ if (pinfo->expired) {
+ luaL_error(L,"expired_pinfo");
+ return 0;
+ }
- if (pinfo->match_string) {
- lua_pushstring(L,pinfo->match_string);
+ if (pinfo->ws_pinfo->match_string) {
+ lua_pushstring(L,pinfo->ws_pinfo->match_string);
} else {
- lua_pushnumber(L,(lua_Number)(pinfo->match_port));
+ lua_pushnumber(L,(lua_Number)(pinfo->ws_pinfo->match_port));
}
return 1;
}
static int Pinfo_columns(lua_State *L) {
+ Columns cols = NULL;
Pinfo pinfo = checkPinfo(L,1);
const gchar* colname = luaL_optstring(L,2,NULL);
+ if (pinfo->expired) {
+ luaL_error(L,"expired_pinfo");
+ return 0;
+ }
+
+ cols = g_malloc(sizeof(struct _wslua_cols));
+ cols->cinfo = pinfo->ws_pinfo->cinfo;
+ cols->expired = FALSE;
+
if (!colname) {
- PUSH_COLUMNS(L,pinfo->cinfo);
+ PUSH_COLUMNS(L,cols);
} else {
lua_settop(L,0);
- PUSH_COLUMNS(L,pinfo->cinfo);
+ PUSH_COLUMNS(L,cols);
lua_pushstring(L,colname);
return Columns_index(L);
}
@@ -666,6 +739,11 @@ int Pinfo_set_addr(lua_State* L, packet_info* pinfo, pinfo_param_type_t pt) {
luaL_error(L,"Not an OK address");
return 0;
}
+
+ if (!pinfo) {
+ luaL_error(L,"expired_pinfo");
+ return 0;
+ }
switch(pt) {
case PARAM_ADDR_SRC:
@@ -698,6 +776,11 @@ int Pinfo_set_addr(lua_State* L, packet_info* pinfo, pinfo_param_type_t pt) {
int Pinfo_set_int(lua_State* L, packet_info* pinfo, pinfo_param_type_t pt) {
guint v = luaL_checkint(L,1);
+ if (!pinfo) {
+ luaL_error(L,"expired_pinfo");
+ return 0;
+ }
+
switch(pt) {
case PARAM_PORT_SRC:
pinfo->srcport = v;
@@ -727,11 +810,15 @@ static int Pinfo_hi(lua_State *L) {
Address addr = g_malloc(sizeof(address));
if (!pinfo) return 0;
+ if (pinfo->expired) {
+ luaL_error(L,"expired_pinfo");
+ return 0;
+ }
- if (CMP_ADDRESS(&(pinfo->src), &(pinfo->dst) ) >= 0) {
- COPY_ADDRESS(addr, &(pinfo->src));
+ if (CMP_ADDRESS(&(pinfo->ws_pinfo->src), &(pinfo->ws_pinfo->dst) ) >= 0) {
+ COPY_ADDRESS(addr, &(pinfo->ws_pinfo->src));
} else {
- COPY_ADDRESS(addr, &(pinfo->dst));
+ COPY_ADDRESS(addr, &(pinfo->ws_pinfo->dst));
}
pushAddress(L,addr);
@@ -743,11 +830,15 @@ static int Pinfo_lo(lua_State *L) {
Address addr = g_malloc(sizeof(address));
if (!pinfo) return 0;
+ if (pinfo->expired) {
+ luaL_error(L,"expired_pinfo");
+ return 0;
+ }
- if (CMP_ADDRESS(&(pinfo->src), &(pinfo->dst) ) < 0) {
- COPY_ADDRESS(addr, &(pinfo->src));
+ if (CMP_ADDRESS(&(pinfo->ws_pinfo->src), &(pinfo->ws_pinfo->dst) ) < 0) {
+ COPY_ADDRESS(addr, &(pinfo->ws_pinfo->src));
} else {
- COPY_ADDRESS(addr, &(pinfo->dst));
+ COPY_ADDRESS(addr, &(pinfo->ws_pinfo->dst));
}
pushAddress(L,addr);
@@ -851,6 +942,10 @@ static int Pinfo_index(lua_State* L) {
lua_pushnil(L);
return 1;
}
+ if (pinfo->expired) {
+ luaL_error(L,"expired_pinfo");
+ return 0;
+ }
for (curr = Pinfo_methods ; curr->name ; curr++) {
if (g_str_equal(curr->name,name)) {
@@ -873,6 +968,10 @@ static int Pinfo_setindex(lua_State* L) {
if (! (pinfo && name) ) {
return 0;
}
+ if (pinfo->expired) {
+ luaL_error(L,"expired_pinfo");
+ return 0;
+ }
for (curr = Pinfo_methods ; curr->name ; curr++) {
if (g_str_equal(curr->name,name)) {
@@ -884,19 +983,36 @@ static int Pinfo_setindex(lua_State* L) {
lua_remove(L,1);
lua_remove(L,1);
- return method(L,pinfo,param_type);
+ return method(L,pinfo->ws_pinfo,param_type);
+}
+
+WSLUA_METAMETHOD Pinfo_gc(lua_State* L) {
+ Pinfo pinfo = checkPinfo(L,1);
+
+ if (!pinfo) return 0;
+
+ if (!pinfo->expired)
+ pinfo->expired = TRUE;
+ else
+ g_free(pinfo);
+
+ return 0;
+
}
static const luaL_reg Pinfo_meta[] = {
{"__index", Pinfo_index},
{"__newindex",Pinfo_setindex},
{"__tostring", Pinfo_tostring},
+ {"__gc", Pinfo_gc},
{ NULL, NULL }
};
int Pinfo_register(lua_State* L) {
WSLUA_REGISTER_META(Pinfo);
- outstanding_stuff = g_ptr_array_new();
+ outstanding_Pinfo = g_ptr_array_new();
+ outstanding_Column = g_ptr_array_new();
+ outstanding_Columns = g_ptr_array_new();
return 1;
}