2015-05-19 2 views
0

Я был просто отмечен курсовой работой за это неправильное решение переполнения буфера в c, но не был предоставлен отзыв о том, как это было неправильно. Может ли кто-нибудь сообщить мне, в чем проблема? Спасибо.Что не так с этим решением переполнения буфера в c?

На вопрос, сформулированный обеспечить решение в случае более длинная строка, чем 16 был принят в этой функции:

void function(char *str) 
{ 
    char buffer[16]; 
    strcpy(buffer, str); 
} 

А вот мое решение

void function(char *str) 
{ 
    size_t str_length = strlen(str); 

    char buffer[str_length]; 
    strcpy(buffer, str); 
} 

Благодаря

+0

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

ответ

11

Вы необходимо учесть нулевой символ, заканчивающий строку:

char buffer[str_length + 1]; 

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

void function(char *str) 
{ 
    size_t str_length = strlen(str); 
    char *buffer = malloc(str_length + 1); 
    if (buffer == NULL) 
     return; 
    memcpy(buffer, str, str_length+1); // Thanks chux 
    // Do something with with buffer... 
    free(buffer); 
} 

Или, может быть, профессор просто искал это:

void function(char *str) 
{ 
    char buffer[16]; 
    strncpy(buffer, str, sizeof(buffer)); 
    buffer[sizeof(buffer)-1] = '\0'; 
} 
+0

По-прежнему выглядит небезопасным. 1) 'buffer' выделяется в стеке - что делать, если вы получаете переполнение стека? 2) На 'str_length' нет верхнего предела - что, если нет никакого оконечного 0 для гигабайт и гигабайт памяти? –

+0

Код заплатил цену, чтобы рассчитать длину 'str'. 'strcpy()' эффективно делает это снова. Вместо 'strcpy (buffer, str);', рассмотрим более эффективную 'memcpy (buffer, str, str_length + 1)'. – chux

1

Это зависит от того, что вам разрешено использовать, но я предполагаю, что самым безопасным способом было бы использовать strdup и проверьте, вернул ли он NULL.

void function(char *str) 
{ 
    char *buffer; 

    buffer = strdup(str); 
    if (!buffer) 
     exit(EXIT_FAILURE); 
    free(buffer); 
    /* free buffer or keep track of it or you'll end up with memory leaks */ 
} 

В том случае, когда вы не позволили динамически выделять память, использование strncpy еще более безопасная альтернатива зЬгсру.

void function(char *str) 
{ 
    size_t str_length = strlen(str); 
    char buffer[str_length + 1]; /* /!\ This is C99 */ 

    strncpy(buffer, str, str_length); 
    buffer[str_length] = '\0'; 
} 
+0

1) 'strncpy (buffer, str, str_length); buffer [str_length] = '\ 0'; 'не требует дополнительной безопасности. Просто используйте 'memcpy (buffer, str, str_length + 1);' 2). Не существует ограничения на размер 'buffer []' - теперь _that_ представляет собой проблему с разбивкой стека. – chux

Смежные вопросы