File size: 5,224 Bytes
7510827 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
#include "sqliteInt.h"
#include "unity.h"
#include <string.h>
#include <stdlib.h>
/* Wrapper for the static function provided by the build system */
extern int test_alterFindCol(Parse *pParse, Table *pTab, Token *pCol, int *piCol);
/* Optional authorizer that denies everything */
static int denyAuthorizer(void *p, int code,
const char *z1, const char *z2,
const char *z3, const char *z4){
(void)p; (void)code; (void)z1; (void)z2; (void)z3; (void)z4;
return SQLITE_DENY;
}
void setUp(void) {
/* Setup code here, or leave empty */
}
void tearDown(void) {
/* Cleanup code here, or leave empty */
}
static sqlite3* open_memory_db(void){
sqlite3 *db = 0;
int rc = sqlite3_open(":memory:", &db);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
TEST_ASSERT_NOT_NULL(db);
return db;
}
static Table* create_table_and_get_handle(sqlite3 *db, const char *sqlCreate, const char *zName, const char *zDb){
int rc = sqlite3_exec(db, sqlCreate, 0, 0, 0);
TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "CREATE TABLE failed");
Table *pTab = sqlite3FindTable(db, zName, zDb);
TEST_ASSERT_NOT_NULL_MESSAGE(pTab, "sqlite3FindTable returned NULL");
return pTab;
}
static void free_parse_error_if_any(sqlite3 *db, Parse *pParse){
if( pParse && pParse->zErrMsg ){
sqlite3DbFree(db, pParse->zErrMsg);
pParse->zErrMsg = 0;
}
}
/* Test: find existing column -> SQLITE_OK, correct index */
void test_alterFindCol_finds_existing_column_index(void){
sqlite3 *db = open_memory_db();
Table *pTab = create_table_and_get_handle(db, "CREATE TABLE t1(a, b, c);", "t1", "main");
Parse sParse;
memset(&sParse, 0, sizeof(sParse));
sParse.db = db;
Token tok;
tok.z = "b";
tok.n = 1;
int iCol = -999;
int rc = test_alterFindCol(&sParse, pTab, &tok, &iCol);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
TEST_ASSERT_EQUAL_INT(1, iCol);
free_parse_error_if_any(db, &sParse);
sqlite3_close(db);
}
/* Test: non-existent column -> SQLITE_ERROR, *piCol = -1 */
void test_alterFindCol_nonexistent_column(void){
sqlite3 *db = open_memory_db();
Table *pTab = create_table_and_get_handle(db, "CREATE TABLE t2(x, y);", "t2", "main");
Parse sParse;
memset(&sParse, 0, sizeof(sParse));
sParse.db = db;
Token tok;
tok.z = "z"; /* not present */
tok.n = 1;
int iCol = -777;
int rc = test_alterFindCol(&sParse, pTab, &tok, &iCol);
TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);
TEST_ASSERT_EQUAL_INT(-1, iCol);
free_parse_error_if_any(db, &sParse);
sqlite3_close(db);
}
/* Test: case-insensitive column name lookup */
void test_alterFindCol_case_insensitive(void){
sqlite3 *db = open_memory_db();
Table *pTab = create_table_and_get_handle(db, "CREATE TABLE t3(ColA, CoLb, colC);", "t3", "main");
Parse sParse;
memset(&sParse, 0, sizeof(sParse));
sParse.db = db;
/* Use uppercase token for mixed-case column 'CoLb' */
Token tok;
tok.z = "COLB";
tok.n = (int)strlen(tok.z);
int iCol = -5;
int rc = test_alterFindCol(&sParse, pTab, &tok, &iCol);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
TEST_ASSERT_EQUAL_INT(1, iCol);
free_parse_error_if_any(db, &sParse);
sqlite3_close(db);
}
/* Test: empty token -> treated as no such column -> SQLITE_ERROR, *piCol = -1 */
void test_alterFindCol_empty_token_errors(void){
sqlite3 *db = open_memory_db();
Table *pTab = create_table_and_get_handle(db, "CREATE TABLE t4(a, b);", "t4", "main");
Parse sParse;
memset(&sParse, 0, sizeof(sParse));
sParse.db = db;
Token tok;
tok.z = "";
tok.n = 0;
int iCol = 12345;
int rc = test_alterFindCol(&sParse, pTab, &tok, &iCol);
/* If allocation of empty name succeeded, lookup fails -> SQLITE_ERROR; if allocation failed (OOM), SQLITE_NOMEM.
We assert that no success occurs and piCol becomes -1. */
TEST_ASSERT(rc == SQLITE_ERROR || rc == SQLITE_NOMEM);
TEST_ASSERT_EQUAL_INT(-1, iCol);
free_parse_error_if_any(db, &sParse);
sqlite3_close(db);
}
/* Test: authorizer denies, but function should still return SQLITE_OK and correct index */
void test_alterFindCol_authorizer_denies_but_returns_ok(void){
sqlite3 *db = open_memory_db();
Table *pTab = create_table_and_get_handle(db, "CREATE TABLE t5(a, b);", "t5", "main");
/* Install an authorizer that denies everything */
int rcSet = sqlite3_set_authorizer(db, denyAuthorizer, 0);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rcSet);
Parse sParse;
memset(&sParse, 0, sizeof(sParse));
sParse.db = db;
Token tok;
tok.z = "a";
tok.n = 1;
int iCol = -1;
int rc = test_alterFindCol(&sParse, pTab, &tok, &iCol);
/* Regardless of authorization, alterFindCol should return SQLITE_OK for valid column */
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
TEST_ASSERT_EQUAL_INT(0, iCol);
/* Remove authorizer */
sqlite3_set_authorizer(db, 0, 0);
free_parse_error_if_any(db, &sParse);
sqlite3_close(db);
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_alterFindCol_finds_existing_column_index);
RUN_TEST(test_alterFindCol_nonexistent_column);
RUN_TEST(test_alterFindCol_case_insensitive);
RUN_TEST(test_alterFindCol_empty_token_errors);
RUN_TEST(test_alterFindCol_authorizer_denies_but_returns_ok);
return UNITY_END();
} |