Jelajahi Sumber

* 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://svn.code.sf.net/p/rathena/svn/trunk@12639 54d463be-8e91-2dee-dedb-b68131a5f0ec

FlavioJS 17 tahun lalu
induk
melakukan
2599064a46
4 mengubah file dengan 54 tambahan dan 6 penghapusan
  1. 3 0
      Changelog-Trunk.txt
  2. 38 5
      src/common/strlib.c
  3. 3 0
      src/common/strlib.h
  4. 10 1
      src/map/script.c

+ 3 - 0
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

+ 38 - 5
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.

+ 3 - 0
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.

+ 10 - 1
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++);