Description:
When using mysql++ libray, using Connection with no exceptions, and trying to get a SSQLS set from a mysql server, but passing a wrong table name, you get a Segmentation Fault.
Following is an example of execution using mysql++ 3.0.8. Similar results are obtained with mysql++ 3.0.9:
(gdb) run EJEMPLO localhost root ""
Starting program: /home/jk/kk/sample EJEMPLO localhost root ""
[Thread debugging using libthread_db enabled]
[New Thread 0xb7fe3730 (LWP 2999)]
There are rows in Table_A
Program received signal SIGSEGV, Segmentation fault.
mysql_fetch_row (res=0x0) at client.c:2917
2917 if (!res->data)
(gdb) bt
#0 mysql_fetch_row (res=0x0) at client.c:2917
#1 0x00139380 in mysqlpp::DBDriver::fetch_row () at lib/dbdriver.h:209
#2 mysqlpp::UseQueryResult::fetch_raw_row (this=0xbffff1a0) at lib/result.cpp:205
#3 0x0804e45f in mysqlpp::Query::storein_set<std::set<stock, std::less<stock>, std::allocator<stock> > > ()
#4 0x0804e615 in mysqlpp::Query::storein<stock> ()
#5 0x0804e672 in mysqlpp::Query::storein<std::set<stock, std::less<stock>, std::allocator<stock> > > ()
#6 0x0804af24 in main ()
How to repeat:
Use MySQL++ 3.0.9. and do not use exceptions.
Test the following code. You should create a table named Table_A with two fields, item CHAR and num BIGINT. Run the program with 4 arguments: database, server, user and password.
#include <mysql++.h>
#include <ssqls.h>
using namespace std;
sql_create_2(stock,
1,2,
mysqlpp::sql_char, item,
mysqlpp::sql_bigint, num);
int main (int argc, char *argv[])
{
const char *db=0, *server=0, *user=0, *pass="";
if(argc != 5) {
cerr << "Bad args" << endl;
return 1;
}
db=argv[1];
server=argv[2];
user=argv[3];
pass=argv[4];
//Establish the connection to the database server, NO EXCEPTIONS
mysqlpp::Connection con(false);
if(!con.connect(db, server, user, pass)) {
cerr << "Connection error: " << con.error() << endl;
}
//Create and insert a stock object
stock row("Hot Dogs",100);
stock::table("Table_A");
mysqlpp::Query query=con.query();
query.insert(row);
query.execute();
//Get all the rows in the table
query.reset();
query << "select * from Table_A";
set<stock> res1;
query.storein(res1); //---OK---
if(res1.size() > 0) cout << "There are rows in Table_A" << endl;
//Get all rows in a table that doesn't exist
query.reset();
query << "select * from NonExistentTable";
set<stock> res2;
query.storein(res2); //--- Segmentation fault ---
if(res2.size() > 0) cout << "There are rows in NonExistentTable" << endl;
return 0;
}
Suggested fix:
In lib/query.h file, there is no check for the return value from "use" method in storein_set and storein_sequence methods:
UseQueryResult result =use(s);
while (1) {
MYSQL_ROW d=result.fetch_raw_row();
...
If the query is wrong, result is NULL and SIGSEGV is signaled.
The simplest fix could be the following -in storein_set and storein_sequence-:
UseQueryResult result =use(s);
if (result)
{
while (1) {
MYSQL_ROW d=result.fetch_raw_row();
...
But maybe some other lines inside the while loop could be revised, similar to the code for "store_if" method in lib/query.h.
Description: When using mysql++ libray, using Connection with no exceptions, and trying to get a SSQLS set from a mysql server, but passing a wrong table name, you get a Segmentation Fault. Following is an example of execution using mysql++ 3.0.8. Similar results are obtained with mysql++ 3.0.9: (gdb) run EJEMPLO localhost root "" Starting program: /home/jk/kk/sample EJEMPLO localhost root "" [Thread debugging using libthread_db enabled] [New Thread 0xb7fe3730 (LWP 2999)] There are rows in Table_A Program received signal SIGSEGV, Segmentation fault. mysql_fetch_row (res=0x0) at client.c:2917 2917 if (!res->data) (gdb) bt #0 mysql_fetch_row (res=0x0) at client.c:2917 #1 0x00139380 in mysqlpp::DBDriver::fetch_row () at lib/dbdriver.h:209 #2 mysqlpp::UseQueryResult::fetch_raw_row (this=0xbffff1a0) at lib/result.cpp:205 #3 0x0804e45f in mysqlpp::Query::storein_set<std::set<stock, std::less<stock>, std::allocator<stock> > > () #4 0x0804e615 in mysqlpp::Query::storein<stock> () #5 0x0804e672 in mysqlpp::Query::storein<std::set<stock, std::less<stock>, std::allocator<stock> > > () #6 0x0804af24 in main () How to repeat: Use MySQL++ 3.0.9. and do not use exceptions. Test the following code. You should create a table named Table_A with two fields, item CHAR and num BIGINT. Run the program with 4 arguments: database, server, user and password. #include <mysql++.h> #include <ssqls.h> using namespace std; sql_create_2(stock, 1,2, mysqlpp::sql_char, item, mysqlpp::sql_bigint, num); int main (int argc, char *argv[]) { const char *db=0, *server=0, *user=0, *pass=""; if(argc != 5) { cerr << "Bad args" << endl; return 1; } db=argv[1]; server=argv[2]; user=argv[3]; pass=argv[4]; //Establish the connection to the database server, NO EXCEPTIONS mysqlpp::Connection con(false); if(!con.connect(db, server, user, pass)) { cerr << "Connection error: " << con.error() << endl; } //Create and insert a stock object stock row("Hot Dogs",100); stock::table("Table_A"); mysqlpp::Query query=con.query(); query.insert(row); query.execute(); //Get all the rows in the table query.reset(); query << "select * from Table_A"; set<stock> res1; query.storein(res1); //---OK--- if(res1.size() > 0) cout << "There are rows in Table_A" << endl; //Get all rows in a table that doesn't exist query.reset(); query << "select * from NonExistentTable"; set<stock> res2; query.storein(res2); //--- Segmentation fault --- if(res2.size() > 0) cout << "There are rows in NonExistentTable" << endl; return 0; } Suggested fix: In lib/query.h file, there is no check for the return value from "use" method in storein_set and storein_sequence methods: UseQueryResult result =use(s); while (1) { MYSQL_ROW d=result.fetch_raw_row(); ... If the query is wrong, result is NULL and SIGSEGV is signaled. The simplest fix could be the following -in storein_set and storein_sequence-: UseQueryResult result =use(s); if (result) { while (1) { MYSQL_ROW d=result.fetch_raw_row(); ... But maybe some other lines inside the while loop could be revised, similar to the code for "store_if" method in lib/query.h.