2011-12-16 5 views
5

This questionsystem कमांड और पास करने वाले चर का उपयोग करने के बारे में बात करता है।मैं सी ++ में 'सिस्टम' कमांड में भेजे गए चर से कैसे बच सकता हूं?

string cmd("curl -b cookie.txt -d test="); 
cmd += line; 
cmd += " http://example.com"; 
system(cmd.c_str()); 

टिप्पणियों में से एक कहा गया है कि अगर line पारित किया गया था और foo & fire_nukes.exe & REM निहित तो यह बहुत संभव है कुछ बुरा हो सकता है है: यहाँ एक उदाहरण यह देता है।

PHP में escape_shell_args नामक एक शानदार फ़ंक्शन है जिसका उपयोग प्रोग्राम में पारित होने वाले पैरामीटर से बचने के लिए किया जा सकता है। क्या सी ++ के पास ऐसा करने का कोई तरीका है?

+2

आप हमेशा 'फोर्क' और 'exec' का उपयोग कर सकते हैं ... –

+4

' मैन फोर्क ',' मैन एक्जिक ':-) (आप वास्तव में "मैं लिनक्स का उपयोग कर रहा हूं" अगर आप' टी 'मैन' पता नहीं है!) –

+5

'मैन 3 exec'। या शायद तुम्हारे लिए: 'आदमी आदमी' ...? वास्तव में पूछने के लिए –

उत्तर

4

सबसे अच्छा तरीका system() का उपयोग नहीं करना है। fork() और exec() और दोस्तों का उपयोग करें। यहाँ एक उदाहरण है:

#include <string> 
#include <unistd.h> 
#include <error.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <errno.h> 
#include <cstdlib> 

int fork_curl(char *line) 
{ 
    std::string linearg("line="); 
    linearg += line; 

    int pid = fork(); 
    if(pid != 0) { 
     /* We're in the parent process, return the child's pid. */ 
     return pid; 
    } 
    /* Otherwise, we're in the child process, so let's exec curl. */ 

    execlp("curl", "-b", "cookie.txt", "-d", linearg.c_str()); 
    /* exec is not supposed to return, so something 
     must have gone wrong. */ 
    exit(100); 
    /* Note: You should probably use an exit status 
     that doesn't collide with these used by curl, if possible. */ 
} 

int main(int argc, char* argv[]) 
{ 
    int cpid = fork_curl("test"); 
    if(cpid == -1) { 
     /* Failed to fork */ 
     error(1, errno, "Fork failed"); 
     return 1; 
    } 

    /* Optionally, wait for the child to exit and get 
     the exit status. */ 
    int status; 
    waitpid(cpid, &status, 0); 
    if(! WIFEXITED(status)) { 
     error(1, 0, "The child was killed or segfaulted or something\n"); 
    } 

    status = WEXITSTATUS(status); 
    /* Status now contains the exit status of the child process. */ 
} 
+1

क्या आप उन आदेशों के दस्तावेज़ीकरण के लिए एक लिंक प्रदान कर सकते हैं जिसका उपयोग करना चाहिए? या संभवतः उन आदेशों का उपयोग करने का उदाहरण दें? – cwd

+1

आप लिनक्स पर हैं, है ना? टर्मिनल में 'मैन 3 exec' टाइप करें :)। – Staven

+0

एक उदाहरण * अच्छा होगा * –

0

आप execl की कोशिश कर सकते ..

http://linux.about.com/library/cmd/blcmdl3_execvp.htm

#include <unistd.h> 

int execl(const char *path, const char *arg, ...); 
+0

शायद यही मुझे चाहिए। अगर मैं अपने प्रोग्राम को'/bin/echo' कमांड में पास किए गए चर को पास करना चाहता हूं, तो मैं यह कैसे करूँगा? (प्वाइंटलेस लेकिन चलिए इसे उदाहरण के रूप में उपयोग करते हैं) – cwd

+0

आपको परिभाषित करना चाहिए कि आपके लिए * चर * मतलब क्या है। एक बार जब आप अपने सिर में अच्छी तरह समझ गए तो उनका मतलब क्या है, आपने लगभग समस्या हल की है। –

4

कभी नहीं एक system कॉल में उपयोगकर्ता इनपुट गुजरती हैं। कभी।

आप उन सभी पात्रों से बचने की कोशिश कर सकते हैं जो आपको लगता है कि खतरनाक हैं, लेकिन आप इसे गलत समझेंगे।

इसके बजाय, दूसरी दिशा से उस पर जाना: उपयोगकर्ता इनपुट कि आपके द्वारा निर्धारित की एक चयन के किसी भी प्रदान करते हैं, तो एक switch करते हैं और खरोंच से अपने खुद के सिस्टम कॉल का निर्माण।

यह स्वीकार किया जाता है कि यह कम मुश्किल हो जाता है जब कमांड लाइन एप्लिकेशन को इनपुट करने के लिए इनपुट फ्रीफॉर्म होता है, लेकिन, वास्तविक पुस्तकालयों के लिए यही है। libcurl, कोई भी?

+0

क्या होगा यदि आपको किसी अन्य प्रोग्राम में आपके प्रोग्राम में पास किए गए चर को पारित करने की आवश्यकता हो? शायद फ़ाइल पथ? यही वह है जो मैं करने का प्रयास कर रहा हूं। कारण मैंने अभी तक नहीं किया है क्योंकि मुझे पता है कि यह "सुरक्षित" नहीं है और इसलिए मैं यह जानना चाहता हूं कि यह करने के लिए एक सुरक्षित (एआर) तरीका क्या है धन्यवाद। – cwd

+0

+1 कभी भी उपयोगकर्ता इनपुट पास करने के लिए +1 सिस्टम कॉल –

+1

आपका मतलब सिस्टम (3) के लिए एक कॉल है, सिस्कोल के रूप में एक syscall नहीं (2) –

0

सभी syscalls सूचीबद्ध करने वाले मैन पेज को देखें (सिस्टम कॉल system(3) फ़ंक्शन नहीं है जो एक खोल को फोर्क करता है)।

पढ़ें system calls और linux kernel, और operating systems

अपने प्रश्न पर वापस के समग्र संगठन और अधिक के बारे में है, तो आप खोल के लिए बोली सकता है (बस खोल भागने नियमों का पालन करें अपने तार को बदलने के लिए, उदाहरण के उपसर्ग किसी भी गैर के लिए बैकस्लैश के साथ अक्षर चरित्र)।

भी fork, execve मैन ऑफ द पृष्ठ देखें, आदि

advanced linux programming और प्रसिद्ध Advanced Unix Programming

पर एक अच्छी किताब पढ़ें एक लिनक्स वितरण पर सॉफ़्टवेयर का सबसे की स्वतंत्रता का प्रयोग करें। उदाहरण के लिए, आप sash जैसे साधारण खोल के स्रोत कोड का अध्ययन कर सकते हैं।

और शायद आप केवल कर्ल का उपयोग करना चाहते हैं। तो सबसे अच्छा तरीका है यह सब सीखने

मज़ा (system(3) के लिए किसी भी कॉल के बिना) libcurl पुस्तकालय के लिए कोड के लिए है!

+1

समस्या यह है कि हर गैर-पत्र से बचने के लिए पर्याप्त नहीं है। क्या होगा यदि एक दुर्भावनापूर्ण उपयोगकर्ता एक संशोधित पथ और/या आईएफएस के साथ एक सेटयूड प्रोग्राम लॉन्च करता है? – ninjalj

+0

मैं सहमत हूं, लेकिन कम से कम यह सवाल का जवाब देता है। मेरी भावना यह है कि पोस्टर को 'सिस्टम' का उपयोग नहीं करना चाहिए और न ही 'curl' प्रक्रिया काटना चाहिए, लेकिन' libcurl' –

+0

से फ़ंक्शंस को कॉल करना सीखें और आपका बाकी उत्तर काफी अच्छा है। लेकिन, वास्तव में, 'प्रणाली()' वास्तव में खतरनाक है। – ninjalj