2010-02-24 14 views
5

के साथ सुरक्षित रूप से कॉल करना हमारे पास एक सी ++/एमएफसी एप्लिकेशन है जो उपयोगकर्ताओं को कॉन्फ़िगरेशन फ़ाइलों के माध्यम से दिनांक स्वरूपण को अनुकूलित करने की अनुमति देता है। पहिया को फिर से शुरू करने की इच्छा नहीं है, मैं वास्तविक स्वरूपण करने के लिए प्रारूप स्ट्रिंग को सीटीआईएम :: प्रारूप ("< प्रारूप स्ट्रिंग>") पास करता हूं। कवर के तहत, प्रारूप मानक सी फ़ंक्शन स्ट्रैटाइम() का एक संस्करण कॉल करता है।सुरक्षित रूप से अविश्वसनीय प्रारूप स्ट्रिंग

स्वाभाविक रूप से, उपयोगकर्ता गलती से एक अवैध प्रारूप स्ट्रिंग दर्ज कर सकता है। (उदाहरण के लिए, "% s" के बजाय "% s"।) जब ऐसा होता है, तो सी रन-टाइम Invalid Argument Handler पर कॉल करता है, जो डिफ़ॉल्ट रूप से ऐप से बाहर निकलता है। (पकड़ने के लिए कोई अपवाद नहीं - बस ऐप से बाहर निकलें।)

मेरा प्रश्न यह है कि इस अविश्वसनीय इनपुट को गहन तरीके से कैसे संभालें। सिद्धांत रूप में, मैं प्रारूप स्ट्रिंग के लिए अपना खुद का पार्सर/सत्यापनकर्ता लिख ​​सकता था, लेकिन यह समय की बर्बादी की तरह लग रहा था। इसके बजाय, सबसे अच्छा मैं के साथ आ सकता है मेरे अपने (वैश्विक) अमान्य तर्क हैंडलर जो, बजाय बाहर निकलने की, आप अमान्य तर्क अपवाद फेंकता है स्थापित करने के लिए किया गया था:

void MyInvalidParameterHandler(
    const wchar_t* expression, 
    const wchar_t* function, 
    const wchar_t* file, 
    unsigned int line, 
    uintptr_t pReserved) 
{ 
    ::AfxThrowInvalidArgException(); 
} 

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

क्या यह दृष्टिकोण समझदार है? या क्या इस समस्या को हल करने के लिए एक क्लीनर दृष्टिकोण है?

उत्तर

3

यदि आप निश्चित रूप से इस त्रुटि को पकड़ने में रुचि रखते हैं, तो आप अस्थायी रूप से अमान्य पैरामीटर हैंडलर को प्रतिस्थापित कर सकते हैं और फिर प्रारूप को कॉल करने के बाद इसे वापस सेट कर सकते हैं।

_invalid_parameter_handler oldHandler = _set_invalid_parameter_handler(MyInvalidParameterHandler); 

// Your try/Format/catch code here 

_set_invalid_parameter_handler(oldHandler); 

बेशक, मैं यह संभव है कि अगर आप अपने कार्यक्रम में एक से अधिक थ्रेड है, एक और धागा अपने अमान्य पैरामीटर हैंडलर बुला लग सकती है, जबकि यह सेट है लगता है। आपको यह निर्धारित करना होगा कि यह कितना संभव है।

अपना खुद का सत्यापन फ़ंक्शन लिखने के अलावा, मुझे यकीन नहीं है कि आप यह कैसे कर सकते हैं।

+0

सुझाव के लिए धन्यवाद। दुर्भाग्यवश, मेरा ऐप वास्तव में बहु-थ्रेडेड है, इसलिए मुझे नहीं लगता कि मैं सुरक्षित रूप से हैंडलर को आगे और पीछे टॉगल कर सकता हूं। (अमान्य पैरामीटर हैंडलर थ्रेड-विशिष्ट के बजाए वैश्विक है।) –

+0

उस स्थिति में, मेरा मानना ​​है कि आपको अपना स्वयं का सत्यापन कार्य बनाना होगा। यह मुश्किल नहीं होना चाहिए। यदि आप सीआरटी स्रोत कोड में strftime.c में देखते हैं तो आपको _expandtime नामक एक फ़ंक्शन दिखाई देगा। इसमें सभी समर्थित प्रारूप विनिर्देशकों के लिए केस स्टेटमेंट शामिल है। आप इसे अपने फ़ंक्शन के आधार के रूप में उपयोग कर सकते हैं। – Dustin

+0

एक संभावना है कि आप अपना खुद का अमान्य पैरामीटर हैंडलर जोड़ना जो कुछ भी नहीं करता है। दस्तावेज़ बताते हैं कि अगर नियंत्रण कॉलिंग फ़ंक्शन पर वापस आता है तो यह एक त्रुटि कोड लौटाएगा। – Dustin

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