2010-05-16 67 views
14

Khi tôi sử dụng được chức năng, gcc mang lại cho tôi một lời cảnh báo:cảnh báo: được chức năng là nguy hiểm

warning:the `gets' function is dangerous and should not be used. 

Tại sao được và đặt chức năng nguy hiểm không?

+18

Hàm 'puts()' là * không * nguy hiểm. Tại sao bạn hỏi về 'puts()' nữa? –

Trả lời

45

Nếu bạn có mã như thế này:

char s[10]; 
gets(s); 

và bạn gõ vào hơn 10 ký tự khi chương trình được chạy, bạn sẽ tràn bộ đệm, gây ra hành vi không xác định. Hàm gets() không có phương tiện ngăn cản bạn gõ các ký tự và vì vậy nên tránh. Thay vào đó bạn nên sử dụng fgets(), cho phép bạn giới hạn số ký tự đọc, vì vậy mà bộ đệm không tràn .:

char s[10]; 
fgets(s, 10, stdin); 

Các puts() chức năng là hoàn toàn an toàn, cung cấp chuỗi đó bạn được xuất ra là null-chấm dứt.

+6

'fgets' không loại bỏ các ký tự. Nó để lại cho họ chưa đọc. Các cuộc gọi tiếp theo tới 'fgets' hoặc bất kỳ chức năng đọc nào khác có thể đọc các ký tự còn lại. –

+0

@R. True - Tôi sẽ chỉnh sửa câu trả lời của mình. BTW, R. không phải là một tên người dùng SO tốt hoặc hợp lý. –

4

gets không hạn chế số lượng dữ liệu mà nó đọc và do đó dễ bị tràn bộ đệm. @ Neil của câu trả lời có giải pháp thích hợp cho việc này.

Chức năng puts không nguy hiểm, AFAIK, trừ khi, tất nhiên, bạn quên vô hiệu hóa nó.

1

Gets không kiểm tra tràn bộ đệm để lộ mã của bạn để tấn công

2

Wikipedia's article says, nó vốn không an toàn vì tất cả những gì cần là một đối số là char *.

Điều này rất nguy hiểm vì không có cách nào cho phương pháp biết số lượng không gian đã được phân bổ cho char * trong mọi tình huống. Do đó gets hoạt động như thể nó có một kiểm tra trống để ghi càng nhiều dữ liệu vào nó càng tốt, điều này có thể dẫn đến tràn bộ đệm.

Phương án thay thế là fgets không chỉ bao gồm mảng ký tự, mà còn chiều dài tối đa và con trỏ luồng. gets chỉ được lưu trữ để tương thích ngược với mã cũ hơn.

2

Lỗi tràn bộ đệm rất nguy hiểm. Dưới đây là định nghĩa:

/* Get a line from the stdin stream. */ 
char *gets(char *buffer); 

Bộ đệm lớn bao nhiêu? Nếu người dùng nhập nhiều dữ liệu hơn có thể vừa với bộ đệm, chương trình có thể bị lỗi và dễ bị hacker khai thác.

1

gets đọc dữ liệu vào khu vực bộ nhớ đã cho đến khi gặp phải dòng mới hoặc kết thúc tệp. Nếu đầu vào (ví dụ như được cung cấp bởi người dùng) chứa một dòng dài hơn kích thước của bộ đệm được cung cấp cho gets, nó sẽ tràn và được ghi vào bộ nhớ ngoài bộ đệm. Tệ nhất điều này có thể cho phép người dùng độc hại ghi dữ liệu làm thay đổi hành vi của chương trình hoặc thậm chí có thể thực thi mã tùy ý với các đặc quyền của chương trình đó (ví dụ: chương trình có thể chạy trên máy chủ từ xa hoặc với đặc quyền của người dùng khác), và thậm chí tràn tình cờ có thể phá vỡ phần mềm.

fgets nên được sử dụng thay vào đó, vì phải mất một đối số bổ sung để hạn chế kích thước của đầu vào.

Các vấn đề liên quan