Explorar o código

- Fixed dangling pointer crashes when bleeding or Deadly poison kills a spawn-once monster.
- Fixed a possible ERS entry corruption when Deadly Poison kills a target that has kaziel active.


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

skotlex %!s(int64=17) %!d(string=hai) anos
pai
achega
fb100b2f09
Modificáronse 2 ficheiros con 17 adicións e 5 borrados
  1. 6 0
      Changelog-Trunk.txt
  2. 11 5
      src/map/status.c

+ 6 - 0
Changelog-Trunk.txt

@@ -3,6 +3,12 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
+
+2008/01/14
+	* Fixed dangling pointer crashes when bleeding or Deadly poison kills a
+	  spawn-once monster.
+	* Fixed a possible ERS entry corruption when Deadly Poison kills a target
+	  that has kaziel active.
 2008/01/13
 	* Fixed a possible ers_entry corruption if you die from bleeding while
 	  under the effects of kaizel.

+ 11 - 5
src/map/status.c

@@ -6788,9 +6788,12 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
 	case SC_DPOISON:
 		if (--(sce->val3) > 0) {
 			if (!sc->data[SC_SLOWPOISON]) {
+				bool flag;
+				map_freeblock_lock();
 				status_zap(bl, sce->val4, 0);
-				if (status_isdead(bl))
-					break;
+				flag = sc->data[type]; //We check for this rather than 'killed' since the target could have revived with kaizel.
+				map_freeblock_unlock();
+				if (!flag) return 0; //target died, SC cancelled already.
 			}
 			sc_timer_next(1000 + tick, status_change_timer, bl->id, data );
 			return 0;
@@ -6806,10 +6809,13 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
 
 	case SC_BLEEDING:
 		if (--(sce->val4) >= 0) {
+			int flag;
+			map_freeblock_lock();
 			status_fix_damage(NULL, bl, rand()%600 + 200, 0);
-			if (status_isdead(bl) || !sc->data[type]) //It is possible you revived from kaizel if killed.
-				break;
-			sc_timer_next(10000 + tick, status_change_timer, bl->id, data ); 
+			flag = sc->data[type];
+			map_freeblock_unlock();
+			if (!flag) return 0; //SC already ended.
+			sc_timer_next(10000 + tick, status_change_timer, bl->id, data); 
 			return 0;
 		}
 		break;