【问题标题】:Using variables in system() function c++在 system() 函数 c++ 中使用变量
【发布时间】:2011-06-21 22:10:13
【问题描述】:


  string line;
  ifstream myfile ("aaa.txt");
  getline (myfile,line);
  system("curl.exe -b cookie.txt -d test="+line+"  @987654321@");

而且它不起作用!我也试过 line.c_str();但它也没有工作。请帮帮我。

【问题讨论】:

  • 投反对票,因为将变量传递给 system()非常危险。在 Win32 上使用 spawn(),在 *nix 上使用 fork()/exec()posix_spawn()
  • @ninjalj 系统的安全性与问题无关。每次出现与 system() 相关的 SO 问题时,都必须有人对安全性发表评论,有时人们(比如你)会否决它。它没有任何贡献,只会使页面混乱。问题是“如何”使用 system(),而不是关于使用它的最佳方式的问题。 “改用其他东西”不是有用的评论。

标签: windows curl system c++


【解决方案1】:

使用字符串流构建您传递给system() 的字符串!

#include <sstream>
#include <fstream>
#include <string>
using namespace std;

int main(void){
    string line;
    ifstream myfile("aaa.txt");
    getline(myfile,line);
    stringstream call_line;
    call_line << "curl.exe -b cookie.txt -d test=" << line << "  http://example.com");
    system(call_line.str().c_str());
}

【讨论】:

  • @ninjalj:所以,我们知道如果允许任意用户输入,使用system() 是危险的。这不会改变 OP 想要从文件中组装输入的事实。如果文件受到保护以防止用户访问怎么办?如果它实际上是从数据库或其他东西中读取的呢?我们不知道也不关心,安全是 OP 责任的一部分。这不是投反对票的理由。我可以删除system() 调用,只显示字符串组装。现在呢?
  • 您可以告诉 OP 使用每个参数独立的 API,并且不使用底层 shell 来解析命令行。
【解决方案2】:

问题一:

您的问题源于system 是签名:

int system (const char *command);

你拥有的是std::string类型。

解决此问题的一种方法是构建一个新的std::string,然后使用c_str() 获取字符指针。

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

然后将内容传递给system

system(cmd.c_str());

问题 2:

读取数据并将未经验证和不干净的数据传递给 system 将允许任何使用您的程序的人在 shell 上运行命令。

这是一个安全风险。

【讨论】:

  • system cals 和在 cmd.exe 中输入命令不一样吗?
  • @Xeo:是的,如果你将foo &amp; fire_nukes.exe &amp; REM 传递给他的程序,它将运行 curl.exe,然后尝试运行 fire_nukes.exe。在 *nix 上看起来会略有不同,但想法是一样的。
【解决方案3】:

它不起作用,因为您将 C++ 字符串传递给 C 函数 system()。 c_str() 可以提供帮助,但您应该将其应用于整个字符串:

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

如下面的 cmets 所述,将随机变量传递给 system() 可能非常危险,因此只有在确切知道其中可能包含的内容时才应该这样做。如果它是由用户提供或从网络接收的,您可能不应该这样做。将字符串通过某种“转义”函数或使用 spawn()/exec()/其他任何不将其传递给 shell 的方法。

【讨论】:

  • 我发现添加int system(std::string const&amp; s) { return s.c_str(); } 重载会更简洁。
  • @MSalters,你的意思是int system(std::string const&amp; s) {return system(s.c_str());}吗?是的,这看起来是个好主意。
  • @ninjalj,问题是关于 如何 在这样的调用中使用变量,而不是它是否危险。事实上,这个家伙从文件中读取变量,而不是直接从用户或网络中读取,这并不一定是危险的。这取决于他从哪里得到这个文件。如果它是由同一个应用程序生成的临时文件并且无法从外部访问,我想这很好。虽然我同意我应该提到可能的危险。
  • 既然您已经清楚地警告过 system() 的危险,我已经删除了反对票。目前,该问题的浏览量约为 350 次,我们不希望 SO 成为不良做法的资源。
猜你喜欢
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-04
相关资源
最近更新 更多