From e8af4bb64be4594cf6ece1b9f05825240107dee1 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Fri, 3 Aug 2012 15:38:55 +0000 Subject: Fixed bugreport:6402 when a menu supersedes the client's maximum length it is truncated and a warning is displayed on console, special thanks to Vianna for providing us with the proper length. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16568 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/script.c | 68 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 17 deletions(-) diff --git a/src/map/script.c b/src/map/script.c index 7d0d9df74..4b8afdb24 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -4261,7 +4261,21 @@ BUILDIN_FUNC(menu) } st->state = RERUNLINE; sd->state.menu_or_input = 1; - clif_scriptmenu(sd, st->oid, StringBuf_Value(&buf)); + + /** + * menus beyond this length crash the client (see bugreport:6402) + **/ + if( StringBuf_Length(&buf) >= 2047 ) { + struct npc_data * nd = map_id2nd(st->oid); + char* menu; + CREATE(menu, char, 2048); + safestrncpy(menu, StringBuf_Value(&buf), 2047); + ShowWarning("NPC Menu too long! (source:%s / length:%d)\n",nd?nd->name:"Unknown",StringBuf_Length(&buf)); + clif_scriptmenu(sd, st->oid, menu); + aFree(menu); + } else + clif_scriptmenu(sd, st->oid, StringBuf_Value(&buf)); + StringBuf_Destroy(&buf); if( sd->npc_menu >= 0xff ) @@ -4331,44 +4345,51 @@ BUILDIN_FUNC(select) if( sd == NULL ) return 0; - if( sd->state.menu_or_input == 0 ) - { + if( sd->state.menu_or_input == 0 ) { struct StringBuf buf; StringBuf_Init(&buf); sd->npc_menu = 0; - for( i = 2; i <= script_lastdata(st); ++i ) - { + for( i = 2; i <= script_lastdata(st); ++i ) { text = script_getstr(st, i); + if( sd->npc_menu > 0 ) StringBuf_AppendStr(&buf, ":"); + StringBuf_AppendStr(&buf, text); sd->npc_menu += menu_countoptions(text, 0, NULL); } st->state = RERUNLINE; sd->state.menu_or_input = 1; - clif_scriptmenu(sd, st->oid, StringBuf_Value(&buf)); + + /** + * menus beyond this length crash the client (see bugreport:6402) + **/ + if( StringBuf_Length(&buf) >= 2047 ) { + struct npc_data * nd = map_id2nd(st->oid); + char* menu; + CREATE(menu, char, 2048); + safestrncpy(menu, StringBuf_Value(&buf), 2047); + ShowWarning("NPC Menu too long! (source:%s / length:%d)\n",nd?nd->name:"Unknown",StringBuf_Length(&buf)); + clif_scriptmenu(sd, st->oid, menu); + aFree(menu); + } else + clif_scriptmenu(sd, st->oid, StringBuf_Value(&buf)); StringBuf_Destroy(&buf); - if( sd->npc_menu >= 0xff ) - { + if( sd->npc_menu >= 0xff ) { ShowWarning("buildin_select: Too many options specified (current=%d, max=254).\n", sd->npc_menu); script_reportsrc(st); } - } - else if( sd->npc_menu == 0xff ) - {// Cancel was pressed + } else if( sd->npc_menu == 0xff ) {// Cancel was pressed sd->state.menu_or_input = 0; st->state = END; - } - else - {// return selected option + } else {// return selected option int menu = 0; sd->state.menu_or_input = 0; - for( i = 2; i <= script_lastdata(st); ++i ) - { + for( i = 2; i <= script_lastdata(st); ++i ) { text = script_getstr(st, i); sd->npc_menu -= menu_countoptions(text, sd->npc_menu, &menu); if( sd->npc_menu <= 0 ) @@ -4416,7 +4437,20 @@ BUILDIN_FUNC(prompt) st->state = RERUNLINE; sd->state.menu_or_input = 1; - clif_scriptmenu(sd, st->oid, StringBuf_Value(&buf)); + + /** + * menus beyond this length crash the client (see bugreport:6402) + **/ + if( StringBuf_Length(&buf) >= 2047 ) { + struct npc_data * nd = map_id2nd(st->oid); + char* menu; + CREATE(menu, char, 2048); + safestrncpy(menu, StringBuf_Value(&buf), 2047); + ShowWarning("NPC Menu too long! (source:%s / length:%d)\n",nd?nd->name:"Unknown",StringBuf_Length(&buf)); + clif_scriptmenu(sd, st->oid, menu); + aFree(menu); + } else + clif_scriptmenu(sd, st->oid, StringBuf_Value(&buf)); StringBuf_Destroy(&buf); if( sd->npc_menu >= 0xff ) -- cgit v1.2.3-70-g09d2