2014-07-14 11 views
6

Điều nào sau đây là an toàn liên quan đến tràn bộ đệm?tràn chuỗi trường quét quá rộng

char buf[10] = {0}; 
scanf("%10s", buf); 

hoặc

char buf[10] = {0}; 
scanf("%9s", buf); 

Từ những gì tôi đã đọc tôi sẽ cho phần thứ hai (trừ một sizeof), nhưng vấn đề là khá tinh tế và tôi đã nhìn thấy mã cho thấy một trong hai. Bất kỳ tình nguyện viên nào để trích dẫn tiêu chuẩn?

+0

Bạn có thể đọc tiêu chuẩn C cho câu trả lời có thẩm quyền, thay vì đọc các trang web ngẫu nhiên. –

Trả lời

9

Các C standard bang rằng:

Một mục đầu vào được định nghĩa là chuỗi dài nhất của byte đầu vào (lên đến bất kỳ chiều rộng lĩnh vực tối đa quy định, có thể được đo bằng ký tự hoặc byte phụ thuộc vào sự xác định chuyển đổi) là một chuỗi ban đầu của một chuỗi trùng khớp.

Tức là, chiều rộng trường tối đa thể hiện số lượng ký tự có thể có trong đầu vào. Giá trị 0 không ở cuối không phải là một phần của đầu vào và cần thêm một khoảng trống.

Các GNU libc manual làm cho thời điểm này rõ ràng:

chuyển đổi chuỗi đầu vào lưu trữ một kí tự null để đánh dấu sự kết thúc của đầu vào; chiều rộng trường tối đa không bao gồm trình kết thúc này.

Vì vậy, phiên bản an toàn duy nhất là scanf("%9s", buf).

+0

Cảm ơn! Tôi thấy tiêu chuẩn gây nhầm lẫn, tôi phải đọc phần bạn trích dẫn nhiều lần cho đến khi nó rõ ràng ... – jimis

2
char buf[10] = {0}; 
scanf("%10s", buf); 

là không an toàn. Bạn phải đưa vào tài khoản chuỗi null terminator.

char buf[10] = {0}; 
scanf("%9s", buf); 

là an toàn.

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