2012-05-14 23 views
5

python: make a variable equal an operator (+,/,*,-)तुलना ऑपरेटर को एक चर बनाने का कोई तरीका है?

मुझे कुछ कोड मिला है जहां उपयोगकर्ता चलाने के लिए तुलना की एक प्रकार चुन सकते हैं, और तुलना करने के लिए एक मूल्य चुन सकते हैं। मैं वहाँ जावास्क्रिप्ट में किसी भी तरह से एक वास्तविक तुलना में है कि उपयोगकर्ता प्रदान की तुलना मूल्य चालू करने के लिए है, तो पता करने के लिए उत्सुक हूँ, मेरे जैसे कुछ करने के लिए अनुमति देता है:

if (user_comparison = '<') { 
    if (user_val < other_val) { 
     do_something(); 
    } 
else if (user_comparison = '<=') { 
    if (user_val <= other_val) { 
     do_something(); 
    } 
....etc 
: इसके बजाय की तरह कुछ करने के लिए होने के

if (user_val user_comparison other_val) { 
    do_something(); 
} 

ध्यान दें कि किसी भी तुलना की मिलान की जानी चाहिए, वही कोड निष्पादित किया जाएगा।

+0

नहीं, आप जेएस –

उत्तर

10

नहीं यह संभव नहीं है

यहाँ एक इस समाधान का प्रदर्शन है। लेकिन आप अपने कोड को बेहतर तरीके से बना सकते हैं।जब user_comparison तालिका में मौजूद नहीं है

if(operator_table[user_comparison](user_val, other_val)) { 
    // do something 
} 
बेशक आप भी इस मामले को संभाल चाहिए के

: उदाहरण के लिए यदि आप एक लुकअप तालिका हो सकते हैं:

var operator_table = { 
    '>': function(a, b) { return a > b; }, 
    '<': function(a, b) { return a < b; } 
    // ... 
}; 

और बाद में।

ये आपको अनुमति देने पर अनुमति देता है और ऑपरेटरों को अनुमति नहीं देता है।

यहां DEMO@Jesse द्वारा निर्मित है।

+2

यहां एक जेएसफ़िल्ड यह प्रदर्शित करता है: http://jsfiddle.net/jonypawks/Cq8Hd/ – Jesse

+0

डाउनवोट क्यों? –

+0

कौन जानता है? यह एक अच्छा, सुरुचिपूर्ण समाधान है जो स्विच से बेहतर तरीके से काम करता है। मैं अपने ऐप में विचारों के बीच स्विच करने के लिए एक समान तकनीक का उपयोग करता हूं। –

4

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

अब, eval()खतरनाक है क्योंकि यह किसी भी जावास्क्रिप्ट कोड को निष्पादित कर सकता है। उपयोगकर्ता निष्पादन योग्य और संभावित रूप से दुर्भावनापूर्ण जावास्क्रिप्ट कोड को ऑपरेटर के रूप में खिला सकता है और eval() इसका मूल्यांकन करेगा। इसलिए, जब आप concatenation करते हैं, तो आपको यह सत्यापित करने के बाद यह करना चाहिए कि ऑपरेंड सुरक्षित है। इस बिंदु पर जोर देने के लिए, मैं बड़े फोंट में कंप्यूटर सुरक्षा के सबसे महत्वपूर्ण सिद्धांतों में से एक लिखूंगा:

अन्य इनपुट अन्यथा सिद्ध होने तक बुराई है।

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

eval() के इन दोषों को ध्यान में रखते हुए, आप फ़ेलिक्स क्लिंग द्वारा पोस्ट किए गए एक निएटर समाधान के लिए जाना चाह सकते हैं।

function compare(a, op, b) 
{ 
    // Check that we have two numbers and an operator fed as a string. 
    if (typeof a != 'number' || typeof b != 'number' || typeof op != 'string') 
    return 

    // Make sure that the string doesn't contain any executable code by checking 
    // it against a whitelist of allowed comparison operators. 
    if (['<', '>', '<=', '>=', '==', '!='].indexOf(op) == -1) 
    return 

    // If we have reached here, we are sure that a and b are two integers and 
    // op contains a valid comparison operator. It is now safe to concatenate 
    // them and make a JavaScript executable code. 
    if (eval(a + op + b)) 
    doSomething(); 
} 

ध्यान दें कि एक श्वेत सूची के खिलाफ इनपुट मान्य लगभग हमेशा एक काली सूची के खिलाफ यह मान्य तुलना में एक बेहतर विचार है: हालांकि, यह भी संभव इस समस्या को एक सुरक्षित तरीके से eval() का उपयोग कर हल करने के लिए के रूप में नीचे दिखाया गया है। इस पर एक संक्षिप्त चर्चा के लिए https://www.owasp.org/index.php/Input_Validation_Cheat_Sheet#White_List_Input_Validation देखें। शामिल जेसी के परीक्षण का मामला साथ डेमो:: http://jsfiddle.net/YrQ4C/ (कोड भी नीचे reproduced):

function doSomething() 
{ 
    alert('done something!') 
} 

function compare(a, op, b) 
{ 
    if (typeof a != 'number' || typeof b != 'number' || typeof op != 'string') 
    return 

    if (['<', '>', '<=', '>=', '==', '!='].indexOf(op) == -1) 
    return 

    if (eval(a + op + b)) 
    doSomething(); 
} 

// Positive test cases 
compare(2, '<', 3) 
compare(2, '<=', 3) 

// Negative test cases 
compare(2, '>', 3) 
compare(2, '>=', 3) 

// Attack tests 
compare('alert(', '"attack!"', ')') 

// Edit: Adding a new attack test case given by Jesse 
// in the comments below. This function prevents this 
// attack successfully because the whitelist validation 
// for the second argument would fail. 
compare(1, ';console.log("executed code");2==', 2) 

संपादित http://jsfiddle.net/99eP2/

+0

में ऐसा नहीं कर सकते हैं आपको कभी भी eval का उपयोग नहीं करना चाहिए। – Jesse

+0

यदि इनमें से कोई भी मान उपयोगकर्ता द्वारा प्रदान किया जाता है, तो वह कुछ भी निष्पादित कर सकता है ... –

+0

@ जेसे क्या आप कृपया बता सकते हैं कि आपको eval का उपयोग क्यों नहीं करना चाहिए? – Esen

-1

चूंकि @ सुसम पाल कोड काम नहीं कर रहा है। मैं एक वर्किंग वर्जन

<html> 
    <head> 
    <script> 
     function CompareSomething(val1, compareString, val2) { 
      eval('if(' + val1 + ' ' + compareString + ' ' + val2 + '){conditionPassed();}else{conditionFailed();}'); 
    } 
    function compare(a, op, b) { 
     if (eval(a + op + b)) 
      conditionPassed(); 
     else 
     conditionFailed(); 
    } 
    function conditionPassed() { 
     alert('condition passed'); 
    } 
    function conditionFailed() { 
     alert('condition failed'); 
    } 
    </script> 
    </head> 
<body> 
a:<input id='txt1' type="text" />&nbsp;op:<input id='txt2' type="text" />&nbsp;b:<input id='txt3' type="text" /><br/> 
<button id='compare' onclick='CompareSomething(document.getElementById("txt1").value,document.getElementById("txt2").value,document.getElementById("txt3").value)'>Compare Esen Method</button><br/> 
<button id='compare' onclick='Compare(document.getElementById("txt1").value,document.getElementById("txt2").value,document.getElementById("txt3").value)'>Compare Susam Method</button> 
    </body> 
</html> 
+1

मैंने फ़ायरफ़ॉक्स में अपने कोड (http://jsfiddle.net/YrQ4C/) का परीक्षण किया है, लिनक्स के साथ-साथ विंडोज़, साथ ही आईई 8 पर क्रोम, और यह सभी तीन ब्राउज़रों पर काम करता है। जब मेरा कोड आपके लिए काम नहीं करता है तो आपने किस ब्राउजर का उपयोग किया था? जावास्क्रिप्ट कंसोल में आपको क्या त्रुटि मिली? –

+0

आपने अपना उत्तर संपादित कर लिया है। आपके पिछले संस्करण में यह कोड था। इसे आज़माएं और मुझे बताएं कि यह सभी ब्राउज़र में काम करता है या नहीं। अगर मैंने आपका संपादन देखा है, तो मैंने अद्यतन संस्करण पोस्ट नहीं किया होगा। अगर इससे आपको नाराज हो जाता है और वोट कम हो जाता है तो आपको बहुत धन्यवाद। फ़ंक्शन तुलना (ए, बी, सेशन) { अगर (eval (a + op + b)) do_something() } – Esen

+1

यदि आप मेरा वर्तमान कोड जांचते हैं तो आपके पास उस कोड का उल्लेख है जिसे आप उल्लेख करते हैं 'अगर (eval (a + op + बी)) कुछ करो(); '। यह वही कोड है जो मेरे पहले अपूर्ण उत्तर में मौजूद था। बाद में, मैंने यह सुनिश्चित करने के लिए केवल सुरक्षा जांच को जोड़ा कि समाधान पूरा हो गया है। आपने अभी तक मुझे नहीं बताया है कि कौन सा ब्राउज़र निष्पादित करने में विफल रहा है 'अगर (eval (a + op + b)) कुछ(); '। मेरे वर्तमान समाधान में यह कोड सभी तीन ब्राउज़रों में निष्पादित करता है। सादगी के लिए –

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