【问题标题】:Replacing some chars in a string替换字符串中的一些字符
【发布时间】:2011-10-07 14:36:17
【问题描述】:

如果我有这样的变量:

char *sql;
sql = "insert into Norm1Tab values (?,?,?,?,?,?)";

我想用存储在其他charchar* 变量中的值替换每个?。我如何在 C++ 中做到这一点?

【问题讨论】:

  • 不要。改用准备好的语句/参数查询,我很确定您用来访问数据库的 API 允许它们。
  • 拼命猜测 OP 正在使用什么:sqlite.org/c3ref/prepare.html
  • 您不应该将字符串文字分配给非const char*。您是否关闭了所有编译器警告? std::string 有什么问题吗?

标签: c++ string


【解决方案1】:

在 C++ 中不要使用 char* C 风格的字符串。如果你使用std::string,你可以使用findreplace来做你想做的事。

但请不要那样做。您将面临一百万次 SQL 注入攻击。改用带有绑定参数的预处理语句。

【讨论】:

    【解决方案2】:

    如果您使用的是 sqlite(肯定看起来像),您不必自己替换字符串。请改用sqlite3_bind_*

    bind documentation

    使用您的数据库提供商提供的 API 有很多好处,因此如果您能提供帮助,您真的不应该避免使用它们。您将拥有更好的类型安全性、更好的注入保护以及更好的性能。

    否则,我会使用boost::format

    std::string sql = "insert into Norm1Tab values ('%1%','%2%');";
    boost::format fmt(sql);
    std::string stmt = boost::str( fmt % param1 % param2 );
    

    正如其他人所提到的,您需要清理参数以确保没有任何注入漏洞。

    如果你不这样做,任何带有特殊字符的东西都可能会破坏它。

    char const* param1 = "Joe's House";
    

    破坏它需要一些结构知识。一旦有人看到来自Joe's House 的错误消息,他们可能就会知道他们可以做得更糟。

    char const* param1 = "'); DROP Norm1Tab; --";
    

    如果您始终如一地这样做,那么聪明的人将拥有您的完整架构只是时间问题。以 sqlite 为例,对查询的任何注入都可以为您提供所需的所有信息,以便以他们想要的任何方式悄悄地修改您的记录。

    SELECT * FROM sqlite_master;
    

    【讨论】:

    • 您能否举例说明如何利用我询问的注入恶意代码的方式,而不能利用准备好的方式!
    • @Adban: char const* param1 = "'); DROP Norm1Tab; --"; 有时有效。否则,至少您可以阻止查询工作。
    • @Adban 更新了一些示例。如果您需要有关如何清理输入的详细信息,您可能应该提出一个单独的问题。 SQL 人群也会告诉你使用存储过程和数据库 API。 :)
    【解决方案3】:

    您可以放置​​ %s 并使用 sprintf 填充字段...

    但是,对于手头的问题,您可能需要准备好的语句...

    【讨论】:

      【解决方案4】:

      如果您坚持这样做(而不是使用 Matteo Italia 的第一条评论),请查看此处的解决方案:

      How do I Search/Find and Replace in a standard string?

      这不是您所需要的,但它显示了如何使用 .find() 获取问号的位置,并使用 .replace 将问号替换为字符缓冲区的内容。

      【讨论】:

        猜你喜欢
        • 2011-02-20
        • 2012-04-19
        • 1970-01-01
        • 1970-01-01
        • 2011-02-21
        • 1970-01-01
        • 2018-08-23
        • 2011-04-10
        • 2014-05-08
        相关资源
        最近更新 更多