1

If I have a variable like:

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

I would like to replace each ? by values that are stored in other char or char* variables. How I can do that in C++ ?

Aan
  • 12,247
  • 36
  • 89
  • 150
  • 10
    Don't. Use prepared statements/parametric queries instead, I'm quite sure that the APIs you are using to access the DB allows them. – Matteo Italia Oct 07 '11 at 14:36
  • Out on a limb guessing what the OP is using: http://www.sqlite.org/c3ref/prepare.html – sehe Oct 07 '11 at 14:38
  • You're not supposed to assign string literals to non-`const` `char*`. Do you have all your compiler warnings turned off? And is there something wrong with `std::string`? – Lightness Races in Orbit Oct 07 '11 at 14:39

4 Answers4

8

In C++ don't use char* C-style strings. If you use std::string you can use find and replace to do what you want.

But please don't do that. You'll just open yourself up to a million SQL injection attacks. Use prepared statements with bound parameters instead.

Mark B
  • 95,107
  • 10
  • 109
  • 188
1

If you are using sqlite (sure looks like it), you do not have to do the string replaces yourself. Use sqlite3_bind_* instead.

bind documentation

There are a lot of benefits from using the APIs from your database provider, so you really shouldn't avoid them if you can help it. You'll have better type safety, better protection against injection, and way better performance.

Otherwise, I would use boost::format for this.

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

As mentioned by others, you'll need to clean your params to make sure there aren't any injection vulnerabilities.

If you don't, anything with special characters could break it.

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

It would take some knowledge of the structure to destroy it. As soon as someone saw the error message from the Joe's House, they would probably know that they could do worse.

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

If you do this consistently, it is only a matter of time before a smart person is going to have your full schema. With sqlite for instance, any injection on a query could get you all the information you needed to quietly modify your records in any way that they wanted.

SELECT * FROM sqlite_master;
Tom Kerr
  • 10,444
  • 2
  • 30
  • 46
  • Can you please give examples how one can exploit the way I asked about to inject malcode, and can't exploit the prepared way! – Aan Oct 07 '11 at 15:48
  • 1
    @Adban: `char const* param1 = "'); DROP Norm1Tab; --";` sometimes works. Otherwise at the very least you can stop the query from working. – Lightness Races in Orbit Oct 07 '11 at 16:06
  • @Adban Updated with some examples. If you need specifics on how to scrub your inputs, you probably should ask a separate question. The SQL crowd will tell you to use stored procedures and the database API as well though. :) – Tom Kerr Oct 07 '11 at 16:26
0

You could put %s and use sprintf to populate the fields ...

However, for the problem at hand, you probably want a prepared statement ...

Foo Bah
  • 25,660
  • 5
  • 55
  • 79
0

If you're adamant about doing it this way (as opposed to using the first comment by Matteo Italia), check the solution found here:

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

It's not quite what you need, but it shows how to can use .find() to get the location of the question mark and .replace to replace the question mark with the contents of your character buffers.

Community
  • 1
  • 1
John Humphreys
  • 37,047
  • 37
  • 155
  • 255