I'm trying to display history of firefox and chrome using C Application .For the history of chrome , it works well because the Sql command doesn't contain symbols but with chrome My sql request contains symbols , So this function doesn't give me result .It give me error :
no such table :moz_historyvisits
Or ,when i test this request from the command prompt it works well . What i think that the problem is the sql request contains (_)symbols .
Rq : For chrome history it works well . CallbackFirefox is to function to display result
I'm using windows and Code blocks as an IDE . When i execute select name from sqlite_master
int DisplayFirefoxHistory()
{
sqlite3 *db;
char *err_msg = 0;
system("cd C:/Users/******/AppData/Roaming/Mozilla/Firefox/Profiles/*.default");
int rc = sqlite3_open("places.sqlite", &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Cannot open database: %s\n",sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
char *sql = "select url,datetime(visit_date/1000000-11644473600,'unixepoch') from moz_historyvisits,moz_places order by visit_date desc";
rc = sqlite3_exec(db, sql, callbackFirefox, NULL, &err_msg);
if (rc != SQLITE_OK ) {
fprintf(stderr, "Failed to select data\n");
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return 1;
}
sqlite3_close(db);
return 0;
}
system("cd C:/Users/******/AppData/Roaming/Mozilla/Firefox/Profiles/*.default");
system() starts a separate shell that is terminated after the command was executed, so this does not change the current directory of your actual program.
You should find out the directory name manually, and include it in the database file name.
Related
I want to make query like this one:
SELECT lyrics FROM cache WHERE author=%s0, title=%s1 LIMIT 1;
where strings %s0 and %s1 should be substituted. Assuming strings are not sanitized, UTF-8 encoded (As database itself), simple null-terminated char* arrays. What are my options to do this? Are there any built-in functions in SQLite (C API) for this?
Like mentioned in comments already prepared statements should be used.
Why Prepared Statements Should Be Favoured
When you create SQL queries yourself as a string, they almost always contain parts of a user's input. An attacker can take advantage of this by, for example, cleverly changing the semantics of the query using ' and thus gaining unauthorized access to data or destroying data.
This is called SQL injection and is one of the top most critical security risks, see here:
https://www.owasp.org/images/7/72/OWASP_Top_10-2017_%28en%29.pdf.pdf
Defense
The use of prepared statements with variable binding (aka parameterized queries) is how all developers should first be taught how to write database queries.
https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html#defense-option-1-prepared-statements-with-parameterized-queries
How to use prepared statements with SQLite
For prepared statements see https://www.sqlite.org/c3ref/stmt.html.
Basic steps are:
create the prepared statement
bind values to parameters
run the SQL
destroy the object to avoid resource leaks
Example
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
void exit_with_error(sqlite3 *db, const char * msg) {
fprintf(stderr, "%s: %s\n", msg, sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
int main() {
sqlite3 *db;
sqlite3_stmt *stmt;
int rc = sqlite3_open("path-to-lyrics", &db);
if (rc != SQLITE_OK)
exit_with_error(db, "can't open db: ");
//create prepared statement
rc = sqlite3_prepare_v2(db, "SELECT lyrics FROM cache WHERE author=?1 AND title=?2 LIMIT 1;", -1, &stmt, 0);
if (rc != SQLITE_OK)
exit_with_error(db, "failure fetching data: ");
//bind values to parameters
sqlite3_bind_text(stmt, 1, "Don Brownrigg", -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, "Just Breathe", -1, SQLITE_STATIC);
//run the SQL
rc = sqlite3_step(stmt);
if (rc == SQLITE_ROW) {
printf("%s\n", sqlite3_column_text(stmt, 0));
}
//destroy the object to avoid resource leaks
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
Build
With CMake it could look like this:
cmake_minimum_required(VERSION 3.14)
project(sqlitequery C)
set(CMAKE_C_STANDARD 99)
add_executable(sqlitequery main.c)
target_link_libraries (sqlitequery sqlite3)
On command line one could build with something like:
gcc -Wall -Wextra main.c -lsqlite3 -o sqlitequery
I'm trying to link sqlite3 library to CMakeList in Clion using the following code:
find_package(SQLite3)
target_link_libraries(IIWProject SQLite::SQLite3)
Library has been loaded but when i Run the code, Clion shows the following error:
SQL logic error
The database has been loaded but when sqlite3_prepare_v2(db, query, -1, &stmt, NULL) was called return SQL logic error
void get_db(sqlite3 **db){
int rc;
if ((rc = sqlite3_open("db_project.db", db)) != SQLITE_OK){
//fprintf(stderr, "Failed to open DB.\n");
fprintf(stderr,"Failed to open DB: %s\n\r", sqlite3_errstr(rc));
exit(EXIT_FAILURE);
}
}
int clear_table(sqlite3 *db){
sqlite3_stmt *stmt;
int rc;
char* query = "DELETE FROM resources";
if ((rc=sqlite3_prepare_v2(db, query, -1, &stmt, NULL)) != SQLITE_OK){
fprintf(stderr,"Failed to prepare statement: %s\n\r", sqlite3_errstr(rc));
return 1;
}
if ((rc = sqlite3_step(stmt)) != SQLITE_DONE){
fprintf(stderr,"Delete failed: %s\n\r", sqlite3_errstr(rc));
return 1;
}
return 0;
}
How can I try to fix it?
EDIT:
If I compile, without Clion manually, with gcc -lsqlite3,it work
Now that we've established that the table doesn't exist when you run your program though your IDE...
The current working directory when you run your program through a command line is different than the current working directory your IDE runs it in. Since you're using a relative path to the database file, this means you're using a different one depending on how you run your program. Only one of the databases actually has the table(s) you're trying to use.
Some solutions:
Use an absolute path to the database.
Configure your IDE to use the same working directory as when you're running your program through a command line.
I'm trying to load regexp.c extension in order to add REGEXP operator into sqlite. What I have done:
Download sqlite3 amalgamation file
Found regexp.c loadable extension
Created test project in VS2015
#include <stdio.h>
#include "stdafx.h"
#include "sqlite3.h"
const char* SQL = "SELECT load_extension('sqlite3.obj', 'sqlite3_regexp_init');";
int main(int argc, char **argv) {
sqlite3 *db = 0; // the hande of connection object to db
char *err = 0;
char *errMsg = "unable to load extension";
// open connection
if (sqlite3_open("my_cosy_database.dblite", &db))
fprintf(stderr, "Error during opening/creation DB: %s\n", sqlite3_errmsg(db));
/*else if (sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0))
{
fprintf(stderr, "Cannot enable extensions loading: %s\n", sqlite3_errmsg(db));
}*/
else if (sqlite3_enable_load_extension(db, 1))
{
fprintf(stderr, "Cannot enable extensions loading: %s\n", sqlite3_errmsg(db));
}
// execute SQL
else if (sqlite3_load_extension(db, "sqlite3.obj", "sqlite3_regexp_init", &errMsg))
{
fprintf(stderr, "Cannot load sqlite3_regexp_init extension: %s\n", sqlite3_errmsg(db));
}
else if (sqlite3_exec(db, SQL, callback, 0, &err))
{
fprintf(stderr, "Ошибка SQL: %sn", err);
sqlite3_free(err);
}
// close connection
sqlite3_close(db);
return 0;
}
Official documentation says: "For security reasons, extension loading is turned off by default. In order to use either the C-language or SQL extension loading functions, one must first enable extension loading using the sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION,1,NULL) C-language API in your application." So this is what I've done. The problem is that I got every time sqlite3_load_extension or sqlite3_exec is called. The same problem appears with commented sqlite3_enable_load_extension and uncommented sqlite3_db_config. I have no idea what causes this exception and there is no clear example of C api usage (even in 'Using Sqlite' book). One thing i could find out is the statement which causes this exception: "(pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/ IMP: R-24505-23230 */" in the SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe p / The VDBE */).
So please, help.
I'm having memory management related crashes when using SQLite. It only crashes once every 30 or so tries unless I enable Guard Malloc (a test mode) in Xcode, in which case it crashes the second time I prepare a statement, 100% of the time. I think it has to do with how I'm opening or using the database, but I can't find anything wrong, BUT I'm a newbie with SQLite. Is there anything I'm forgetting?
Wrapper function for opening:
int databaseConnect(sqlite3 **db){
int rc = sqlite3_open_v2(dbURL, db, SQLITE_OPEN_READWRITE, NULL);
if(rc!=SQLITE_OK){
fprintf(stderr, "Can't open database! Error: %s\n", sqlite3_errmsg(*db));
sqlite3_close_v2(*db);
return(SQL_ERROR);
}
return NO_ERROR;
}
Wrapper function for sending commands:
int databaseCommand(char* command, sqlite3* db){
char* error = NULL;
int ret = sqlite3_exec(db, command, NULL, 0, &error);
if (ret!=SQLITE_OK){
printf("SQL command aborted. Error: %s\n", error);
return SQL_ERROR; //EDIT: this will cause the database to close later
}
if (error) sqlite3_free(error);
return NO_ERROR;
}
How I use my opening function:
//ONCE IN MAIN THREAD, BEFORE ANY OTHER THREADS:
sqlite3* db = NULL;
databaseConnect(&db);
//call databaseCommmand a few times while creating tables...
sqlite3_close_v2(db);
//ONCE PER THREAD IN OTHER THREADS:
sqlite3* db = NULL; databaseConnect(&db);
How I use sqlite3_prepare_v2 in my non-main threads (and where it crashes):
struct LinkedList* databaseSelect(char* command, sqlite3* db){
sqlite3_stmt* stmt = NULL;
int retval = retval = sqlite3_prepare_v2(db,command,(strlen(command))*sizeof(char),&stmt,NULL); //crashes here the second time I run it
if(retval!=SQLITE_OK){
printf("Selecting data from database failed! Error: %s\n", sqlite3_errmsg(db));
sqlite3_free(stmt);
return NULL; //EDIT: this will cause the database to close later
}
// Then the function does stuff involving sqlite3_column_text and sqlite3_column_int…
sqlite3_free(stmt);
// return the linked list result
}
The error I get and the part of the SQLite3 library that causes it:
EXC_BAD_ACCESS (code=1) in this part of sqlite3.c:
/*
** Create a new virtual database engine.
*/
SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3 *db){
Vdbe *p;
p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
if( p==0 ) return 0;
p->db = db;
if( db->pVdbe ){
db->pVdbe->pPrev = p; //error is right here; db->pVdbe is pointing to invalid address
}
p->pNext = db->pVdbe;
p->pPrev = 0;
db->pVdbe = p;
p->magic = VDBE_MAGIC_INIT;
return p;
}
Whenever I use sqlite3_column_text, I copy the result immediately. I do not modify the result. In databaseCommand and databaseSelect, char* command is null-terminated and valid (I checked). Each thread uses its own database handle, each connected to the same database. However, in this test case, there is only one thread connected to the database at any given time.
If there really is nothing wrong here, I have to assume that I trampled the memory elsewhere in my program, and I can't find anything in the rest of the program that even looks a bit dangerous. Plus it's suspicious that SQLite is the one thing crashing every time.
The sqlite3_prepare_v2 documentation says:
The calling procedure is responsible for deleting the compiled SQL statement using sqlite3_finalize() after it has finished with it.
sqlite3_free() can be used only for raw memory allocated with sqlite3_alloc(), or when a function such as sqlite3_exec() is documented as requiring it.
Since you are using multiple threads operating on same database just make sure you close and reopen the database from these thread after every operation. You should also try not to neglect the error condition and add the close statement there also as shown below.
if(retval!=SQLITE_OK){
printf("Selecting data from database failed! Error: %s\n", sqlite3_errmsg(db));
sqlite3_free(stmt);
sqlite3_close(your_db_ptr);
......
}
sqlite3_prepare_v2() alone just compiles the SQL but does not run it. Call sqlite3_step() on the compiled statement to run it, or use sqlite3_exec() that combines prepare+step+finalize into one function call. From here.
Hope this helps.
TL;DR How do you send a string to cmd.exe, execute grep/findstr or sort, and then print the output using popen?
I have a client and server setup. The user enters a command, such as 'list X: | grep name', which is then broken into 'list X:' and 'grep name'. 'list X:' is sent to the server which then executes a list function and returns a char[] containing the list result. The client then needs to feed this into cmd.exe and execute the 'grep name' command on that data and print it out to the user. I don't need to return the data from cmd to the client process, just output it.
I know my code isn't trying to write at the moment (I'm opening the file in read mode) but I had tried a few other things and can't seem to send the data to cmd.exe)
Code is as follows:
...
int n = recv(clientSocket, reply, sizeof(reply), 0);
std::string* cmdStr = new std::string(cmd);
cmdStr->erase(std::remove(cmdStr->begin(), cmdStr->end(), '\n'), cmdStr->end());
if(cmdStr->compare("") != 0) //Something to pipe to command
{
char pipeBuffer[8192];
FILE* pipe;
char c [8192];
strcat(c, "cmd.exe /C ");
strcat(c, reply);
strcat(c, " | ");
strcat(c, cmdStr->c_str());
if((pipe = _popen(c, "r")) == NULL)
{
printf("Unable to create pipe!\n");
}
while(!feof(pipe))
{
if(fgets(pipeBuffer, 8192, pipe) != NULL)
{
printf(pipeBuffer);
}
}
}
...
I ended up fixing it with this, just in case anyone else runs into a similar problem:
FILE* pipe;
if((pipe = _popen(cmdStr->c_str(), "w")) == NULL)
{
printf("Unable to create pipe!\n");
}
fprintf(pipe, "%s", reply);
printf("\nPipe process returned %d\n", _pclose(pipe));
well, if your application is already running as a console, you can use the function system() that executes a command on CMD, if not, you can simulate a console using AllocConsole() and then using system(), if you want to really emulate, you can use pipes