AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5#include <stdio.h>6 7extern int test_isAlterableTable(Parse *pParse, Table *pTab);8 9static void freeParseErrorIfAny(sqlite3 *db, Parse *pParse){10 if( pParse->zErrMsg ){11 sqlite3DbFree(db, pParse->zErrMsg);12 pParse->zErrMsg = 0;13 }14}15 16void setUp(void) {17 /* No global setup needed */18}19 20void tearDown(void) {21 /* No global teardown needed */22}23 24/* Helper to initialize a fresh Parse object tied to a db */25static void initParse(Parse *pParse, sqlite3 *db){26 memset(pParse, 0, sizeof(*pParse));27 pParse->db = db;28}29 30/* Helper to init a simple Table object */31static void initTable(Table *pTab, const char *zName, u32 flags){32 memset(pTab, 0, sizeof(*pTab));33 pTab->zName = (char*)zName; /* string literal is fine; function only reads */34 pTab->tabFlags = flags;35}36 37void test_isAlterableTable_user_table_allowed(void){38 sqlite3 *db = 0;39 Parse p;40 Table t;41 int rc;42 43 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));44 initParse(&p, db);45 initTable(&t, "t1", 0);46 47 rc = test_isAlterableTable(&p, &t);48 TEST_ASSERT_EQUAL_INT(0, rc);49 TEST_ASSERT_NULL(p.zErrMsg);50 51 sqlite3_close(db);52}53 54void test_isAlterableTable_system_table_denied(void){55 sqlite3 *db = 0;56 Parse p;57 Table t;58 int rc;59 60 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));61 initParse(&p, db);62 initTable(&t, "sqlite_master", 0);63 64 rc = test_isAlterableTable(&p, &t);65 TEST_ASSERT_EQUAL_INT(1, rc);66 TEST_ASSERT_NOT_NULL(p.zErrMsg);67 /* Ensure message mentions table name and the refusal */68 TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "sqlite_master"));69 TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "may not be altered"));70 71 freeParseErrorIfAny(db, &p);72 sqlite3_close(db);73}74 75void test_isAlterableTable_system_table_case_insensitive_denied(void){76 sqlite3 *db = 0;77 Parse p;78 Table t;79 int rc;80 81 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));82 initParse(&p, db);83 initTable(&t, "SQLite_TeMp123", 0);84 85 rc = test_isAlterableTable(&p, &t);86 TEST_ASSERT_EQUAL_INT(1, rc);87 TEST_ASSERT_NOT_NULL(p.zErrMsg);88 TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "may not be altered"));89 90 freeParseErrorIfAny(db, &p);91 sqlite3_close(db);92}93 94#ifndef SQLITE_OMIT_VIRTUALTABLE95void test_isAlterableTable_eponymous_denied(void){96 sqlite3 *db = 0;97 Parse p;98 Table t;99 int rc;100 101 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));102 initParse(&p, db);103 initTable(&t, "user_tab", TF_Eponymous);104 105 rc = test_isAlterableTable(&p, &t);106 TEST_ASSERT_EQUAL_INT(1, rc);107 TEST_ASSERT_NOT_NULL(p.zErrMsg);108 TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "may not be altered"));109 110 freeParseErrorIfAny(db, &p);111 sqlite3_close(db);112}113 114void test_isAlterableTable_shadow_readonly_denied(void){115 sqlite3 *db = 0;116 Parse p;117 Table t;118 int rc;119 int old = 0;120 121 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));122 /* Enable defensive mode to force read-only shadow tables */123 sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, 1, &old);124 125 initParse(&p, db);126 initTable(&t, "shadow_tab", TF_Shadow);127 128 rc = test_isAlterableTable(&p, &t);129 TEST_ASSERT_EQUAL_INT(1, rc);130 TEST_ASSERT_NOT_NULL(p.zErrMsg);131 TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "may not be altered"));132 133 freeParseErrorIfAny(db, &p);134 /* Restore prior defensive setting and close */135 sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, old, 0);136 sqlite3_close(db);137}138 139void test_isAlterableTable_shadow_writable_allowed(void){140 sqlite3 *db = 0;141 Parse p;142 Table t;143 int rc;144 int old = 0;145 146 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));147 /* Ensure defensive mode is OFF so shadow tables are not read-only */148 sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, 0, &old);149 150 initParse(&p, db);151 initTable(&t, "shadow_tab2", TF_Shadow);152 153 rc = test_isAlterableTable(&p, &t);154 TEST_ASSERT_EQUAL_INT(0, rc);155 TEST_ASSERT_NULL(p.zErrMsg);156 157 /* Restore prior defensive setting and close */158 sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, old, 0);159 sqlite3_close(db);160}161#endif /* SQLITE_OMIT_VIRTUALTABLE */162 163int main(void){164 UNITY_BEGIN();165 RUN_TEST(test_isAlterableTable_user_table_allowed);166 RUN_TEST(test_isAlterableTable_system_table_denied);167 RUN_TEST(test_isAlterableTable_system_table_case_insensitive_denied);168#ifndef SQLITE_OMIT_VIRTUALTABLE169 RUN_TEST(test_isAlterableTable_eponymous_denied);170 RUN_TEST(test_isAlterableTable_shadow_readonly_denied);171 RUN_TEST(test_isAlterableTable_shadow_writable_allowed);172#endif173 return UNITY_END();174}