diff options
author | FlavioJS <FlavioJS@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-04-23 11:14:45 +0000 |
---|---|---|
committer | FlavioJS <FlavioJS@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-04-23 11:14:45 +0000 |
commit | f09707bb9ea08e32d849ae2019d16cd7e14606a7 (patch) | |
tree | 0e081f4e99d4d99c9a2f96b5eade70924f7f65f9 /src | |
parent | 4e45ec34bb37eb515480cfc42dce7d7380a5e235 (diff) | |
download | hercules-f09707bb9ea08e32d849ae2019d16cd7e14606a7.tar.gz hercules-f09707bb9ea08e32d849ae2019d16cd7e14606a7.tar.bz2 hercules-f09707bb9ea08e32d849ae2019d16cd7e14606a7.tar.xz hercules-f09707bb9ea08e32d849ae2019d16cd7e14606a7.zip |
* 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
Diffstat (limited to 'src')
-rw-r--r-- | src/common/strlib.c | 43 | ||||
-rw-r--r-- | src/common/strlib.h | 3 | ||||
-rw-r--r-- | src/map/script.c | 11 |
3 files changed, 51 insertions, 6 deletions
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++); |