Parcourir la source

Fixes a potential map-server crash by skill units (#6226)

Fixes #6224.
Restart the iterator if a skill unit is deleted when trying to clear previous grouped unit skills.
Thanks to @technoken!

Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
Aleos il y a 3 ans
Parent
commit
bccbf8b166
2 fichiers modifiés avec 11 ajouts et 5 suppressions
  1. 10 4
      src/map/skill.cpp
  2. 1 1
      src/map/skill.hpp

+ 10 - 4
src/map/skill.cpp

@@ -17862,10 +17862,10 @@ int skill_attack_area(struct block_list *bl, va_list ap)
 
 /**
  * Clear skill unit group
- * @param bl
- * @param flag &1
+ * @param bl: Unit to check
+ * @param flag: Skill group to clear
  */
-int skill_clear_group(struct block_list *bl, int flag)
+int skill_clear_group(block_list *bl, uint8 flag)
 {
 	nullpo_ret(bl);
 
@@ -17875,8 +17875,10 @@ int skill_clear_group(struct block_list *bl, int flag)
 		return 0;
 
 	size_t count = 0;
+	bool deleted;
 
-	for (auto it = ud->skillunits.begin(); it != ud->skillunits.end(); it++) {
+	// The after loop statement might look stupid, but this prevents iteration problems, if an entry was deleted
+	for (auto it = ud->skillunits.begin(); it != ud->skillunits.end(); (deleted ? it = ud->skillunits.begin() : it++), deleted = false) {
 		switch ((*it)->skill_id) {
 			case SA_DELUGE:
 			case SA_VOLCANO:
@@ -17890,6 +17892,7 @@ int skill_clear_group(struct block_list *bl, int flag)
 				if (flag & 1) {
 					skill_delunitgroup(*it);
 					count++;
+					deleted = true;
 				}
 				break;
 			case SO_CLOUD_KILL:
@@ -17897,18 +17900,21 @@ int skill_clear_group(struct block_list *bl, int flag)
 				if (flag & 4) {
 					skill_delunitgroup(*it);
 					count++;
+					deleted = true;
 				}
 				break;
 			case SO_WARMER:
 				if (flag & 8) {
 					skill_delunitgroup(*it);
 					count++;
+					deleted = true;
 				}
 				break;
 			default:
 				if (flag & 2 && skill_get_inf2((*it)->skill_id, INF2_ISTRAP)) {
 					skill_delunitgroup(*it);
 					count++;
+					deleted = true;
 				}
 				break;
 		}

+ 1 - 1
src/map/skill.hpp

@@ -568,7 +568,7 @@ std::shared_ptr<s_skill_unit_group> skill_initunitgroup(struct block_list* src,
 int skill_delunitgroup_(std::shared_ptr<s_skill_unit_group> group, const char* file, int line, const char* func);
 #define skill_delunitgroup(group) skill_delunitgroup_(group,__FILE__,__LINE__,__func__)
 void skill_clear_unitgroup(struct block_list *src);
-int skill_clear_group(struct block_list *bl, int flag);
+int skill_clear_group(block_list *bl, uint8 flag);
 void ext_skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, t_tick tick);
 int64 skill_unit_ondamaged(struct skill_unit *unit,int64 damage);