Lua: Validate Proto() arguments

Check if description (protocol name) and short_name are used before
registering the protocol.  This because proto_register_protocol() makes
sure there's not already a protocol with any of the names registered
and duplicates will be reported with a g_error() which terminates the
Wireshark unexpectedly.

Also check if short_name contains valid characters.

Give appropriate error messages.

Bug: 11739
Change-Id: Ib9776a2a3406ae5278ce744defd61864ebed0282
Reviewed-on: https://code.wireshark.org/review/11995
Reviewed-by: Stig Bjørlykke <stig@bjorlykke.org>
This commit is contained in:
Stig Bjørlykke 2015-11-20 18:56:45 +01:00
parent 23258fb841
commit 94b9907d0f
4 changed files with 36 additions and 6 deletions

View File

@ -989,6 +989,7 @@ libwireshark.so.0 libwireshark0 #MINVER#
proto_item_set_end@Base 1.9.1
proto_item_set_len@Base 1.9.1
proto_item_set_text@Base 1.9.1
proto_name_already_registered@Base 2.0.1
proto_register_field_array@Base 1.9.1
proto_register_fields_manual@Base 1.12.0~rc1
proto_register_fields_section@Base 1.12.0~rc1

View File

@ -5508,6 +5508,19 @@ proto_get_id(const protocol_t *protocol)
return protocol->proto_id;
}
gboolean
proto_name_already_registered(const gchar *name)
{
gint key;
DISSECTOR_ASSERT_HINT(name, "No name present");
key = wrs_str_hash(name);
if (g_hash_table_lookup(proto_names, &key) != NULL)
return TRUE;
return FALSE;
}
int
proto_get_id_by_filter_name(const gchar *filter_name)
{

View File

@ -2116,6 +2116,11 @@ WS_DLL_PUBLIC int proto_get_next_protocol(void **cookie);
WS_DLL_PUBLIC header_field_info *proto_get_first_protocol_field(const int proto_id, void **cookie);
WS_DLL_PUBLIC header_field_info *proto_get_next_protocol_field(const int proto_id, void **cookie);
/** Check if a protocol name is already registered.
@param name the name to search for
@return proto_id */
WS_DLL_PUBLIC int proto_name_already_registered(const gchar *name);
/** Given a protocol's filter_name.
@param filter_name the filter name to search for
@return proto_id */

View File

@ -93,7 +93,6 @@ WSLUA_CONSTRUCTOR Proto_new(lua_State* L) {
const gchar* desc = luaL_checkstring(L,WSLUA_ARG_Proto_new_DESC);
Proto proto;
gchar *loname, *hiname;
int proto_id;
/* TODO: should really make a common function for all of wslua that does checkstring and non-empty at same time */
if (!name[0]) {
@ -106,17 +105,29 @@ WSLUA_CONSTRUCTOR Proto_new(lua_State* L) {
return 0;
}
loname = g_ascii_strdown(name, -1);
proto_id = proto_get_id_by_filter_name(loname);
if (proto_name_already_registered(desc)) {
WSLUA_ARG_ERROR(Proto_new,DESC,"there cannot be two protocols with the same description");
return 0;
}
if (proto_id > 0) {
WSLUA_ARG_ERROR(Proto_new,NAME,"there cannot be two protocols with the same name");
loname = g_ascii_strdown(name, -1);
if (proto_check_field_name(loname)) {
WSLUA_ARG_ERROR(Proto_new,NAME,"invalid character in name");
g_free(loname);
return 0;
}
proto = (wslua_proto_t *)g_malloc(sizeof(wslua_proto_t));
hiname = g_ascii_strup(name, -1);
if ((proto_get_id_by_short_name(hiname) != -1) ||
(proto_get_id_by_filter_name(loname) != -1))
{
WSLUA_ARG_ERROR(Proto_new,NAME,"there cannot be two protocols with the same name");
g_free(loname);
g_free(hiname);
return 0;
}
proto = (wslua_proto_t *)g_malloc(sizeof(wslua_proto_t));
proto->name = hiname;
proto->loname = loname;