#include <libpq-fe.h> #define UPDATE_COMMAND \ "UPDATE employee SET password='%s' WHERE username='%s';" int db_update(char *username, char *password) { PGconn *conn; PGresult *res; ExecStatusType status; char query[1024]; // connect to server /* * Set parameter */ snprintf(query, sizeof(query), UPDATE_COMMAND, password, username); /* * Execute the query. */ res = PQexec(conn, query); if (res) { status = PQresultStatus(res); if (status == PGRES_COMMAND_OK)) { printf("Update successfully\n"); } else { printf("error message=[%s]\n", PQresultErrorMessage(res)); } } }初學者容易犯的錯誤就是把 user input 直接跟 SQL query 串接在一起,如果 username, password 存在不安全的字眼,很有可能會造成 SQL injection,切記永遠不要相信 user 的資料,該做的檢查、防呆都不能少。
改成參數形式就可以避免 :)
Database client library 都會有提供類似的用法
#include <libpq-fe.h> #define UPDATE_COMMAND \ "UPDATE employee SET password=$1 WHERE username=$2;" #define PREPARED_STMT "my_update" #define NPARAMS 2 int db_update(char *username, char *password) { PGconn *conn; PGresult *res; ExecStatusType status; char *params[NPARAMS]; // connect to server /* * Set parameter */ params[0] = password; params[1] = username; res = PQprepare(conn, PREPARED_STMT, UPDATE_COMMAND, NPARAMS, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { printf("PQprepare() failed [%s]", PQresultErrorMessage(res)); return -1; } /* * Execute the query. */ res = PQexecPrepared(conn, PREPARED_STMT, NPARAMS, (const char **)params, NULL, NULL, 0); if (res) { status = PQresultStatus(res); if (status == PGRES_COMMAND_OK)) { printf("Update successfully\n"); } else { printf("error message=[%s]\n", PQresultErrorMessage(res)); } } }關於 PQprepare()、PQexecPrepared() 的使用方式可以參考官方文件
沒有留言:
張貼留言