From 941cb34b52c879ffeb2ec3959bef17b147268285 Mon Sep 17 00:00:00 2001 From: ai4rei Date: Sun, 16 Jan 2011 12:51:27 +0000 Subject: * Fixed a map-server crash, when a script attempts to call a local function, which has only a forward declaration. Such functions now count as script parse error (bugreport:4009, since r3422). * Fixed definitions of local functions would set a label reference, even when their name was already taken (follow up to r14600, since r3422). git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@14675 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 3 +++ src/map/script.c | 31 ++++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 78b569324..8df6776a7 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -1,5 +1,8 @@ Date Added +2011/01/16 + * Fixed a map-server crash, when a script attempts to call a local function, which has only a forward declaration. Such functions now count as script parse error (bugreport:4009, since r3422). [Ai4rei] + * Fixed definitions of local functions would set a label reference, even when their name was already taken (follow up to r14600, since r3422). 2011/01/15 * Various accumulated insignificant fixes to documentation, examples and comments. [Ai4rei] 2011/01/14 diff --git a/src/map/script.c b/src/map/script.c index ed1e13aee..f842b614a 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -70,6 +70,7 @@ // - remove dynamic allocation in add_word() // - remove GETVALUE / SETVALUE // - clean up the set_reg / set_val / setd_sub mess +// - detect invalid label references at parse-time // // struct script_state* st; @@ -1558,8 +1559,12 @@ const char* parse_syntax(const char* p) // function declaration - just register the name int l; l = add_word(func_name); - if( str_data[l].type == C_NOP )// set type only if the name did not exist before + if( str_data[l].type == C_NOP )// register only, if the name was not used by something else str_data[l].type = C_USERFUNC; + else if( str_data[l].type == C_USERFUNC ) + ; // already registered + else + disp_error_message("parse_syntax:function: function name is invalid", func_name); // if, for , while ‚̕‚¶”»’è p = parse_syntax_close(p2 + 1); @@ -1585,11 +1590,16 @@ const char* parse_syntax(const char* p) // Set the position of the function (label) l=add_word(func_name); - if( str_data[l].type == C_NOP )// set type only if the name did not exist before + if( str_data[l].type == C_NOP || str_data[l].type == C_USERFUNC )// register only, if the name was not used by something else + { str_data[l].type = C_USERFUNC; - set_label(l, script_pos, p); - if( parse_options&SCRIPT_USE_LABEL_DB ) - strdb_put(scriptlabel_db, get_str(l), (void*)script_pos); + set_label(l, script_pos, p); + if( parse_options&SCRIPT_USE_LABEL_DB ) + strdb_put(scriptlabel_db, get_str(l), (void*)script_pos); + } + else + disp_error_message("parse_syntax:function: function name is invalid", func_name); + return skip_space(p); } else @@ -2006,6 +2016,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o struct script_code* code = NULL; static int first=1; char end; + bool unresolved_names = false; if( src == NULL ) return NULL;// empty script @@ -2129,6 +2140,16 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o j=next; } } + else if( str_data[i].type == C_USERFUNC ) + {// 'function name;' without follow-up code + ShowError("parse_script: function '%s' declared but not defined.\n", str_buf+str_data[i].str); + unresolved_names = true; + } + } + + if( unresolved_names ) + { + disp_error_message("parse_script: unresolved function references", p); } #ifdef DEBUG_DISP -- cgit v1.2.3-60-g2f50