diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index b07d6c6..7cb498b 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -887,6 +887,12 @@ exec_simple_query(const char *query_string) bool was_logged = false; bool isTopLevel; char msec_str[32]; + ListCell *parsetree_head_cell; + ListCell *parsetree_tail_cell; + const char *commandTagHead; + const char *commandTagTail; + Node *parsetreehead; + Node *parsetreetail; /* @@ -932,7 +938,29 @@ exec_simple_query(const char *query_string) * we are in aborted transaction state!) */ parsetree_list = pg_parse_query(query_string); + /* + * we use head and tail cell for checking weather it is a transaction + * block or not + */ + parsetree_head_cell = list_head(parsetree_list); + parsetree_tail_cell = list_tail(parsetree_list); + parsetreehead = (Node *) lfirst(parsetree_head_cell); + parsetreetail = (Node *) lfirst(parsetree_tail_cell); + /* + * figure out head and tail command type + */ + commandTagHead = CreateCommandTag(parsetreehead); + commandTagTail = CreateCommandTag(parsetreetail); + /* + * We only allow a single user query or a transaction block per call . + * This is provide an additional defense against SQL-injection attacks. + */ + if ((list_length(parsetree_list) > 1) + && (strcmp(commandTagHead, "BEGIN") != 0) + && (strcmp(commandTagTail, "COMMIT") != 0)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), errmsg("cannot execute multiple commands unless it is a transaction block"))); /* Log immediately if dictated by log_statement */ if (check_log_statement(parsetree_list)) {