Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_attach_codeAttach.c227 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4 5/* Wrapper for the static function under test (provided by the module) */6extern void test_codeAttach(7  Parse *pParse,8  int type,9  const FuncDef *pFunc,10  Expr *pAuthArg,11  Expr *pFilename,12  Expr *pDbname,13  Expr *pKey14);15 16/* Dummy scalar function to populate FuncDef.xSFunc */17static void dummy_scalar(sqlite3_context *ctx, int argc, sqlite3_value **argv){18  UNUSED_PARAMETER(argc);19  UNUSED_PARAMETER(argv);20  sqlite3_result_null(ctx);21}22 23/* Helpers */24static sqlite3* open_memory_db(void){25  sqlite3 *db = 0;26  int rc = sqlite3_open(":memory:", &db);27  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);28  TEST_ASSERT_NOT_NULL(db);29  return db;30}31 32static void close_db(sqlite3 *db){33  if( db ){34    sqlite3_close(db);35  }36}37 38static void init_parse(Parse *pParse, sqlite3 *db){39  memset(pParse, 0, sizeof(*pParse));40  pParse->db = db;41}42 43static Expr* make_id_expr(sqlite3 *db, const char *z){44  Token t;45  t.z = z;46  t.n = (int)strlen(z);47  return sqlite3ExprAlloc(db, TK_ID, &t, 0);48}49 50static Expr* make_null_expr(sqlite3 *db){51  return sqlite3ExprAlloc(db, TK_NULL, 0, 0);52}53 54static Expr* make_concat_ids(sqlite3 *db, const char *a, const char *b){55  Expr *pLeft = make_id_expr(db, a);56  Expr *pRight = make_id_expr(db, b);57  Expr *pConcat = sqlite3ExprAlloc(db, TK_CONCAT, 0, 0);58  /* Link children */59  pConcat->pLeft = pLeft;60  pConcat->pRight = pRight;61  return pConcat;62}63 64static void make_funcdef(FuncDef *pFd, int nArg, const char *zName){65  memset(pFd, 0, sizeof(*pFd));66  pFd->nArg = (i8)nArg;67  pFd->funcFlags = SQLITE_UTF8;68  pFd->xSFunc = dummy_scalar;69  pFd->zName = (char*)zName;70}71 72static Op* find_last_op(Vdbe *v){73  if( v==0 || v->nOp<=0 ) return 0;74  return &v->aOp[v->nOp-1];75}76 77static int has_opcode(Vdbe *v, int opcode){78  if( v==0 ) return 0;79  for(int i=0; i<v->nOp; i++){80    if( v->aOp[i].opcode == opcode ) return 1;81  }82  return 0;83}84 85/* Unity fixtures */86void setUp(void) {87  /* no-op */88}89void tearDown(void) {90  /* no-op */91}92 93/* Tests */94 95void test_codeAttach_attach_success_expire_op(void){96  sqlite3 *db = open_memory_db();97  Parse pParse;98  init_parse(&pParse, db);99 100  /* Prepare expressions: treat TK_ID at root; resolver will convert to TK_STRING */101  Expr *pFilename = make_id_expr(db, "abc");102  Expr *pDbname  = make_id_expr(db, "db2");103  Expr *pKey     = make_null_expr(db);104 105  FuncDef fd;106  make_funcdef(&fd, 3, "sqlite_attach");107 108  /* pAuthArg is the same as pFilename for ATTACH */109  test_codeAttach(&pParse, SQLITE_ATTACH, &fd, pFilename, pFilename, pDbname, pKey);110 111  Vdbe *v = pParse.pVdbe;112  TEST_ASSERT_NOT_NULL(v);113  TEST_ASSERT_TRUE(v->nOp > 0);114 115  /* There should be a function call in the program */116  TEST_ASSERT_TRUE(has_opcode(v, OP_Function));117 118  /* Last op should be OP_Expire with P1=1 for ATTACH */119  Op *pLast = find_last_op(v);120  TEST_ASSERT_NOT_NULL(pLast);121  TEST_ASSERT_EQUAL_INT(OP_Expire, pLast->opcode);122  TEST_ASSERT_EQUAL_INT(1, pLast->p1);123 124  sqlite3VdbeDelete(v);125  pParse.pVdbe = 0;126  close_db(db);127}128 129void test_codeAttach_detach_success_expire_op(void){130  sqlite3 *db = open_memory_db();131  Parse pParse;132  init_parse(&pParse, db);133 134  /* DETACH uses only the dbname; filename/key are unused. */135  Expr *pDbname  = make_id_expr(db, "db2");136 137  FuncDef fd;138  make_funcdef(&fd, 1, "sqlite_detach");139 140  test_codeAttach(&pParse, SQLITE_DETACH, &fd, pDbname, 0, pDbname, 0);141 142  Vdbe *v = pParse.pVdbe;143  TEST_ASSERT_NOT_NULL(v);144  TEST_ASSERT_TRUE(v->nOp > 0);145 146  /* There should be a function call in the program */147  TEST_ASSERT_TRUE(has_opcode(v, OP_Function));148 149  /* Last op should be OP_Expire with P1=0 for DETACH */150  Op *pLast = find_last_op(v);151  TEST_ASSERT_NOT_NULL(pLast);152  TEST_ASSERT_EQUAL_INT(OP_Expire, pLast->opcode);153  TEST_ASSERT_EQUAL_INT(0, pLast->p1);154 155  sqlite3VdbeDelete(v);156  pParse.pVdbe = 0;157  close_db(db);158}159 160void test_codeAttach_resolve_failure_on_concat_identifier(void){161  sqlite3 *db = open_memory_db();162  Parse pParse;163  init_parse(&pParse, db);164 165  /* pFilename is a concatenation of two identifiers, which should fail resolveAttachExpr */166  Expr *pFilename = make_concat_ids(db, "abc", "def");167  Expr *pDbname   = make_id_expr(db, "db2");168  Expr *pKey      = make_null_expr(db);169 170  FuncDef fd;171  make_funcdef(&fd, 3, "sqlite_attach");172 173  test_codeAttach(&pParse, SQLITE_ATTACH, &fd, pFilename, pFilename, pDbname, pKey);174 175  /* Should not create any VDBE because resolution fails */176  TEST_ASSERT_NULL(pParse.pVdbe);177 178  close_db(db);179}180 181static int deny_attach_authorizer(void *pUser, int action,182                                  const char *z1, const char *z2,183                                  const char *z3, const char *z4){184  UNUSED_PARAMETER(pUser);185  UNUSED_PARAMETER(z1);186  UNUSED_PARAMETER(z2);187  UNUSED_PARAMETER(z3);188  UNUSED_PARAMETER(z4);189  if( action==SQLITE_ATTACH ) return SQLITE_DENY;190  return SQLITE_OK;191}192 193void test_codeAttach_authorizer_denies(void){194  sqlite3 *db = open_memory_db();195  Parse pParse;196  init_parse(&pParse, db);197 198  /* Install authorizer that denies ATTACH */199  int rc = sqlite3_set_authorizer(db, deny_attach_authorizer, 0);200  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);201 202  Expr *pFilename = make_id_expr(db, "abc");203  Expr *pDbname   = make_id_expr(db, "db2");204  Expr *pKey      = make_null_expr(db);205 206  FuncDef fd;207  make_funcdef(&fd, 3, "sqlite_attach");208 209  test_codeAttach(&pParse, SQLITE_ATTACH, &fd, pFilename, pFilename, pDbname, pKey);210 211  /* Should not create any VDBE due to authorization failure */212  TEST_ASSERT_NULL(pParse.pVdbe);213 214  /* Cleanup */215  sqlite3_set_authorizer(db, 0, 0);216  close_db(db);217}218 219/* Main */220int main(void){221  UNITY_BEGIN();222  RUN_TEST(test_codeAttach_attach_success_expire_op);223  RUN_TEST(test_codeAttach_detach_success_expire_op);224  RUN_TEST(test_codeAttach_resolve_failure_on_concat_identifier);225  RUN_TEST(test_codeAttach_authorizer_denies);226  return UNITY_END();227}