PDA

Просмотр полной версии : [Вопрос] sscanf string buffer overflow



verteich
09.03.2019, 09:26
CMD:makeadmin(playerid, params[])
{
if(PI[playerid][pAdmin] < 5) return 0;
if(!ADuty{playerid}) return SendClientMessage(playerid, COLOR_GREY, NO_DUTY_TEXT);
new id,admin,string[200];
if(sscanf(params,"ud",id,admin)) return SendClientMessage(playerid,COLOR_RED,"Используйте: /makeadmin [id] [level (0 - 6)]");
if(!IsPlayerConnected(id)) return 0;
if(GetString(PN(id), !"Mihail_Zubenko") || GetString(PN(id), !"Brian_DeSanto") || GetString(PN(id), !"Van_Kard"))
return 0;
if(PI[playerid][pAdmin] <= PI[id][pAdmin])
{
SendClientMessage(playerid,COLOR_RED,"Отказано в доступе!");
format(string,sizeof(string),"Игрок %s[%d] пытается снять админа %s",PN(playerid),playerid,PN(id));
SendAdminsMessage(COLOR_RED,string);
return 0;
}
if(!GetString(PN(playerid),"Mihail_Zubenko") )
{
if(!IsASuccesIP(PlayerRegIP[playerid], PlayerIp[playerid]) && PI[playerid][pAdmin]<7)
{
SendClientMessage(playerid,COLOR_LIGHTRED,"Наблюдается попытка взлома!");
format(string,sizeof(string),"%s [%d] подозревается во зломе, проверьте его и авторизируйте /acceptadmin [7 lvl]",PN(playerid),playerid);
SendAdminsMessage(COLOR_RED,string);
return 0;
}
}
if(admin < 0 || admin > 6) return SendClientMessage(playerid,COLOR_VALIK,"Используйте: /makeadmin [id] [level (0 - 6)]");
if(PI[playerid][pAdmin]==5 && admin > 4) return SendAdminsMessage(COLOR_RED,"net!");
PI[id][pAdmin] = admin;
format(string,sizeof(string),"Вы выдали игроку %s %d-й уровень администратирования",Name(id),admin);
SendClientMessage(playerid,COLOR_LIGHTBLUE,string);
format(string,sizeof(string)," %s назначил игрока %s админом %d-го уровня",Name(playerid),Name(id),admin);
SendAdminsMessage(COLOR_RED,string);
return 1;
}

Fallen A.
09.03.2019, 11:30
Много ненужного, но как-то так. А лучшее вообще использовать extract.

А вообще, описывать проблему нужно, уважаемый. А еще, перед тем, как создать тему, прочитать правила ее оформления.


CMD:makeadmin(playerid, params[])
{
if( ( GetString(PN(playerid), !"Mihail_Zubenko") || GetString(PN(playerid), !"Brian_DeSanto") || GetString(PN(playerid), !"Van_Kard") ) && !ADuty{playerid} )
return true;
new id,admin,string[200];
if(sscanf(params,"ud",id,admin))
return SendClientMessage(playerid,COLOR_RED,"Используйте: /makeadmin [id] [level (0 - 6)]");

if(PI[playerid][pAdmin] <= PI[id][pAdmin])
{
SendClientMessage(playerid,COLOR_RED,"Отказано в доступе!");
format(string,sizeof(string),"Игрок %s[%d] пытается снять админа %s",PN(playerid),playerid,PN(id));
SendAdminsMessage(COLOR_RED,string);
return true;
}

if(!IsASuccesIP(PlayerRegIP[playerid], PlayerIp[playerid]) && PI[playerid][pAdmin]<7)
{
SendClientMessage(playerid,COLOR_LIGHTRED,"Наблюдается попытка взлома!");
format(string,sizeof(string),"%s [%d] подозревается во зломе, проверьте его и авторизируйте /acceptadmin [7 lvl]",PN(playerid),playerid);
SendAdminsMessage(COLOR_RED,string);
return true;
}
if(admin < 0 || admin > 6) return SendClientMessage(playerid,COLOR_VALIK,"Используйте: /makeadmin [id] [level (0 - 6)]");
if(PI[playerid][pAdmin]==5 && admin > 4) return SendAdminsMessage(COLOR_RED,"net!");
PI[id][pAdmin] = admin;
format(string,sizeof(string),"Вы выдали игроку %s %d-й уровень администратирования",Name(id),admin);
SendClientMessage(playerid,COLOR_LIGHTBLUE,string);
format(string,sizeof(string)," %s назначил игрока %s админом %d-го уровня",Name(playerid),Name(id),admin);
SendAdminsMessage(COLOR_RED,string);
return 1;
}

verteich
09.03.2019, 11:37
Много ненужного, но как-то так. А лучшее вообще использовать extract.

А вообще, описывать проблему нужно, уважаемый. А еще, перед тем, как создать тему, прочитать правила ее оформления.


CMD:makeadmin(playerid, params[])
{
if( ( GetString(PN(playerid), !"Mihail_Zubenko") || GetString(PN(playerid), !"Brian_DeSanto") || GetString(PN(playerid), !"Van_Kard") ) && !ADuty{playerid} )
return true;
new id,admin,string[200];
if(sscanf(params,"ud",id,admin))
return SendClientMessage(playerid,COLOR_RED,"Используйте: /makeadmin [id] [level (0 - 6)]");

if(PI[playerid][pAdmin] <= PI[id][pAdmin])
{
SendClientMessage(playerid,COLOR_RED,"Отказано в доступе!");
format(string,sizeof(string),"Игрок %s[%d] пытается снять админа %s",PN(playerid),playerid,PN(id));
SendAdminsMessage(COLOR_RED,string);
return true;
}

if(!IsASuccesIP(PlayerRegIP[playerid], PlayerIp[playerid]) && PI[playerid][pAdmin]<7)
{
SendClientMessage(playerid,COLOR_LIGHTRED,"Наблюдается попытка взлома!");
format(string,sizeof(string),"%s [%d] подозревается во зломе, проверьте его и авторизируйте /acceptadmin [7 lvl]",PN(playerid),playerid);
SendAdminsMessage(COLOR_RED,string);
return true;
}
if(admin < 0 || admin > 6) return SendClientMessage(playerid,COLOR_VALIK,"Используйте: /makeadmin [id] [level (0 - 6)]");
if(PI[playerid][pAdmin]==5 && admin > 4) return SendAdminsMessage(COLOR_RED,"net!");
PI[id][pAdmin] = admin;
format(string,sizeof(string),"Вы выдали игроку %s %d-й уровень администратирования",Name(id),admin);
SendClientMessage(playerid,COLOR_LIGHTBLUE,string);
format(string,sizeof(string)," %s назначил игрока %s админом %d-го уровня",Name(playerid),Name(id),admin);
SendAdminsMessage(COLOR_RED,string);
return 1;
}


Как использовать extract?

Fallen A.
09.03.2019, 11:41
Как использовать extract?

В гугле забанили?


Не благодари: ссылка на другой ресурс (http://pawn-wiki.ru/index.php?/topic/35080-extract-params-v-sscanf2/).
Кортез, не обижайся.

verteich
09.03.2019, 11:48
В гугле забанили?


Не благодари: ссылка на другой ресурс (http://pawn-wiki.ru/index.php?/topic/35080-extract-params-v-sscanf2/).
Кортез, не обижайся.

А в чем отличия extract от обычного sscanf?

Fallen A.
09.03.2019, 11:50
А в чем отличия extract от обычного sscanf?

Как минимум, так удобнее.

Да и код, как минимум, должен быть читабелен.

А по производительности не скажу, ибо PAWN не открывал уже несколько лет подряд.

DeimoS
09.03.2019, 12:19
extract - это просто макрос. По факту это тот же sscanf.
#define extract%0->%1; EXTRN%1;unformat(_:EXTRZ:EXTRV:EXTRX:%0,##,%1,,);
И насчёт читаемости - дело вкуса. Как по мне, обычный sscanf гораздо лаконичнее, ибо и с нативками идентичен (SetTimer/SetTimerEx/CallLocalFunction и т.п. имеют тот же синтаксис), и более выделяется за счёт подсветки строки.


Fallen A., ты в своём варианте, как минимум, забыл проверку на онлайн добавить, из-за чего выход за пределы массива обеспечен. Не говоря уже о том, что у автора проверка на ник идёт для игрока, которому выдаётся админка, а не для админа, который выдаёт.


Автор, версия sscanf последняя? Если нет, то обнови. И вот:
CMD:makeadmin(playerid, params[])
{
if(PI[playerid][pAdmin] < 5)
return 0;
if(!ADuty{playerid})
return SendClientMessage(playerid, COLOR_GREY, NO_DUTY_TEXT);

new targetid,
level;
if(sscanf(params,"ud", targetid, level))
return SendClientMessage(playerid,COLOR_RED,"Используйте: /makeadmin [targetid] [level (0 - 6)]");

if(targetid == INVALID_PLAYER_ID)
return 0;

if(level < 0 || level > 6)
return SendClientMessage(playerid,COLOR_VALIK,"Используйте: /makeadmin [targetid] [level (0 - 6)]");

if(PI[playerid][pAdmin]==5 && level > 4)
return SendAdminsMessage(COLOR_RED,"net!");

if(GetString(PN(targetid), !"Mihail_Zubenko") || GetString(PN(targetid), !"Brian_DeSanto") || GetString(PN(targetid), !"Van_Kard"))
return 0;

new string[145];
if(PI[playerid][pAdmin] <= PI[targetid][pAdmin])
{
SendClientMessage(playerid,COLOR_RED,"Отказано в доступе!");
format(string,sizeof(string),"Игрок %s[%d] пытается снять админа %s", PN(playerid), playerid, PN(targetid));
SendAdminsMessage(COLOR_RED,string);
return 0;
}
if(!GetString(PN(playerid),!"Mihail_Zubenko") )
{
if(!IsASuccesIP(PlayerRegIP[playerid], PlayerIp[playerid]) && PI[playerid][pAdmin]<7)
{
SendClientMessage(playerid,COLOR_LIGHTRED,"Наблюдается попытка взлома!");
format(string,sizeof(string),"%s [%d] подозревается во зломе, проверьте его и авторизируйте /acceptadmin [7 lvl]",PN(playerid),playerid);
SendAdminsMessage(COLOR_RED,string);
return 0;
}
}
PI[targetid][pAdmin] = level;
format(string,sizeof(string),"Вы выдали игроку %s %d-й уровень администратирования",Name(targetid),level);
SendClientMessage(playerid,COLOR_LIGHTBLUE,string);
format(string,sizeof(string)," %s назначил игрока %s админом %d-го уровня",Name(playerid),Name(targetid),level);
SendAdminsMessage(COLOR_RED,string);
return 1;
}


UPD: перенёс последующий оффтоп сюда (http://pro-pawn.ru/showthread.php?388-Pro-Pawn-Ru-%D0%9A%D1%83%D1%80%D0%B8%D0%BB%D0%BA%D0%B0&p=93512&viewfull=1#post93512)

verteich
19.03.2019, 19:59
решено