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>
This commit is contained in:
Aleos 2021-08-31 06:00:58 -04:00 committed by GitHub
parent fe7cb5a33f
commit bccbf8b166
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 5 deletions

View File

@ -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;
}

View File

@ -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);