2013-03-13 2 views
5

ऐसा लगता है कि दोनों में बफर को बहने की क्षमता है। फिर भी मुझे सलाह दी जाती है कि कभी भी उपयोग न हो() लेकिन स्कैनफ() का उपयोग करने के लिए अभी भी प्रोत्साहित किया गया है।स्कैनफ() से अधिक खतरनाक क्यों हो जाता है?

यह सिर्फ स्वरूपण तर्क scanf में अनुमति() की वजह से है या किसी अन्य कारण से है?

+0

एक, बचने वाले पात्रों की वजह से, 'हो जाता है() 'एंडलाइन – noMAD

+3

फ़िल्टर नहीं करता है क्योंकि शायद() निराशाजनक है, स्कैनफ के साथ आप बफर ओवरफ्लो से बच सकते हैं यदि आप इनपुट लंबाई सीमित करने के दर्द से गुजरते हैं ** प्रत्येक ** ** एकल ** ** समय ** – loreb

+0

आईआईआरसी 'प्राप्त करता है यदि आपको कोई '\ n' नहीं है, लेकिन इसके बजाय' EOF' है तो आपको लाइन नहीं मिलती है। – pampeho

उत्तर

8

gets समारोह बफर अतिप्रवाह के खिलाफ की रक्षा नहीं है।

scanf प्रारूप स्ट्रिंग के साथ आप मानक इनपुट और पढ़ने वाले मेमोरी बफर में स्टोर से पढ़ने के लिए स्ट्रिंग की अधिकतम लंबाई को परिभाषित कर सकते हैं। उदाहरण के लिए scanf("%10s\n", str); के साथ अधिकतम 10 वर्ण पढ़े जाएंगे। NULL समाप्ति चरित्र को स्टोर करने के लिए str बफर 11 बाइट्स होना चाहिए।

प्रदर्शन के अनुसार, यदि आप के बफर ओवरफ़्लो समस्याओं को हल करने के लिए केवल scanf का उपयोग करते हैं, तो इसके बजाय fgets फ़ंक्शन का उपयोग करना पसंद करते हैं।

+0

कुछ शोध मैं यह भी पाया कि ऐसा करने से: scanf() केवल आप एक से अधिक क्षेत्र, में प्रवेश करने की अनुमति नहीं दी जाएगी लेकिन यह भी आप में प्रवेश करने की अनुमति देता है ** संरचित ** क्या पात्रों को निर्दिष्ट करने की क्षमता सहित डेटा फ़ील्ड के बीच दिखाई देते हैं। तो मुझे लगता है कि यह ध्यान में रखना भी दिलचस्प है। स्रोत: हेड फर्स्ट सी, डेविड एंड डॉन ग्रिफिथ्स। –

+0

आप सही हैं, 'स्कैनफ़' और' होट' (या 'fgets') समान उपयोग मामलों को कवर नहीं करता है। आप इनपुट स्ट्रीम से एक लाइन पढ़ने के लिए 'fgets' का उपयोग करते हैं। आप इनपुट स्ट्रीम से डेटा पार्स करने के लिए 'scanf' का उपयोग करते हैं। यह कहा गया है कि आप इनपुट स्ट्रीम से एक लाइन पढ़ने के लिए 'scanf' का उपयोग कर सकते हैं जैसा कि आप' fgets' के साथ करेंगे लेकिन इसके परिणामस्वरूप प्रदर्शन हानि होगी। – greydet

1

क्योंकि वहाँ बफर अतिप्रवाह को रोकने के लिए कोई रास्ता नहीं है। fgets सुरक्षित है क्योंकि अधिकतम बफर लंबाई निर्दिष्ट है।

+4

प्रश्न वास्तव में 'होट' बनाम 'स्कैनएफ' के बारे में है। –

2

क्योंकि आप बफर के आकार की तुलना में इनपुट अधिक वर्ण और हो जाता है() खुशी से यह अनुमति देगा कर सकते हैं। इसके अलावा,() को हटा दिया गया है (सी 11 में)। तो scanf() के साथ तुलना अब मान्य नहीं है। स्कैनफ() के अलावा गैर-स्वरूपित डेटा से निपटने के दौरान इसकी अपनी समस्याएं हैं।

तो बेहतर विकल्प fgets() होगा और फिर अपनी आवश्यकताओं के अनुसार इसे संसाधित करेगा।

1

gets के साथ विकृत इनपुट के मामले में बफर ओवरफ़्लो को रोकना संभव नहीं है। scanf डेटा पढ़ने की मात्रा पर नियंत्रण की अनुमति देता है।

How to prevent scanf causing a buffer overflow in C?

1

अभी भी scanf का उपयोग करने के लिए प्रोत्साहित किया()।

"scanf सुरक्षा" के लिए एक त्वरित गूगल खोज ~ 212k परिणाम बदल जाता है। पहले Wikipedia, जिसमें कहा गया है कि लंबाई विनिर्देशक बिना %s प्लेसहोल्डर के

का उपयोग करता है स्वाभाविक असुरक्षित और बफर अतिप्रवाह के लिए दोहन हो रहा है।

तो वेब पर scanf सुरक्षा के बारे में पर्याप्त जानकारी है। gets साथ अंतर यह है कि scanf, सुरक्षित उपयोग करता है gets का उपयोग कर व्यावहारिक रूप से हमेशा एक बुरा विचार है, जबकि है।

1

हो जाता है की नाममात्र कार्य() एक धारा से एक स्ट्रिंग में पढ़ने के लिए है। कॉलर कहता है कि आने वाले पात्रों को कहां रखा जाए। लेकिन हो जाता है() बफर स्पेस की जांच नहीं करता है। यदि कॉलर स्टैक पर पॉइंटर प्रदान करता है, और बफर स्पेस से अधिक इनपुट मिलता है, तो() स्टैक को ओवरराइट कर देगा। अधिकांश सिस्टम स्टैक के बीच में मौजूदा प्रविष्टि को ओवरराइट करने के लिए कमजोर होते हैं, जो कुछ बड़े होते हैं, जो पड़ोसी प्रविष्टियों को ओवरराइट भी करते हैं। एक पुरुषफैक्टर तर्क स्ट्रिंग में सही बाइनरी पैटर्न को दबाकर स्टैक पर प्रक्रिया सक्रियण रिकॉर्ड में वापसी पता संशोधित कर सकता है। यह निष्पादन के प्रवाह को वापस नहीं करेगा, जहां से यह आया था, लेकिन एक विशेष निर्देश अनुक्रम के लिए जो चलती छवि को एक खोल के साथ बदलने के लिए execv() को कॉल करता है।यह खोल सिस्टम को वायरस की एक प्रतिलिपि खींचने के लिए आदेश जारी कर सकता है। तो हो जाता है() सुरक्षित नहीं है।

+0

यह स्पष्ट नहीं करता है कि क्यों 'scanf' सुरक्षित है। – jamesdlin

संबंधित मुद्दे