From f09707bb9ea08e32d849ae2019d16cd7e14606a7 Mon Sep 17 00:00:00 2001 From: FlavioJS Date: Wed, 23 Apr 2008 11:14:45 +0000 Subject: * Fixed script strings not being handled properly (only skipped the \). * Added skip_escaped_c to strlib.c/h. * Fixed sv_unescape_c not handling hex/octal escapes properly. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@12639 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 3 +++ src/common/strlib.c | 43 ++++++++++++++++++++++++++++++++++++++----- src/common/strlib.h | 3 +++ src/map/script.c | 11 ++++++++++- 4 files changed, 54 insertions(+), 6 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index eb3f551ba..2bb321461 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,9 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2008/04/23 + * Fixed script strings not being handled properly (only skipped the \). + * Added skip_escaped_c to strlib.c/h. + * Fixed sv_unescape_c not handling hex/octal escapes properly. * Script parse errors displayed with one ShowError instead of several ShowMessage's. [FlavioJS] 2008/04/22 * Changed itemdb_reload to clear the database before reloading, so it is possible diff --git a/src/common/strlib.c b/src/common/strlib.c index b6ff4b279..88de59cb9 100644 --- a/src/common/strlib.c +++ b/src/common/strlib.c @@ -740,20 +740,21 @@ size_t sv_unescape_c(char* out_dest, const char* src, size_t len) ShowWarning("sv_unescape_c: hex escape sequence out of range\n"); inrange = 0; } - c = (c<<8)|low2hex[(unsigned char)src[i++]];// hex digit - }while( i >= len || !ISXDIGIT(src[i]) ); + c = (c<<4)|low2hex[(unsigned char)src[i]];// hex digit + ++i; + }while( i < len && ISXDIGIT(src[i]) ); out_dest[j++] = (char)c; } else if( src[i] == '0' || src[i] == '1' || src[i] == '2' || src[i] == '3' ) {// octal escape sequence (255=0377) unsigned char c = src[i]-'0'; ++i;// '0', '1', '2' or '3' - if( i < len && src[i] >= '0' && src[i] <= '9' ) + if( i < len && src[i] >= '0' && src[i] <= '7' ) { c = (c<<3)|(src[i]-'0'); ++i;// octal digit } - if( i < len && src[i] >= '0' && src[i] <= '9' ) + if( i < len && src[i] >= '0' && src[i] <= '7' ) { c = (c<<3)|(src[i]-'0'); ++i;// octal digit @@ -763,7 +764,7 @@ size_t sv_unescape_c(char* out_dest, const char* src, size_t len) else {// other escape sequence if( strchr(SV_ESCAPE_C_SUPPORTED, src[i]) == NULL ) - ShowWarning("sv_parse: unknown escape sequence \\%c\n", src[i]); + ShowWarning("sv_unescape_c: unknown escape sequence \\%c\n", src[i]); switch( src[i] ) { case 'a': out_dest[j++] = '\a'; break; @@ -786,6 +787,38 @@ size_t sv_unescape_c(char* out_dest, const char* src, size_t len) return j; } +/// Skips a C escape sequence (starting with '\\'). +const char* skip_escaped_c(const char* p) +{ + if( p && *p == '\\' ) + { + ++p; + switch( *p ) + { + case 'x':// hexadecimal + ++p; + while( ISXDIGIT(*p) ) + ++p; + break; + case '0': + case '1': + case '2': + case '3':// octal + ++p; + if( *p >= '0' && *p <= '7' ) + ++p; + if( *p >= '0' && *p <= '7' ) + ++p; + break; + default: + if( *p && strchr(SV_ESCAPE_C_SUPPORTED, *p) ) + ++p; + } + } + return p; +} + + /// Opens and parses a file containing delim-separated columns, feeding them to the specified callback function row by row. /// Tracks the progress of the operation (current line number, number of successfully processed rows). /// Returns 'true' if it was able to process the specified file, or 'false' if it could not be read. diff --git a/src/common/strlib.h b/src/common/strlib.h index 3c4075902..074c7eae3 100644 --- a/src/common/strlib.h +++ b/src/common/strlib.h @@ -91,6 +91,9 @@ size_t sv_escape_c(char* out_dest, const char* src, size_t len, const char* esca /// out_dest should be len+1 in size and can be the same buffer as src. size_t sv_unescape_c(char* out_dest, const char* src, size_t len); +/// Skips a C escape sequence (starting with '\\'). +const char* skip_escaped_c(const char* p); + /// Opens and parses a file containing delim-separated columns, feeding them to the specified callback function row by row. /// Tracks the progress of the operation (current line number, number of successfully processed rows). /// Returns 'true' if it was able to process the specified file, or 'false' if it could not be read. diff --git a/src/map/script.c b/src/map/script.c index 236bcf71e..6c2f30c55 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -921,7 +921,16 @@ const char* parse_simpleexpr(const char *p) p++; while( *p && *p != '"' ){ if( (unsigned char)p[-1] <= 0x7e && *p == '\\' ) - p++; + { + char buf[8]; + size_t len = skip_escaped_c(p) - p; + size_t n = sv_unescape_c(buf, p, len); + if( n != 1 ) + ShowDebug("parse_simpleexpr: unexpected length %d after unescape (\"%.*s\" -> %.*s)\n", (int)n, (int)len, p, (int)n, buf); + p += len; + add_scriptb(*buf); + continue; + } else if( *p == '\n' ) disp_error_message("parse_simpleexpr: unexpected newline @ string",p); add_scriptb(*p++); -- cgit v1.2.3-70-g09d2