views:

429

answers:

1

I'm building a class wrapper for the mysql c api, specifically at the moment for mysql_real_escape_string and I don't think I'm doing it quite right.

this is what I have for the function:

std::string Database::EscapeString(const char *pStr)
{
    char *tStr = new char[strlen(pStr)*2+1];
    mysql_real_escape_string(m_sqlCon, tStr, pStr, strlen(pStr));
    string retStr(tStr);
    delete [] tStr;
    return retStr;
}

I tried running this through but it did not perform as expected and ended in mysql errors.

+1  A: 

Looks good to me. I suspect your database problem is elsewhere.

There's an easy way to check: temporarily replace Database::EscapeString with a dummy function, i.e.

std::string Database::EscapeString(const char *pStr) {return string(pStr);}

Then see if you get the same errors.

Edit: Not knowing exactly what the error is, or what the query causing it is, it's tough to narrow down the problem. Here are some things to try:

A) Just get rid of all characters that would need to be escaped. It'll put bogus data into the database, but hopefully you're just testing anyways:

std::string Database::EscapeString(const char *pStr) {
    string result;
    while (*pStr) {
        if (strchr("\"'\r\n\t",*pStr))
        {
            //bad character, skip
        }
        else
        {
            result.push_back(*pStr);
        }
        ++pStr;
    }
    return result;
}

B) Look for errors elsewhere. Is Database::Execute coded well? Maybe it does a snprintf internally with a hardcoded buffer size (which you may be exceeding)

C) Try taking your debug output and entering it straight into the mysql client program (don't forget to put a semicolon at the end). Same error?

Managu
When/if you do this, make sure the strings you pass in don't contain any characters that need be escaped (e.g. quote marks)
Managu
I get the same type of error but in different locations of the string when not using mysql_real_escape_string.Erorr: 20:46:36 E Database: Database Query Failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's leading design team, mixed with fear among the next lower ranking support staf' at line 1
Undawned
Gotta quote that string. E.g. "INSERT INTO table (string_column) VALUES (somebodys leading design team, mixed with fear amoung the next lower ranking support staf)" is invalid SQL.
Managu
quoting the string, and escaping it are two different processes
Managu
It is quoted as far as I can tell: MainDatabase.ExecuteQuery("INSERT INTO `changelog` (`TypeId`, `TypeName`, `Misc`, `Author`, `Description`, `IconName`) VALUES('%u', '%s', '%u', '%s', '%s', '%s')", Data->m_typeId, RevTypeNames[Data->m_typeId], Data->m_revVer, Data->m_revAuthor.c_str(), revDesc.c_str(), Data->m_revIcon.c_str()); <- revDesc would be the string returned from mysql_real_escape_string
Undawned
Also: it appears to me that your string has an apostrophe in it. That would need to be escaped (see above comment about not passing in characters that need to be escaped, while doing this diagnostic ;-)
Managu
The code works fine without escaping, it's used on a daily basis, but this would be the first time something that needs to be escaped needed to be ran through it.
Undawned
Hrmm, ok. Why don't you add the full query (e.g. put in a diagnostic printf mirroring the MainDatabase.ExecuteQuery statement) and error message (with the EscapeString method you originally posted) to your original post.
Managu
I'm unable to do that as it contains sensitive project information.I did find several \r\n\r\n when I dumped the data into a file rather than SQL near where it indicated the errors were, would these have anything to do with the issue?
Undawned
I should mention, the above statement I mad about the filedump was referring to the escape string'd version, which gives the same type of SQL error, but in a different location, just before those \'s start.
Undawned
Doesn't sound like a problem to me. I've made a few changes to my answer
Managu
Ah thank you sir, you've hit the nail on the head with option C.My buffer was originally too small (1024) I did change this value when the problem arose but forgot to change the second reference to the value @ the sprintf location.
Undawned