AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5#include <stdio.h>6 7static void setDefensive(sqlite3 *db, int on){8#ifdef SQLITE_DBCONFIG_DEFENSIVE9 int rc;10 int oldVal = 0;11 rc = sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, on, &oldVal);12 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);13#else14 if( on ){15 db->flags |= SQLITE_Defensive;16 }else{17 db->flags &= ~SQLITE_Defensive;18 }19#endif20}21 22void setUp(void) {23 /* No global setup needed */24}25 26void tearDown(void) {27 /* No global teardown needed */28}29 30static sqlite3* open_in_memory_db(void){31 sqlite3 *db = 0;32 int rc = sqlite3_open(":memory:", &db);33 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);34 TEST_ASSERT_NOT_NULL(db);35 return db;36}37 38void test_sqlite3ReadOnlyShadowTables_returns_0_when_defensive_not_set(void){39 sqlite3 *db = open_in_memory_db();40 41 /* Ensure baseline fields are in the expected state */42 setDefensive(db, 0);43 db->pVtabCtx = 0;44 db->nVdbeExec = 0;45 46 int ro = sqlite3ReadOnlyShadowTables(db);47 48 /* If virtual tables are omitted, it must be 0; otherwise also 0 because defensive is off */49#ifdef SQLITE_OMIT_VIRTUALTABLE50 TEST_ASSERT_EQUAL_INT(0, ro);51#else52 TEST_ASSERT_EQUAL_INT(0, ro);53#endif54 55 sqlite3_close(db);56}57 58void test_sqlite3ReadOnlyShadowTables_returns_1_when_defensive_and_no_vtabctx_no_exec_and_not_in_sync(void){59 sqlite3 *db = open_in_memory_db();60 61 setDefensive(db, 1);62 /* A fresh in-memory db should have these zeroed; set explicitly for clarity */63 db->pVtabCtx = 0;64 db->nVdbeExec = 0;65 66 int ro = sqlite3ReadOnlyShadowTables(db);67 68#ifdef SQLITE_OMIT_VIRTUALTABLE69 /* With SQLITE_OMIT_VIRTUALTABLE, function always returns 0 */70 TEST_ASSERT_EQUAL_INT(0, ro);71#else72 TEST_ASSERT_EQUAL_INT(1, ro);73#endif74 75 sqlite3_close(db);76}77 78void test_sqlite3ReadOnlyShadowTables_returns_0_when_pVtabCtx_nonnull_even_with_defensive(void){79 sqlite3 *db = open_in_memory_db();80 81 setDefensive(db, 1);82 db->nVdbeExec = 0;83 84 /* Set a non-NULL pVtabCtx; we use an allocated byte to avoid invalid pointer linting. */85 void *tmp = sqlite3_malloc(1);86 TEST_ASSERT_NOT_NULL(tmp);87 db->pVtabCtx = (VtabCtx*)tmp;88 89 int ro = sqlite3ReadOnlyShadowTables(db);90 91 /* Regardless of SQLITE_OMIT_VIRTUALTABLE, this must be 0 since pVtabCtx!=0 */92 TEST_ASSERT_EQUAL_INT(0, ro);93 94 /* Restore state and free temp memory before closing */95 db->pVtabCtx = 0;96 sqlite3_free(tmp);97 98 sqlite3_close(db);99}100 101void test_sqlite3ReadOnlyShadowTables_returns_0_when_nVdbeExec_nonzero_even_with_defensive(void){102 sqlite3 *db = open_in_memory_db();103 104 setDefensive(db, 1);105 db->pVtabCtx = 0;106 107 /* Simulate executing VDBE by setting counter non-zero */108 db->nVdbeExec = 1;109 110 int ro = sqlite3ReadOnlyShadowTables(db);111 112 /* Regardless of SQLITE_OMIT_VIRTUALTABLE, this must be 0 since nVdbeExec!=0 */113 TEST_ASSERT_EQUAL_INT(0, ro);114 115 /* Restore before close */116 db->nVdbeExec = 0;117 118 sqlite3_close(db);119}120 121int main(void) {122 UNITY_BEGIN();123 124 RUN_TEST(test_sqlite3ReadOnlyShadowTables_returns_0_when_defensive_not_set);125 RUN_TEST(test_sqlite3ReadOnlyShadowTables_returns_1_when_defensive_and_no_vtabctx_no_exec_and_not_in_sync);126 RUN_TEST(test_sqlite3ReadOnlyShadowTables_returns_0_when_pVtabCtx_nonnull_even_with_defensive);127 RUN_TEST(test_sqlite3ReadOnlyShadowTables_returns_0_when_nVdbeExec_nonzero_even_with_defensive);128 129 return UNITY_END();130}