AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Helper authorizer that denies SELECT/READ */7static int deny_select_or_read(void *pArg, int code,8 const char *z1, const char *z2,9 const char *z3, const char *z4){10 (void)pArg; (void)z1; (void)z2; (void)z3; (void)z4;11 if( code==SQLITE_SELECT || code==SQLITE_READ ){12 return SQLITE_DENY;13 }14 return SQLITE_OK;15}16 17/* Helper struct and authorizer that logs usage */18typedef struct AuthLog {19 int callCount;20 int lastCode;21 void *seenArg;22} AuthLog;23 24static int log_authorizer(void *pArg, int code,25 const char *z1, const char *z2,26 const char *z3, const char *z4){27 (void)z1; (void)z2; (void)z3; (void)z4;28 AuthLog *L = (AuthLog*)pArg;29 if( L ){30 L->callCount++;31 L->lastCode = code;32 L->seenArg = pArg;33 }34 return SQLITE_OK;35}36 37void setUp(void) {38 /* No-op */39}40void tearDown(void) {41 /* No-op */42}43 44#ifndef SQLITE_OMIT_AUTHORIZATION45 46static sqlite3* open_in_memory_db(void){47 sqlite3 *db = NULL;48 int rc = sqlite3_open(":memory:", &db);49 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open(:memory:) failed");50 return db;51}52 53void test_sqlite3_set_authorizer_sets_and_clears_fields(void){54 sqlite3 *db = open_in_memory_db();55 56 /* Initially, authorizer should be NULL */57 TEST_ASSERT_NULL(db->xAuth);58 TEST_ASSERT_NULL(db->pAuthArg);59 60 AuthLog log1;61 memset(&log1, 0, sizeof(log1));62 int rc = sqlite3_set_authorizer(db, log_authorizer, &log1);63 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);64 TEST_ASSERT_EQUAL_PTR((sqlite3_xauth)log_authorizer, db->xAuth);65 TEST_ASSERT_EQUAL_PTR(&log1, db->pAuthArg);66 67 /* Change to NULL authorizer with a different pArg */68 AuthLog log2;69 memset(&log2, 0, sizeof(log2));70 rc = sqlite3_set_authorizer(db, NULL, &log2);71 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);72 TEST_ASSERT_NULL(db->xAuth);73 TEST_ASSERT_EQUAL_PTR(&log2, db->pAuthArg);74 75 sqlite3_close(db);76}77 78void test_sqlite3_set_authorizer_expires_prepared_statements_and_enforces_denial(void){79 sqlite3 *db = open_in_memory_db();80 81 /* Prepare a statement before installing the authorizer */82 sqlite3_stmt *pStmt = NULL;83 const char *sql = "SELECT name FROM sqlite_master";84 int rc = sqlite3_prepare_v2(db, sql, -1, &pStmt, NULL);85 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "Initial prepare failed");86 TEST_ASSERT_NOT_NULL(pStmt);87 88 /* Install a denying authorizer. This should expire the prepared statement. */89 rc = sqlite3_set_authorizer(db, deny_select_or_read, NULL);90 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);91 92 /* Stepping should force a recompile, which should be denied by the authorizer. */93 rc = sqlite3_step(pStmt);94 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_ERROR, rc, "sqlite3_step should fail after denial");95 TEST_ASSERT_EQUAL_INT(SQLITE_AUTH, sqlite3_errcode(db));96 97 sqlite3_finalize(pStmt);98 sqlite3_close(db);99}100 101void test_sqlite3_set_authorizer_callback_receives_pArg_and_is_used(void){102 sqlite3 *db = open_in_memory_db();103 104 AuthLog L;105 memset(&L, 0, sizeof(L));106 int rc = sqlite3_set_authorizer(db, log_authorizer, &L);107 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);108 109 /* Execute something simple that will trigger authorizer calls. */110 char *zErr = NULL;111 rc = sqlite3_exec(db, "CREATE TABLE t(x)", 0, 0, &zErr);112 if( rc!=SQLITE_OK && zErr ){113 /* If failed for some reason unrelated to authorization, free message and fail */114 sqlite3_free(zErr);115 }116 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "CREATE TABLE failed unexpectedly");117 TEST_ASSERT_TRUE_MESSAGE(L.callCount > 0, "Authorizer was not called");118 TEST_ASSERT_EQUAL_PTR(&L, L.seenArg);119 120 sqlite3_close(db);121}122 123#ifdef SQLITE_ENABLE_API_ARMOR124void test_sqlite3_set_authorizer_returns_misuse_when_db_null(void){125 AuthLog L;126 memset(&L, 0, sizeof(L));127 int rc = sqlite3_set_authorizer(NULL, log_authorizer, &L);128 TEST_ASSERT_EQUAL_INT(SQLITE_MISUSE_BKPT, rc);129}130#endif /* SQLITE_ENABLE_API_ARMOR */131 132#else /* SQLITE_OMIT_AUTHORIZATION */133 134void test_sqlite3_set_authorizer_omitted_build_noop(void){135 /* In builds omitting authorization, just assert true to keep runner happy. */136 TEST_ASSERT_TRUE(1);137}138 139#endif /* SQLITE_OMIT_AUTHORIZATION */140 141int main(void){142 UNITY_BEGIN();143#ifndef SQLITE_OMIT_AUTHORIZATION144 RUN_TEST(test_sqlite3_set_authorizer_sets_and_clears_fields);145 RUN_TEST(test_sqlite3_set_authorizer_expires_prepared_statements_and_enforces_denial);146 RUN_TEST(test_sqlite3_set_authorizer_callback_receives_pArg_and_is_used);147 #ifdef SQLITE_ENABLE_API_ARMOR148 RUN_TEST(test_sqlite3_set_authorizer_returns_misuse_when_db_null);149 #endif150#else151 RUN_TEST(test_sqlite3_set_authorizer_omitted_build_noop);152#endif153 return UNITY_END();154}