From 94b9907d0f32fe4d570d94b820b20b6906a21499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stig=20Bj=C3=B8rlykke?= Date: Fri, 20 Nov 2015 18:56:45 +0100 Subject: [PATCH] Lua: Validate Proto() arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- debian/libwireshark0.symbols | 1 + epan/proto.c | 13 +++++++++++++ epan/proto.h | 5 +++++ epan/wslua/wslua_proto.c | 23 +++++++++++++++++------ 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/debian/libwireshark0.symbols b/debian/libwireshark0.symbols index 6a3cdb5565..e52ed0d3a0 100644 --- a/debian/libwireshark0.symbols +++ b/debian/libwireshark0.symbols @@ -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 diff --git a/epan/proto.c b/epan/proto.c index 8ef138d959..0fe4b320c7 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -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) { diff --git a/epan/proto.h b/epan/proto.h index 2e8f30c24e..6010e6c593 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -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 */ diff --git a/epan/wslua/wslua_proto.c b/epan/wslua/wslua_proto.c index 4cfe734683..8721b451c7 100644 --- a/epan/wslua/wslua_proto.c +++ b/epan/wslua/wslua_proto.c @@ -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;