2010-01-04 8 views
14

मैं अपने उपयोगकर्ताओं को कुछ विशेषताओं के लिए नियमित अभिव्यक्तियों का उपयोग करना चाहता हूं। मैं उत्सुक हूं कि resupportpile() पर उपयोगकर्ता इनपुट पास करने के प्रभाव क्या हैं। मुझे लगता है कि उपयोगकर्ता के लिए मुझे एक स्ट्रिंग देने का कोई तरीका नहीं है जो उन्हें मनमाने ढंग से कोड निष्पादित करने दे। जिन खतरों के बारे में मैंने सोचा है वे हैं:क्या Python के नियमित अभिव्यक्तियों के लिए उपयोगकर्ता इनपुट का उपयोग करना सुरक्षित है?

  1. उपयोगकर्ता इनपुट को पास कर सकता है जो अपवाद उठाता है।
    • उपयोगकर्ता इनपुट पास कर सकता है जो रेगेक्स इंजन को लंबे समय तक ले सकता है, या बहुत सारी मेमोरी का उपयोग कर सकता है।

1. का हल आसान है: पकड़ अपवाद नहीं। मुझे यकीन नहीं है कि 2 के लिए कोई अच्छा समाधान है या नहीं। शायद रेगेक्स की लंबाई सीमित करना काम करेगा।

क्या मुझे और चिंता करने की ज़रूरत है?

उत्तर

17

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

regex की लंबाई सीमित काम नहीं करेगा, क्योंकि समस्या उलटे पांव लौटने से किया जाता है। उदाहरण के लिए, लंबाई एन की एक स्ट्रिंग पर regex r"(\S+)+x" से मिलान करना जिसमें "x" नहीं है, 2 ** एन बार बैकट्रैक होगा। अपने सिस्टम पर इस "a"*21 के खिलाफ मैच के लिए एक दूसरे के बारे में लेता है और समय प्रत्येक अतिरिक्त चरित्र के लिए दोगुना हो जाता है, तो 100 अक्षरों की स्ट्रिंग लगभग 19167393131891000 साल लग जाएगा पूरा करने के लिए (यह एक अनुमान है, मैं इसे समय समाप्त हो गया है)।

अधिक जानकारी के लिए ओ रेली पुस्तक "रेगुलर एक्सप्रेशन मास्टरिंग" पढ़ा - इस प्रदर्शन पर अध्याय की एक जोड़ी है।

संपादित इस हम एक regex विश्लेषण समारोह है कि पकड़ने और अधिक स्पष्ट पतित मामलों में से कुछ को अस्वीकार करने की कोशिश की लिखा दौर प्राप्त करने के लिए, लेकिन यह उन सभी को प्राप्त करने के लिए असंभव है।

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

+8

+1 "(यह एक अनुमान है, मैंने इसे समय नहीं दिया है)" –

+1

मुझे लगता है कि मैं एक और प्रक्रिया को जन्म दे सकता हूं और इसे बहुत लंबे समय बाद बाहर निकाल सकता हूं? – Skeletron

+0

स्पॉन्गिंग और हत्या काम करेगी, लेकिन प्रत्येक मैच को चलाने के लिए काफी ओवरहेड जोड़ें। चाहे वह भुगतान करने के लिए स्वीकार्य मूल्य है आप पर निर्भर है। –

0

मुझे सच में नहीं लगता कि इसे पुनः reppile में पास करके कोड निष्पादित करना संभव है। जिस तरह से मैं इसे समझता हूं, re.compile (या किसी भी भाषा में किसी भी regex प्रणाली) regex स्ट्रिंग को finite automaton (डीएफए या एनएफए) में परिवर्तित करता है, और अशुभ नाम 'संकलन' के बावजूद इसके किसी भी कोड के निष्पादन के साथ कुछ लेना देना नहीं है ।

0

स्ट्रिंग पर नियमित अभिव्यक्ति ऑपरेशन करने के लिए आपको तकनीकी रूप से re.compile() का उपयोग करने की आवश्यकता नहीं है। वास्तव में, संकलन विधि अक्सर धीमी हो सकती है यदि आप प्रारंभिक संकलन के साथ जुड़े ओवरहेड के बाद से केवल ऑपरेशन निष्पादित कर रहे हैं।

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

+1

मुझे लगता है कि यह कुछ हद तक बिंदु के अलावा है। वास्तविक खोज करने के लिए, 'मैच' को संकलन चरण को वैसे भी करना होगा, ओपी के बारे में चिंतित है। – wds

1

संकलन() का उपयोग करना आवश्यक नहीं है, सिवाय इसके कि जब आपको कई अलग-अलग नियमित अभिव्यक्तियों का पुन: उपयोग करने की आवश्यकता होती है। मॉड्यूल पहले से ही अंतिम अभिव्यक्तियों को पकड़ता है।

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

3

नियमित अभिव्यक्ति संकलित करना उचित रूप से सुरक्षित होना चाहिए। यद्यपि यह जो संकलित करता है वह सख्ती से एक एनएफए नहीं है (बैकरेन्फर का मतलब है कि यह काफी साफ नहीं है) इसे अभी भी संकलित करने के लिए सरल होना चाहिए।

अब प्रदर्शन विशेषताओं के रूप में, यह पूरी तरह से एक और समस्या है। बैकट्रैकिंग के कारण भी एक छोटी नियमित अभिव्यक्ति में घातीय समय विशेषताओं हो सकती है। सुविधाओं के एक निश्चित सबसेट को परिभाषित करना बेहतर हो सकता है और केवल आपके द्वारा अनुवादित बहुत सीमित अभिव्यक्तियों का समर्थन करना बेहतर हो सकता है।

यदि आप वास्तव में सामान्य नियमित अभिव्यक्तियों का समर्थन करना चाहते हैं तो आपको या तो अपने उपयोगकर्ताओं (कभी-कभी एक विकल्प) पर भरोसा करना होगा या उपयोग की जाने वाली जगह और समय की सीमा को सीमित करना होगा। मैं मानता हूं कि अंतरिक्ष का उपयोग केवल नियमित अभिव्यक्ति की लंबाई से निर्धारित होता है।

संपादित करें: डेव नोट्स के रूप में, स्पष्ट रूप से वैश्विक दुभाषिया लॉक रेगेक्स मिलान के दौरान आयोजित किया जाता है, जो उस समय को कठिन बना देगा।यदि ऐसा है, तो टाइमआउट सेट करने का आपका एकमात्र विकल्प मैच को एक अलग प्रक्रिया में चलाने के लिए है। हालांकि बिल्कुल आदर्श नहीं है यह करने योग्य है। मैं पूरी तरह से multiprocessing भूल गया। ऑब्जेक्ट्स साझा करने पर ब्याज की बात this section है। यदि आपको वास्तव में कठोर बाधाओं की आवश्यकता है, तो अलग-अलग प्रक्रियाएं यहां जाने का तरीका हैं।

+1

टाइमआउट को लागू करने के लिए एक अलग थ्रेड का उपयोग करना काम नहीं करता है क्योंकि एक मैच करते समय पाइथन जीआईएल रखता है - मेरा जवाब देखें। भले ही आपने जीआईएल को रिहा करने के लिए फिर से चिपकाया हो, आपको एक रेगेक्स चलाने वाले थ्रेड को मारने का कुछ तरीका जोड़ना होगा - तुच्छ नहीं! –

+0

मेरी गलती, यह तब बहुत ही कष्टप्रद है। मैं कुछ और अस्पष्ट लेकिन संभव के लिए मेरा जवाब संपादित कर दूंगा। – wds

6

यह उन्हें एक सबसेट भाषा देने के लिए आकस्मिक उपयोगकर्ताओं के लिए बहुत सरल है। उदाहरण के लिए fnmatch में शैल के ग्लोबिंग नियम। एसक्यूएल LIKE हालत नियम एक और उदाहरण हैं।

रनटाइम पर निष्पादन के लिए एक उचित regex में उपयोगकर्ता की भाषा का अनुवाद करें।

+0

+1 जाने का एकमात्र सुरक्षित तरीका +1 – bobince