sqlite / tests /tests_alter_sqlite3RenameTokenRemap.c
AryaWu's picture
Upload folder using huggingface_hub
7510827 verified
#include "sqliteInt.h"
#include "unity.h"
#include <string.h>
#include <stdlib.h>
/* Forward declaration of function under test */
void sqlite3RenameTokenRemap(Parse *pParse, const void *pTo, const void *pFrom);
static void* allocByte(unsigned char v){
unsigned char *p = (unsigned char*)sqlite3_malloc(1);
TEST_ASSERT_NOT_NULL(p);
*p = v;
return (void*)p;
}
static void freeIf(void *p){
if(p) sqlite3_free(p);
}
static void initParseWithDb(Parse *pParse, sqlite3 **ppDb){
int rc;
sqlite3 *db = 0;
memset(pParse, 0, sizeof(*pParse));
rc = sqlite3_open(":memory:", &db);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
TEST_ASSERT_NOT_NULL(db);
pParse->db = db;
db->pParse = pParse;
db->mallocFailed = 0;
*ppDb = db;
}
static void cleanupDb(sqlite3 *db){
if(db){
db->pParse = 0;
sqlite3_close(db);
}
}
void setUp(void) {
/* no-op */
}
void tearDown(void) {
/* no-op */
}
/* Test 1: Basic remap when pFrom is found in the list (nErr==0).
Ensure only the first matching token is updated and others unchanged. */
void test_sqlite3RenameTokenRemap_basic_remap(void){
Parse parse;
sqlite3 *db = NULL;
initParseWithDb(&parse, &db);
parse.nErr = 0;
/* Create distinct valid pointers for dereference */
void *pA = allocByte(0xA1);
void *pB = allocByte(0xB2);
void *pC = allocByte(0xC3);
void *pX = allocByte(0x5A); /* pTo: ensure not equal to any existing p */
/* Build RenameToken list: A -> B -> C */
RenameToken rt1, rt2, rt3;
memset(&rt1, 0, sizeof(rt1));
memset(&rt2, 0, sizeof(rt2));
memset(&rt3, 0, sizeof(rt3));
rt1.p = pA; rt1.pNext = &rt2;
rt2.p = pB; rt2.pNext = &rt3;
rt3.p = pC; rt3.pNext = NULL;
parse.pRename = &rt1;
/* Act */
sqlite3RenameTokenRemap(&parse, pX, pB);
/* Assert */
TEST_ASSERT_EQUAL_PTR(pA, rt1.p);
TEST_ASSERT_EQUAL_PTR(pX, rt2.p);
TEST_ASSERT_EQUAL_PTR(pC, rt3.p);
/* Cleanup */
freeIf(pA);
freeIf(pB);
freeIf(pC);
freeIf(pX);
cleanupDb(db);
}
/* Test 2: No match for pFrom in the list (nErr==0).
Ensure list remains unchanged. */
void test_sqlite3RenameTokenRemap_no_match(void){
Parse parse;
sqlite3 *db = NULL;
initParseWithDb(&parse, &db);
parse.nErr = 0;
void *pA = allocByte(0x11);
void *pB = allocByte(0x22);
void *pC = allocByte(0x33);
void *pZ = allocByte(0x44); /* pFrom not in list */
void *pTo = allocByte(0x55); /* unique pTo not in list */
RenameToken rt1, rt2, rt3;
memset(&rt1, 0, sizeof(rt1));
memset(&rt2, 0, sizeof(rt2));
memset(&rt3, 0, sizeof(rt3));
rt1.p = pA; rt1.pNext = &rt2;
rt2.p = pB; rt2.pNext = &rt3;
rt3.p = pC; rt3.pNext = NULL;
parse.pRename = &rt1;
sqlite3RenameTokenRemap(&parse, pTo, pZ);
TEST_ASSERT_EQUAL_PTR(pA, rt1.p);
TEST_ASSERT_EQUAL_PTR(pB, rt2.p);
TEST_ASSERT_EQUAL_PTR(pC, rt3.p);
freeIf(pA);
freeIf(pB);
freeIf(pC);
freeIf(pZ);
freeIf(pTo);
cleanupDb(db);
}
/* Test 3: Multiple matches for pFrom; only the first should be remapped (nErr==0). */
void test_sqlite3RenameTokenRemap_multiple_matches_first_only(void){
Parse parse;
sqlite3 *db = NULL;
initParseWithDb(&parse, &db);
parse.nErr = 0;
void *pM = allocByte(0x77);
void *pOther = allocByte(0x88);
void *pNew = allocByte(0x99); /* unique pTo not in list */
RenameToken rt1, rt2, rt3;
memset(&rt1, 0, sizeof(rt1));
memset(&rt2, 0, sizeof(rt2));
memset(&rt3, 0, sizeof(rt3));
rt1.p = pM; rt1.pNext = &rt2;
rt2.p = pOther; rt2.pNext = &rt3;
rt3.p = pM; rt3.pNext = NULL;
parse.pRename = &rt1;
sqlite3RenameTokenRemap(&parse, pNew, pM);
TEST_ASSERT_EQUAL_PTR(pNew, rt1.p);
TEST_ASSERT_EQUAL_PTR(pOther, rt2.p);
TEST_ASSERT_EQUAL_PTR(pM, rt3.p); /* unchanged */
freeIf(pM);
freeIf(pOther);
freeIf(pNew);
cleanupDb(db);
}
/* Test 4: pParse->nErr != 0 bypasses the renameTokenCheckAll deref and P==pTo check.
Here, pTo equals an existing pointer in the list. */
void test_sqlite3RenameTokenRemap_nErr_nonzero_allows_pTo_equal_existing(void){
Parse parse;
sqlite3 *db = NULL;
initParseWithDb(&parse, &db);
parse.nErr = 1; /* bypass renameTokenCheckAll internal deref and equality assert */
void *pA = allocByte(0xAB);
void *pB = allocByte(0xBC);
RenameToken rt1, rt2;
memset(&rt1, 0, sizeof(rt1));
memset(&rt2, 0, sizeof(rt2));
rt1.p = pA; rt1.pNext = &rt2;
rt2.p = pB; rt2.pNext = NULL;
parse.pRename = &rt1;
/* pTo equals existing pointer (rt2.p) */
sqlite3RenameTokenRemap(&parse, pB, pA);
TEST_ASSERT_EQUAL_PTR(pB, rt1.p);
TEST_ASSERT_EQUAL_PTR(pB, rt2.p);
/* Cleanup: avoid double-free: both tokens point to pB now */
freeIf(pA);
freeIf(pB);
cleanupDb(db);
}
/* Test 5: List contains a NULL pointer entry; function should skip it safely (nErr==0). */
void test_sqlite3RenameTokenRemap_handles_null_token_pointers(void){
Parse parse;
sqlite3 *db = NULL;
initParseWithDb(&parse, &db);
parse.nErr = 0;
void *pA = allocByte(0x01);
void *pNew = allocByte(0x02);
RenameToken rt1, rt2;
memset(&rt1, 0, sizeof(rt1));
memset(&rt2, 0, sizeof(rt2));
rt1.p = NULL; rt1.pNext = &rt2;
rt2.p = pA; rt2.pNext = NULL;
parse.pRename = &rt1;
sqlite3RenameTokenRemap(&parse, pNew, pA);
TEST_ASSERT_NULL(rt1.p);
TEST_ASSERT_EQUAL_PTR(pNew, rt2.p);
freeIf(pA);
freeIf(pNew);
cleanupDb(db);
}
int main(void){
UNITY_BEGIN();
RUN_TEST(test_sqlite3RenameTokenRemap_basic_remap);
RUN_TEST(test_sqlite3RenameTokenRemap_no_match);
RUN_TEST(test_sqlite3RenameTokenRemap_multiple_matches_first_only);
RUN_TEST(test_sqlite3RenameTokenRemap_nErr_nonzero_allows_pTo_equal_existing);
RUN_TEST(test_sqlite3RenameTokenRemap_handles_null_token_pointers);
return UNITY_END();
}