AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6static u64 ext_bits(void){7 return ((u64)SQLITE_LoadExtension) | ((u64)SQLITE_LoadExtFunc);8}9 10void setUp(void) {11 /* No-op */12}13 14void tearDown(void) {15 /* No-op */16}17 18/* Helper to open an in-memory database and assert success */19static sqlite3* open_memdb(void){20 sqlite3 *db = NULL;21 int rc = sqlite3_open(":memory:", &db);22 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");23 TEST_ASSERT_NOT_NULL(db);24 return db;25}26 27/* Helper to close db safely */28static void close_db(sqlite3 *db){29 if( db ){30 int rc = sqlite3_close(db);31 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_close failed");32 }33}34 35/* Verify that disabling yields 'not authorized' from sqlite3_load_extension */36void test_sqlite3_enable_load_extension_disable_gives_not_authorized(void){37 sqlite3 *db = open_memdb();38 39 int rc = sqlite3_enable_load_extension(db, 0);40 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);41 42 char *errmsg = NULL;43 rc = sqlite3_load_extension(db, "", 0, &errmsg);44 TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);45 TEST_ASSERT_NOT_NULL(errmsg);46 TEST_ASSERT_EQUAL_STRING("not authorized", errmsg);47 sqlite3_free(errmsg);48 49 close_db(db);50}51 52/* Verify enabling changes behavior of sqlite3_load_extension (different error) */53void test_sqlite3_enable_load_extension_enable_changes_error_path(void){54 sqlite3 *db = open_memdb();55 56 /* Ensure disabled baseline first */57 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_enable_load_extension(db, 0));58 59 /* Enable and check behavior */60 int rc = sqlite3_enable_load_extension(db, 1);61 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);62 63 char *errmsg = NULL;64 rc = sqlite3_load_extension(db, "", 0, &errmsg);65 TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);66 TEST_ASSERT_NOT_NULL(errmsg);67 /* Expect "unable to open shared library [..]" prefix */68 const char *prefix = "unable to open shared library";69 TEST_ASSERT_TRUE_MESSAGE(strncmp(errmsg, prefix, strlen(prefix)) == 0,70 "Expected error prefix 'unable to open shared library'");71 sqlite3_free(errmsg);72 73 close_db(db);74}75 76/* Verify that enabling sets bits and disabling clears them, and no other flags change */77void test_sqlite3_enable_load_extension_sets_and_clears_bits_only(void){78 sqlite3 *db = open_memdb();79 80 /* Capture initial non-extension flags */81 u64 initial_flags = db->flags;82 u64 initial_other = initial_flags & ~ext_bits();83 84 /* Enable */85 int rc = sqlite3_enable_load_extension(db, 1);86 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);87 u64 flags_after_enable = db->flags;88 TEST_ASSERT_BITS_HIGH(ext_bits(), ext_bits(), flags_after_enable); /* both bits set */89 TEST_ASSERT_EQUAL_UINT64(initial_other, flags_after_enable & ~ext_bits());90 91 /* Disable */92 rc = sqlite3_enable_load_extension(db, 0);93 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);94 u64 flags_after_disable = db->flags;95 TEST_ASSERT_BITS_LOW(ext_bits(), flags_after_disable); /* both bits cleared */96 TEST_ASSERT_EQUAL_UINT64(initial_other, flags_after_disable & ~ext_bits());97 98 close_db(db);99}100 101/* Verify idempotency: multiple enables keep bits set; multiple disables keep bits clear */102void test_sqlite3_enable_load_extension_idempotent(void){103 sqlite3 *db = open_memdb();104 105 /* Disable twice */106 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_enable_load_extension(db, 0));107 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_enable_load_extension(db, 0));108 TEST_ASSERT_BITS_LOW(ext_bits(), db->flags);109 110 /* Enable twice */111 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_enable_load_extension(db, 1));112 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_enable_load_extension(db, 1));113 TEST_ASSERT_BITS_HIGH(ext_bits(), ext_bits(), db->flags);114 115 /* Disable twice again */116 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_enable_load_extension(db, 0));117 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_enable_load_extension(db, 0));118 TEST_ASSERT_BITS_LOW(ext_bits(), db->flags);119 120 close_db(db);121}122 123/* Explicitly verify return code is SQLITE_OK */124void test_sqlite3_enable_load_extension_returns_ok(void){125 sqlite3 *db = open_memdb();126 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_enable_load_extension(db, 1));127 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_enable_load_extension(db, 0));128 close_db(db);129}130 131int main(void) {132 UNITY_BEGIN();133 RUN_TEST(test_sqlite3_enable_load_extension_disable_gives_not_authorized);134 RUN_TEST(test_sqlite3_enable_load_extension_enable_changes_error_path);135 RUN_TEST(test_sqlite3_enable_load_extension_sets_and_clears_bits_only);136 RUN_TEST(test_sqlite3_enable_load_extension_idempotent);137 RUN_TEST(test_sqlite3_enable_load_extension_returns_ok);138 return UNITY_END();139}