Почему и как gcc выдает предупреждение для gets()?

while(1)
    {
        printf("\nEnter message : ");
        gets(message);

        //Send some data
        if( send(sock , message , strlen(message) , 0) < 0)
        {
            puts("Send failed");
            return 1;
        }

        //Receive a reply from the server
        if( recv(sock , server_reply , 2000 , 0) < 0)
        {
            puts("recv failed");
            break;
        }

        puts("Server reply :");
        puts(server_reply);
    }

    close(sock);
    return 0;
}

Это часть моей программы. Когда я компилирую и запускаю его, я получаю сообщение об ошибке. Сообщение об ошибке

предупреждение: функция gets опасна и не должна использоваться!


person Mediocre    schedule 10.07.2015    source источник
comment
возможный дубликат как подавить предупреждение gets() устарело?   -  person Yu Hao    schedule 10.07.2015
comment
предупреждение компилятора и ошибка компилятора - разные. Может быть связаны, да, но, очень разные.   -  person askmish    schedule 10.07.2015
comment
Да, gets устарел и теперь удален после того, как c11.gets_s был представлен как более безопасная альтернатива.   -  person Raman    schedule 10.07.2015
comment
используйте такие fgets fgets(array, sizeof(arr), stdin) или scanf("%[^\n]%*c", arr) не забудьте отрезать \n в случае fgets   -  person Mayukh Sarkar    schedule 10.07.2015
comment
@ARBY Обратите внимание, что gets_s() существует только из соображений обратной совместимости, сам стандарт рекомендует использовать fgets().   -  person Lundin    schedule 10.07.2015
comment
@Lundin: Хорошо, спасибо за информацию :-).   -  person Raman    schedule 10.07.2015


Ответы (3)


Простой поиск в Google дал бы много полезной информации, такой как этот ответ.

https://stackoverflow.com/a/1694042/2425366

Пример переполнения буфера с использованием gets

#include <stdio.h>
#include <string.h>

int main(void) {
    char buff[15];
    int pass = 0;
    printf("\n Enter the password : \n");
    gets(buff);
    if (strcmp(buff, "thegeekstuff")) {
        printf("\n Wrong Password \n");
    }
    else {
        printf("\n Correct Password \n");
        pass = 1;
    }
    if (pass) {
        /* Now Give root or admin rights to user*/
        printf("\n Root privileges given to the user \n");
    }
    return 0;
}

Ввод 1

thegeekstuff

Вывод

 Correct Password
 Root privileges given to the user

Ввод 2

abcdefghijklmnopqr    <-- stack smashing

Вывод

 Wrong Password
 Root privileges given to the user
person Shreevardhan    schedule 10.07.2015

Что касается вопроса:

Функция gets() опасна из-за риска переполнения буфера и исключена из стандарта C согласно стандарту C11. Компиляторы могут поддерживать их для обратной совместимости с устаревшими кодами.

FWIW, это предупреждение не выдается gcc само по себе. Скорее всего, glibc содержит прагму, которая заставляет компилятор выдавать предупреждение. Ссылка

По поводу ошибки:

У вас есть -Werror в вашем операторе компиляции, который в основном запрашивает gcc рассматривать любое предупреждение как ошибку.

person Sourav Ghosh    schedule 10.07.2015

Вы не показали нам, как вы объявили переменную message, которую вы передали в качестве аргумента для gets. Предположим, это было

char message[100];

Теперь предположим, что фактическая строка ввода, которую ваша программа пытается прочитать, имеет длину 200 символов. Массив переполнится, что может привести к катастрофическим последствиям. (Серьезно: серьезные нарушения безопасности произошли в результате использования gets.)

Независимо от того, насколько велик ваш массив, ввод всегда может быть больше, и нет никакого способа предотвратить переполнение, потому что нет никакого способа сказать gets, насколько велик ваш массив на самом деле. Вот почему вы никогда не должны использовать его.

person Steve Summit    schedule 10.07.2015