AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Global test fixtures */7static sqlite3 *gDb = NULL;8static Parse gParse;9 10/* Authorizer state and callback used for tests */11typedef struct AuthState {12 int call_count;13 int last_code;14 const char *last_a1;15 const char *last_a2;16 const char *last_a3;17 const char *last_ctx;18 int next_rc;19} AuthState;20 21static int testAuthCb(void *pArg, int code,22 const char *zArg1, const char *zArg2, const char *zArg3,23 const char *zContext){24 AuthState *st = (AuthState*)pArg;25 if( st ){26 st->call_count++;27 st->last_code = code;28 st->last_a1 = zArg1;29 st->last_a2 = zArg2;30 st->last_a3 = zArg3;31 st->last_ctx = zContext;32 return st->next_rc;33 }34 return SQLITE_OK;35}36 37/* Helper to clear any error message set in Parse */38static void clearParseError(void){39 if( gParse.zErrMsg ){40 sqlite3DbFree(gDb, gParse.zErrMsg);41 gParse.zErrMsg = 0;42 }43 gParse.rc = 0;44}45 46void setUp(void) {47 int rc = sqlite3_open(":memory:", &gDb);48 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);49 memset(&gParse, 0, sizeof(gParse));50 gParse.db = gDb;51 gParse.zErrMsg = 0;52 gParse.rc = 0;53 /* Ensure no authorizer installed by default */54 sqlite3_set_authorizer(gDb, NULL, NULL);55 /* Ensure init.busy is not set */56 gDb->init.busy = 0;57}58 59void tearDown(void) {60 clearParseError();61 sqlite3_set_authorizer(gDb, NULL, NULL);62 if( gDb ){63 sqlite3_close(gDb);64 gDb = NULL;65 }66 memset(&gParse, 0, sizeof(gParse));67}68 69/* Tests */70 71void test_sqlite3AuthCheck_no_authorizer_returns_ok(void){72 /* Ensure no authorizer is set */73 sqlite3_set_authorizer(gDb, NULL, NULL);74 75 int rc = sqlite3AuthCheck(&gParse, SQLITE_SELECT, "t1", "c1", "main");76 77 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);78 TEST_ASSERT_EQUAL_INT(0, gParse.rc);79 TEST_ASSERT_NULL(gParse.zErrMsg);80}81 82void test_sqlite3AuthCheck_calls_authorizer_and_params_ok(void){83 AuthState st;84 memset(&st, 0, sizeof(st));85 st.next_rc = SQLITE_OK;86 const char *a1 = "T1";87 const char *a2 = "C1";88 const char *a3 = "main";89 const char *ctx = "CTX";90 gParse.zAuthContext = ctx;91 92 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_set_authorizer(gDb, testAuthCb, &st));93 94 int rc = sqlite3AuthCheck(&gParse, SQLITE_SELECT, a1, a2, a3);95 96 TEST_ASSERT_EQUAL_INT(1, st.call_count);97 TEST_ASSERT_EQUAL_INT(SQLITE_SELECT, st.last_code);98 TEST_ASSERT_EQUAL_STRING(a1, st.last_a1);99 TEST_ASSERT_EQUAL_STRING(a2, st.last_a2);100 TEST_ASSERT_EQUAL_STRING(a3, st.last_a3);101 TEST_ASSERT_NOT_NULL(st.last_ctx);102 TEST_ASSERT_EQUAL_STRING(ctx, st.last_ctx);103 104 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);105 TEST_ASSERT_EQUAL_INT(0, gParse.rc);106 TEST_ASSERT_NULL(gParse.zErrMsg);107}108 109void test_sqlite3AuthCheck_ignore_propagated(void){110 AuthState st;111 memset(&st, 0, sizeof(st));112 st.next_rc = SQLITE_IGNORE;113 gParse.zAuthContext = "CTX2";114 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_set_authorizer(gDb, testAuthCb, &st));115 116 int rc = sqlite3AuthCheck(&gParse, SQLITE_UPDATE, "T", "C", "main");117 118 TEST_ASSERT_EQUAL_INT(1, st.call_count);119 TEST_ASSERT_EQUAL_INT(SQLITE_IGNORE, rc);120 TEST_ASSERT_EQUAL_INT(0, gParse.rc);121 TEST_ASSERT_NULL(gParse.zErrMsg);122}123 124void test_sqlite3AuthCheck_deny_sets_auth_error_and_message(void){125 AuthState st;126 memset(&st, 0, sizeof(st));127 st.next_rc = SQLITE_DENY;128 gParse.zAuthContext = "CTX3";129 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_set_authorizer(gDb, testAuthCb, &st));130 131 int rc = sqlite3AuthCheck(&gParse, SQLITE_DELETE, "T2", "C2", "temp");132 133 TEST_ASSERT_EQUAL_INT(1, st.call_count);134 TEST_ASSERT_EQUAL_INT(SQLITE_DENY, rc);135 TEST_ASSERT_EQUAL_INT(SQLITE_AUTH, gParse.rc);136 TEST_ASSERT_NOT_NULL(gParse.zErrMsg);137 TEST_ASSERT_EQUAL_STRING("not authorized", gParse.zErrMsg);138 139 clearParseError();140}141 142void test_sqlite3AuthCheck_illegal_return_sets_malfunction_error(void){143 AuthState st;144 memset(&st, 0, sizeof(st));145 st.next_rc = 12345; /* Invalid return code */146 gParse.zAuthContext = "CTX4";147 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_set_authorizer(gDb, testAuthCb, &st));148 149 int rc = sqlite3AuthCheck(&gParse, SQLITE_INSERT, "T3", "C3", "main");150 151 TEST_ASSERT_EQUAL_INT(1, st.call_count);152 TEST_ASSERT_EQUAL_INT(SQLITE_DENY, rc); /* coerced to DENY */153 TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, gParse.rc); /* malfunction error */154 TEST_ASSERT_NOT_NULL(gParse.zErrMsg);155 TEST_ASSERT_EQUAL_STRING("authorizer malfunction", gParse.zErrMsg);156 157 clearParseError();158}159 160void test_sqlite3AuthCheck_init_busy_skips_authorizer(void){161 AuthState st;162 memset(&st, 0, sizeof(st));163 st.next_rc = SQLITE_DENY; /* Would error if actually called */164 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_set_authorizer(gDb, testAuthCb, &st));165 166 gDb->init.busy = 1; /* Simulate initialization */167 168 int rc = sqlite3AuthCheck(&gParse, SQLITE_SELECT, "T4", "C4", "main");169 170 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);171 TEST_ASSERT_EQUAL_INT(0, st.call_count);172 TEST_ASSERT_EQUAL_INT(0, gParse.rc);173 TEST_ASSERT_NULL(gParse.zErrMsg);174 175 gDb->init.busy = 0; /* Reset */176}177 178void test_sqlite3AuthCheck_null_arguments_and_context_forwarded(void){179 AuthState st;180 memset(&st, 0, sizeof(st));181 st.next_rc = SQLITE_OK;182 gParse.zAuthContext = NULL;183 184 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_set_authorizer(gDb, testAuthCb, &st));185 186 int rc = sqlite3AuthCheck(&gParse, SQLITE_PRAGMA, NULL, NULL, NULL);187 188 TEST_ASSERT_EQUAL_INT(1, st.call_count);189 TEST_ASSERT_EQUAL_INT(SQLITE_PRAGMA, st.last_code);190 TEST_ASSERT_NULL(st.last_a1);191 TEST_ASSERT_NULL(st.last_a2);192 TEST_ASSERT_NULL(st.last_a3);193 TEST_ASSERT_NULL(st.last_ctx);194 195 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);196 TEST_ASSERT_EQUAL_INT(0, gParse.rc);197 TEST_ASSERT_NULL(gParse.zErrMsg);198}199 200int main(void) {201 UNITY_BEGIN();202 RUN_TEST(test_sqlite3AuthCheck_no_authorizer_returns_ok);203 RUN_TEST(test_sqlite3AuthCheck_calls_authorizer_and_params_ok);204 RUN_TEST(test_sqlite3AuthCheck_ignore_propagated);205 RUN_TEST(test_sqlite3AuthCheck_deny_sets_auth_error_and_message);206 RUN_TEST(test_sqlite3AuthCheck_illegal_return_sets_malfunction_error);207 RUN_TEST(test_sqlite3AuthCheck_init_busy_skips_authorizer);208 RUN_TEST(test_sqlite3AuthCheck_null_arguments_and_context_forwarded);209 return UNITY_END();210}