Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 10 из 10
  1. #1
    Аватар для Danny_Marcelo
    Пользователь

    Статус
    Оффлайн
    Регистрация
    15.11.2015
    Сообщений
    29
    Репутация:
    0 ±

    sscanf warning: String buffer overflow.

    Всем привет. У меня такой вопрос. Как многие знают, я занимаюсь модом Funny RP. Так вот, как написал Daniel_Cortez:

    Сам собой напрашивается вопрос: зачем вообще к моду подключен sscanf2? Ради пары отрывков кода, которые лень переделать?
    Кстати, sscanf2 используется в моде всего 5 раз.
    Вот самое первое место, где он встречается:
    PHP код:
    public OnPlayerCommandText(playerid, cmdtext[])
    {
    new string[256];
    new tmp[128],idx;
    new cmd[128];
    new giveplayerid;
    cmd = strtok(cmdtext,idx);
    // sscanf
    new command[32], params[128];
    sscanf(cmdtext, "s[32]s[128]", command, params);
    Параметры команды отделяются от названия сразу двумя способами, в лучших быдлокодерских традициях.
    И присмотритесь внимательно к форматной строке в sscanf: "s[32]s[128]". В переменную params ничего не запишется, вместо этого и название, и параметры окажутся в command. Мало того, если длина команды и параметров в сумме больше 31 символа, sscanf выплюнет сообщение в лог "sscanf warning: String buffer overflow" - и после этого гадай, откуда берётся такое сообщение.
    В остальных 4 случаях с помощью sscanf2 в командах (OnPlayerCommandText) обрабатываются параметры из params, но поскольку в params ничего нет, то команды будут работать не так, как задумано.
    Ну вот попробовал наконец добавить команду с использованием sscanf и у меня в консоли выбило:

    PHP код:
    sscanf warningString buffer overflow
    Ну как я понял, переполнение буфера. Но Daniel_Cortez сказал, что sscanf подключен к моду не правильно, по этому будут такие ошибки.

    Так как же правильно подключить sscanf к моду? Я гуглил, везде одно и тоже и в моде тоже самое. Прошу по этому вашей помощи. Заранее благодарю.

    Вот собственно подключение к sscanf.

    PHP код:
    public OnPlayerCommandText(playeridcmdtext[])
    {
         new 
    string[256];
        new 
    tmp[128],idx;
        new 
    cmd[128];
        new 
    giveplayerid;
        
    cmd strtok(cmdtext,idx);
        
    // sscanf
        
    new command[32], params[128];
        
    sscanf(cmdtext"s[32]s[128]"commandparams); 
    Ну а вот тестовая команда:

    PHP код:
    if(strcmp(cmd"/msg"true) == 0)
        {
            static const 
    fmt_str[] = "Администратор %s: %s";
            new 
    str[sizeof fmt_str 16 MAX_PLAYER_NAME 50];
            if(
    PlayerInfo[playerid][pAdmin] < 4) return true;
            if(
    sscanf(params"s[50]"params[0])) return SendClientMessage(playeridCOLOR_GREY"Используйте: /msg [текст]");
            
    format(strsizeof(str), fmt_strPlayerInfo[playerid][pName], params[0]);
            
    SendClientMessageToAll(0xFFCC00AAstr);
            return 
    true;
        } 
    Если тут написать текст больше 50, то в консоли выбивает про буфер. Я пробовал изменять на 128 и т.д., но все равно, если больше напишешь символов, то будет снова это сообщение. P.S. используется sscanf 2.8.1

  2. #2
    Аватар для Danny_Marcelo
    Пользователь

    Статус
    Оффлайн
    Регистрация
    15.11.2015
    Сообщений
    29
    Репутация:
    0 ±
    Ну и? Кто нибудь поможет? Где все профессионалы?

  3. #3
    Аватар для Sp1ke
    Пользователь

    Статус
    Оффлайн
    Регистрация
    01.03.2015
    Сообщений
    245
    Репутация:
    55 ±
    Цитата Сообщение от Danny_Marcelo Посмотреть сообщение
    Ну и? Кто нибудь поможет? Где все профессионалы?
    Поэтому и надо делать ограничение на кол-во символов, понятное же дело

  4. #4
    Аватар для nikvlad
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.02.2016
    Сообщений
    94
    Репутация:
    2 ±
    Код:
    if(sscanf(params, "?<SSCANF_QUIET=1>s[50]", params[0])) return SendClientMessage(playerid, COLOR_GREY, "Используйте: /msg [текст]");

  5. Пользователь сказал cпасибо:
    Danny_Marcelo (16.06.2016)
  6. #5
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Danny_Marcelo Посмотреть сообщение
    Так как же правильно подключить sscanf к моду?
    PHP код:
    #include <sscanf2> 
    Худшее, что здесь можно сделать - неправильно написать название инклуда или забыть скопировать сам инклуд в pawno/include. В любом случае компилятор укажет на такую ошибку.


    Цитата Сообщение от Danny_Marcelo Посмотреть сообщение
    Вот собственно подключение к sscanf.

    PHP код:
    public OnPlayerCommandText(playeridcmdtext[])
    {
         new 
    string[256];
        new 
    tmp[128],idx;
        new 
    cmd[128];
        new 
    giveplayerid;
        
    cmd strtok(cmdtext,idx);
        
    // sscanf
        
    new command[32], params[128];
        
    sscanf(cmdtext"s[32]s[128]"commandparams); 
    "Подключение" и "использование" - совершенно разные вещи...


    Цитата Сообщение от Danny_Marcelo Посмотреть сообщение
    Ну а вот тестовая команда:

    PHP код:
    if(strcmp(cmd"/msg"true) == 0)
        {
            static const 
    fmt_str[] = "Администратор %s: %s";
            new 
    str[sizeof fmt_str 16 MAX_PLAYER_NAME 50];
            if(
    PlayerInfo[playerid][pAdmin] < 4) return true;
            if(
    sscanf(params"s[50]"params[0])) return SendClientMessage(playeridCOLOR_GREY"Используйте: /msg [текст]");
            
    format(strsizeof(str), fmt_strPlayerInfo[playerid][pName], params[0]);
            
    SendClientMessageToAll(0xFFCC00AAstr);
            return 
    true;
        } 
    Если тут написать текст больше 50, то в консоли выбивает про буфер.
    Ну так правильно, нужно делать буфер под столько символов, сколько игрок может ввести, а не сколько захочет левая пятка.


    Цитата Сообщение от Danny_Marcelo Посмотреть сообщение
    Я пробовал изменять на 128 и т.д., но все равно, если больше напишешь символов, то будет снова это сообщение.
    Каждая строка должна заканчиваться нуль-символом '\0' (должна же машина как-то знать, где заканчивается последовательность символов), под который нужна ещё одна ячейка в массиве. В итоге в OPCT массивы command и params должны быть оба размером в 129 ячеек.

    Есть ещё вариант посложнее, но использующий только один массив в 129 ячеек вместо двух. Вместо того, чтобы использовать sscanf2, можно скопировать всё содержимое cmdtext в массив command, пройтись циклом по массиву, найти первый пробел и записать на его месте '\0', затем пропустить лишние пробелы между командой и параметрами (да, их там может быть больше одного) и записать позицию, где начинаются параметры команды, в переменную params_start_pos. В итоге сама команда будет в массиве command, а вместо params можно будет использовать command[params_start_pos].
    А вообще для подобных манипуляций есть командные процессоры, кои я и советую вам использовать.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  7. Пользователь сказал cпасибо:
    Danny_Marcelo (16.06.2016)
  8. #6
    Аватар для Battista
    Пользователь

    Статус
    Оффлайн
    Регистрация
    27.02.2016
    Адрес
    Улан-Удэ
    Сообщений
    27
    Репутация:
    1 ±
    new cmd[64],params[64],idx;
    cmd = strtok(cmdtext, idx);
    sscanf(cmdtext,"s[32]s[64]",cmd,params);

  9. Пользователь сказал cпасибо:
    Danny_Marcelo (16.06.2016)
  10. #7
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Battista Посмотреть сообщение
    new cmd[64],params[64],idx;
    cmd = strtok(cmdtext, idx);
    sscanf(cmdtext,"s[32]s[64]",cmd,params);
    Команда может быть длиннее 31 символа, а параметры - длиннее 63 (сразу будет заметно в чатовых командах типа /s, /a, /pm, /sms и т.п.).
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  11. #8
    Аватар для Desulaid
    лесоруб продакшен

    Статус
    Оффлайн
    Регистрация
    15.03.2015
    Адрес
    Slobodskoy
    Сообщений
    667
    Репутация:
    236 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Команда может быть длиннее 31 символа, а параметры - длиннее 63 (сразу будет заметно в чатовых командах типа /s, /a, /pm, /sms и т.п.).
    Почему 63? Разве длинна строки параметра - это не остаток от лимита ввода в чат (128) минус лимит длины имени функции (31)?

  12. #9
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Anton Styazhkin Посмотреть сообщение
    Почему 63? Разве длинна строки параметра - это не остаток от лимита ввода в чат (128) минус лимит длины имени функции (31)?
    Именно.
    Кстати, по поводу моего первого поста в этой теме, небольшая поправка: если команда может быть длиной от 2 до 128 символов, то максимальная длина параметров будет равна 129 - 2 - 1 = 126 символов. В итоге под массив params потребуется не 129, а 126 ячеек.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  13. #10
    Аватар для Desulaid
    лесоруб продакшен

    Статус
    Оффлайн
    Регистрация
    15.03.2015
    Адрес
    Slobodskoy
    Сообщений
    667
    Репутация:
    236 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Именно.
    Кстати, по поводу моего первого поста в этой теме, небольшая поправка: если команда может быть длиной от 2 до 128 символов, то максимальная длина параметров будет равна 129 - 2 - 1 = 126 символов. В итоге под массив params потребуется не 129, а 126 ячеек.
    Учет пробелов и '/' всегда должен быть, если ты об этом.

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •