Corrected a few potential crash points (#3874)

* Fixes #3872.
* Added a couple more map data validity checks on block list counting functions.
* QD Shot should no longer remove the read status.
* Dragon Trail should no longer end the Crimson Marker status.
* Some other minor optimizations/cleanups.
* Fixed a va_arg corruption
Thanks to @attackjom, @Lemongrass3110, and @teededung!
This commit is contained in:
Aleos 2019-01-23 20:27:41 -05:00 committed by GitHub
parent a9f868f85f
commit 6c86492764
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 13 deletions

View File

@ -625,6 +625,10 @@ int map_foreachinrangeV(int (*func)(struct block_list*,va_list),struct block_lis
struct map_data *mapdata = map_getmapdata(m);
if( mapdata == nullptr || mapdata->block == nullptr ){
return 0;
}
x0 = i16max(center->x - range, 0);
y0 = i16max(center->y - range, 0);
x1 = i16min(center->x + range, mapdata->xs - 1);
@ -744,7 +748,6 @@ int map_foreachinareaV(int(*func)(struct block_list*, va_list), int16 m, int16 x
struct map_data *mapdata = map_getmapdata(m);
// Required for delayed monster removal in instances
if( mapdata == nullptr || mapdata->block == nullptr ){
return 0;
}
@ -849,6 +852,11 @@ int map_forcountinrange(int (*func)(struct block_list*,va_list), struct block_li
m = center->m;
mapdata = map_getmapdata(m);
if( mapdata == nullptr || mapdata->block == nullptr ){
return 0;
}
x0 = i16max(center->x - range, 0);
y0 = i16max(center->y - range, 0);
x1 = i16min(center->x + range, mapdata->xs - 1);
@ -919,6 +927,10 @@ int map_forcountinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x
struct map_data *mapdata = map_getmapdata(m);
if( mapdata == nullptr || mapdata->block == nullptr ){
return 0;
}
x0 = i16max(x0, 0);
y0 = i16max(y0, 0);
x1 = i16min(x1, mapdata->xs - 1);
@ -978,6 +990,10 @@ int map_foreachinmovearea(int (*func)(struct block_list*,va_list), struct block_
struct map_data *mapdata = map_getmapdata(m);
if( mapdata == nullptr || mapdata->block == nullptr ){
return 0;
}
x0 = center->x - range;
x1 = center->x + range;
y0 = center->y - range;
@ -1097,6 +1113,10 @@ int map_foreachincell(int (*func)(struct block_list*,va_list), int16 m, int16 x,
struct map_data *mapdata = map_getmapdata(m);
va_list ap;
if( mapdata == nullptr || mapdata->block == nullptr ){
return 0;
}
if ( x < 0 || y < 0 || x >= mapdata->xs || y >= mapdata->ys ) return 0;
by = y / BLOCK_SIZE;
@ -1219,6 +1239,10 @@ int map_foreachinpath(int (*func)(struct block_list*,va_list),int16 m,int16 x0,i
struct map_data *mapdata = map_getmapdata(m);
if( mapdata == nullptr || mapdata->block == nullptr ){
return 0;
}
mx0 = max(mx0, 0);
my0 = max(my0, 0);
mx1 = min(mx1, mapdata->xs - 1);
@ -1359,6 +1383,10 @@ int map_foreachindir(int(*func)(struct block_list*, va_list), int16 m, int16 x0,
struct map_data *mapdata = map_getmapdata(m);
if( mapdata == nullptr || mapdata->block == nullptr ){
return 0;
}
//Get area that needs to be checked
mx0 = x0 + dx*(offset / ((dir % 2) + 1));
my0 = y0 + dy*(offset / ((dir % 2) + 1));
@ -1483,6 +1511,10 @@ int map_foreachinmap(int (*func)(struct block_list*,va_list), int16 m, int type,
struct map_data *mapdata = map_getmapdata(m);
va_list ap;
if( mapdata == nullptr || mapdata->block == nullptr ){
return 0;
}
bsize = mapdata->bxs * mapdata->bys;
if( type&~BL_MOB )
@ -1595,6 +1627,10 @@ int map_searchrandfreecell(int16 m,int16 *x,int16 *y,int stack) {
int free_cells[9][2];
struct map_data *mapdata = map_getmapdata(m);
if( mapdata == nullptr || mapdata->block == nullptr ){
return 0;
}
for(free_cell=0,i=-1;i<=1;i++){
if(i+*y<0 || i+*y>=mapdata->ys)
continue;
@ -1666,6 +1702,10 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1
struct map_data *mapdata = map_getmapdata(m);
if( mapdata == nullptr || mapdata->block == nullptr ){
return 0;
}
if (rx >= 0 && ry >= 0) {
tries = rx2*ry2;
if (tries > 100) tries = 100;

View File

@ -6053,18 +6053,11 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case RL_QD_SHOT:
if (sd)
status_change_end(&sd->bl, SC_QD_SHOT_READY, INVALID_TIMER);
case RL_D_TAIL:
if (!sd || (sd && tsc && tsc->data[SC_C_MARKER])) {
int sflag = flag;
if (!sd || (tsc && tsc->data[SC_C_MARKER])) {
if (skill_id == RL_QD_SHOT && skill_area_temp[1] == bl->id )
break;
if (flag&1)
sflag = (skill_area_temp[0]&0xFFF)|(flag&SD_LEVEL ? SD_LEVEL : 0)|(flag&SD_ANIMATION ? SD_ANIMATION : 0);
skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, sflag);
if (sd && skill_id == RL_D_TAIL)
status_change_end(bl, SC_C_MARKER, INVALID_TIMER);
skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag|SD_ANIMATION);
}
break;
@ -10847,7 +10840,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
break;
case RL_D_TAIL:
map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|SD_ANIMATION|1, skill_castend_damage_id);
map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
break;
case RL_QD_SHOT:
if (sd) {
@ -11153,9 +11146,9 @@ static int8 skill_castend_id_check(struct block_list *src, struct block_list *ta
int count = 0;
if (battle_config.skill_wall_check)
count = map_foreachinshootrange(skill_area_sub, src, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, 0, BCT_ENEMY, skill_area_sub_count);
count = map_foreachinshootrange(skill_area_sub, src, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, gettick(), BCT_ENEMY, skill_area_sub_count);
else
count = map_foreachinrange(skill_area_sub, src, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, 0, BCT_ENEMY, skill_area_sub_count);
count = map_foreachinrange(skill_area_sub, src, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, gettick(), BCT_ENEMY, skill_area_sub_count);
if (!count) {
return USESKILL_FAIL_LEVEL;