Browse Source

* Fixed itemdb_read_sqldb blowing up the server with segmentation faults.
* Added an option for parse_script to ignore the checks for the set of brackets around the script.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@11398 54d463be-8e91-2dee-dedb-b68131a5f0ec

FlavioJS 17 năm trước cách đây
mục cha
commit
faa553103c
5 tập tin đã thay đổi với 50 bổ sung48 xóa
  1. 3 0
      Changelog-Trunk.txt
  2. 16 34
      src/map/itemdb.c
  3. 1 1
      src/map/map.c
  4. 28 12
      src/map/script.c
  5. 2 1
      src/map/script.h

+ 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.
 
 2007/10/10
+	* Fixed itemdb_read_sqldb blowing up the server with segmentation faults.
+	* Added an option for parse_script to ignore the checks for the set of 
+	  brackets around the script. [FlavioJS]
 	* Removed 'into_abyss' effect on traps; tests show that it works ONLY
 	  for Gemstones (tho' iRO website claims otherwise) - bugreport:171
 	- corrected code that was exploiting the flag as an 'expired' trap flag

+ 16 - 34
src/map/itemdb.c

@@ -696,7 +696,7 @@ static int itemdb_gendercheck(struct item_data *id)
 /*==========================================
  * processes one itemdb entry
  *------------------------------------------*/
-static bool itemdb_parse_dbrow(const char** str, const char* source, int line)
+static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt)
 {
 	/*
 		+----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
@@ -785,11 +785,11 @@ static bool itemdb_parse_dbrow(const char** str, const char* source, int line)
 	}
 
 	if (*str[19])
-		id->script = parse_script(str[19], source, line, 0);
+		id->script = parse_script(str[19], source, line, scriptopt);
 	if (*str[20])
-		id->equip_script = parse_script(str[20], source, line, 0);
+		id->equip_script = parse_script(str[20], source, line, scriptopt);
 	if (*str[21])
-		id->unequip_script = parse_script(str[21], source, line, 0);
+		id->unequip_script = parse_script(str[21], source, line, scriptopt);
 
 	return true;
 }
@@ -891,7 +891,7 @@ static int itemdb_readdb(void)
 			str[21] = p;
 
 
-			if (!itemdb_parse_dbrow(str, path, lines))
+			if (!itemdb_parse_dbrow(str, path, lines, 0))
 				continue;
 
 			count++;
@@ -917,49 +917,31 @@ static int itemdb_read_sqldb(void)
 	for( fi = 0; fi < ARRAYLENGTH(item_db_name); ++fi )
 	{
 		uint32 lines = 0, count = 0;
-		
+
 		// retrieve all rows from the item database
 		if( SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", item_db_name[fi]) )
 		{
 			Sql_ShowDebug(mmysql_handle);
 			continue;
 		}
-		
+
 		// process rows one by one
 		while( SQL_SUCCESS == Sql_NextRow(mmysql_handle) )
-		{
-			// wrap the result into a TXT-compatible format
-			char line[1024];
+		{// wrap the result into a TXT-compatible format
 			char* str[22];
-			char* p;
 			int i;
-			
-			lines++;
-			for (i = 0, p = line; i < 22; i++)
-			{
-				char* data;
-				size_t len;
-				Sql_GetData(mmysql_handle, i, &data, &len);
-				
-				if (data == NULL)
-					p[0] = '\0';
-				else if (i >= 19 && data[0] != '{') {
-					sprintf(p, "{ %s }", data); len+= 4;
-				} else
-					strcpy(p, data);
-				str[i] = p;
-				p+= len + 1;
-			}
-			
-			if (!itemdb_parse_dbrow(str, item_db_name[fi], lines))
+			++lines;
+			for( i = 0; i < 22; ++i )
+				Sql_GetData(mmysql_handle, i, &str[i], NULL);
+
+			if (!itemdb_parse_dbrow(str, item_db_name[fi], lines, 0))
 				continue;
-			
-			count++;
+			++count;
 		}
-		
+
 		// free the query result
 		Sql_FreeResult(mmysql_handle);
-		
+
 		ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, item_db_name[fi]);
 	}
 

+ 1 - 1
src/map/map.c

@@ -2607,7 +2607,7 @@ int map_readgat (struct map_data* m)
 int map_readallmaps (void)
 {
 	int i;
-	FILE* fp;
+	FILE* fp=NULL;
 	int maps_removed = 0;
 
 	if( enable_grf )

+ 28 - 12
src/map/script.c

@@ -1898,6 +1898,9 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
 	struct script_code *code;
 	static int first=1;
 
+	if( src == NULL )
+		return NULL;// empty script
+
 	memset(&syntax,0,sizeof(syntax));
 	if(first){
 		add_buildin_func();
@@ -1948,21 +1951,34 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
 	parse_syntax_for_flag=0;
 	p=src;
 	p=skip_space(p);
-	if(*p!='{'){
-		disp_error_message("not found '{'",p);
+	if( options&SCRIPT_IGNORE_EXTERNAL_BRACKETS )
+	{// does not require brackets around the script
+		if( *p == '\0' )
+		{// empty script
+			aFree( script_buf );
+			script_pos  = 0;
+			script_size = 0;
+			script_buf  = NULL;
+			return NULL;
+		}
 	}
-	p++;
-	p = skip_space(p);
-	if (p && *p == '}') {
-		// an empty function, just return  
-		aFree( script_buf );
-		script_pos  = 0;
-		script_size = 0;
-		script_buf  = NULL;
-		return NULL;
+	else
+	{// requires brackets around the script
+		if( *p != '{' )
+			disp_error_message("not found '{'",p);
+		p = skip_space(++p);
+		if( *p == '}' )
+		{// empty script
+			aFree( script_buf );
+			script_pos  = 0;
+			script_size = 0;
+			script_buf  = NULL;
+			return NULL;
+		}
 	}
 
-	while (p && *p && (*p!='}' || syntax.curly_count != 0)) {
+	while (*p && (*p != '}' || syntax.curly_count != 0) )
+	{
 		p=skip_space(p);
 		// label‚¾‚¯“ÁŽê�ˆ—�
 		tmpp=skip_space(skip_word(p));

+ 2 - 1
src/map/script.h

@@ -62,7 +62,8 @@ struct script_state {
 };
 
 enum script_parse_options {
-	SCRIPT_USE_LABEL_DB = 0x1
+	SCRIPT_USE_LABEL_DB = 0x1,// records labels in scriptlabel_db
+	SCRIPT_IGNORE_EXTERNAL_BRACKETS = 0x2// ignores the check for {} brackets around the script
 };
 
 struct script_code* parse_script(const char* src,const char* file,int line,int options);