Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_build_sqlite3NestedParse.c193 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Unity fixtures */7void setUp(void) {8  /* No global setup needed */9}10void tearDown(void) {11  /* No global teardown needed */12}13 14/* Helpers to manipulate and verify PARSE_TAIL */15static void fill_parse_tail(Parse *p, unsigned char v){16  memset(PARSE_TAIL(p), v, PARSE_TAIL_SZ);17}18static void snapshot_parse_tail(Parse *p, unsigned char *out){19  memcpy(out, PARSE_TAIL(p), PARSE_TAIL_SZ);20}21static void assert_parse_tail_equals(Parse *p, const unsigned char *snap){22  TEST_ASSERT_EQUAL_INT(0, memcmp(PARSE_TAIL(p), snap, PARSE_TAIL_SZ));23}24 25/* Helper to clean up any VDBE produced during parsing to allow sqlite3_close() */26static void cleanup_parse(Parse *p){27  if( p->pVdbe ){28    sqlite3VdbeDelete(p->pVdbe);29    p->pVdbe = 0;30  }31}32 33static void init_parse(Parse *p, sqlite3 *db){34  memset(p, 0, sizeof(*p));35  p->db = db;36  /* Ensure predictable starting conditions */37  p->nErr = 0;38  p->rc = SQLITE_OK;39  p->eParseMode = 0;40  p->nested = 0;41}42 43/* Test: Early return when pParse->nErr > 0, state should remain unchanged */44void test_sqlite3NestedParse_early_return_on_existing_error(void){45  sqlite3 *db = 0;46  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));47 48  Parse p;49  init_parse(&p, db);50  p.nErr = 1;            /* Force early-return condition */51  p.nested = 2;          /* Ensure nested is not incremented */52  u32 origFlags = db->mDbFlags;53 54  unsigned char snap[PARSE_TAIL_SZ];55  fill_parse_tail(&p, 0x5A);56  snapshot_parse_tail(&p, snap);57 58  sqlite3NestedParse(&p, "SELECT 1");59 60  /* State unchanged */61  TEST_ASSERT_EQUAL_INT(1, p.nErr);62  TEST_ASSERT_EQUAL_INT(2, p.nested);63  TEST_ASSERT_EQUAL_INT(origFlags, db->mDbFlags);64  assert_parse_tail_equals(&p, snap);65 66  cleanup_parse(&p);67  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));68}69 70/* Test: Early return when eParseMode != 0, state should remain unchanged */71void test_sqlite3NestedParse_early_return_on_eParseMode_nonzero(void){72  sqlite3 *db = 0;73  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));74 75  Parse p;76  init_parse(&p, db);77  p.eParseMode = 1;      /* Force early-return condition */78  p.nested = 3;79  u32 origFlags = db->mDbFlags;80 81  unsigned char snap[PARSE_TAIL_SZ];82  fill_parse_tail(&p, 0xA5);83  snapshot_parse_tail(&p, snap);84 85  sqlite3NestedParse(&p, "SELECT 1");86 87  /* State unchanged */88  TEST_ASSERT_EQUAL_INT(0, p.nErr);89  TEST_ASSERT_EQUAL_INT(3, p.nested);90  TEST_ASSERT_EQUAL_INT(origFlags, db->mDbFlags);91  assert_parse_tail_equals(&p, snap);92 93  cleanup_parse(&p);94  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));95}96 97/* Test: Too-big SQL (exceeding SQLITE_LIMIT_LENGTH) sets rc=SQLITE_TOOBIG and increments nErr */98void test_sqlite3NestedParse_sets_TOOBIG_when_SQL_exceeds_limit(void){99  sqlite3 *db = 0;100  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));101 102  /* Set a small length limit to trigger SQLITE_TOOBIG in sqlite3VMPrintf */103  int oldLim = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 50);104 105  Parse p;106  init_parse(&p, db);107  u32 origFlags = db->mDbFlags;108 109  unsigned char snap[PARSE_TAIL_SZ];110  fill_parse_tail(&p, 0xCC);111  snapshot_parse_tail(&p, snap);112 113  char longbuf[200];114  memset(longbuf, 'x', sizeof(longbuf)-1);115  longbuf[sizeof(longbuf)-1] = '\0';116 117  sqlite3NestedParse(&p, "%s", longbuf);118 119  /* Should report an error and not modify parser/db state beyond error fields */120  TEST_ASSERT_EQUAL_INT(1, p.nErr);121  TEST_ASSERT_EQUAL_INT(SQLITE_TOOBIG, p.rc);122  TEST_ASSERT_EQUAL_INT(0, p.nested);         /* No nesting occurred */123  TEST_ASSERT_EQUAL_INT(origFlags, db->mDbFlags);124  assert_parse_tail_equals(&p, snap);125 126  /* Restore limit and cleanup */127  sqlite3_limit(db, SQLITE_LIMIT_LENGTH, oldLim);128  cleanup_parse(&p);129  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));130}131 132/* Test: Normal parse path restores flags, nested level, and PARSE_TAIL */133void test_sqlite3NestedParse_restores_state_after_successful_parse(void){134  sqlite3 *db = 0;135  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));136 137  Parse p;138  init_parse(&p, db);139  u32 origFlags = db->mDbFlags;140 141  unsigned char snap[PARSE_TAIL_SZ];142  fill_parse_tail(&p, 0xAA);143  snapshot_parse_tail(&p, snap);144 145  sqlite3NestedParse(&p, "SELECT 1");146 147  /* No new errors */148  TEST_ASSERT_EQUAL_INT(0, p.nErr);149  /* Nested level restored */150  TEST_ASSERT_EQUAL_INT(0, p.nested);151  /* Flags restored */152  TEST_ASSERT_EQUAL_INT(origFlags, db->mDbFlags);153  /* PARSE_TAIL restored */154  assert_parse_tail_equals(&p, snap);155 156  cleanup_parse(&p);157  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));158}159 160/* Test: Nested depth near limit (nested==9) still works and restores properly */161void test_sqlite3NestedParse_handles_maximum_supported_nesting_minus_one(void){162  sqlite3 *db = 0;163  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));164 165  Parse p;166  init_parse(&p, db);167  p.nested = 9;  /* Allowed by the assert: nested < 10 */168  u32 origFlags = db->mDbFlags;169 170  unsigned char snap[PARSE_TAIL_SZ];171  fill_parse_tail(&p, 0x11);172  snapshot_parse_tail(&p, snap);173 174  sqlite3NestedParse(&p, "SELECT 1");175 176  TEST_ASSERT_EQUAL_INT(0, p.nErr);177  TEST_ASSERT_EQUAL_INT(9, p.nested);178  TEST_ASSERT_EQUAL_INT(origFlags, db->mDbFlags);179  assert_parse_tail_equals(&p, snap);180 181  cleanup_parse(&p);182  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));183}184 185int main(void){186  UNITY_BEGIN();187  RUN_TEST(test_sqlite3NestedParse_early_return_on_existing_error);188  RUN_TEST(test_sqlite3NestedParse_early_return_on_eParseMode_nonzero);189  RUN_TEST(test_sqlite3NestedParse_sets_TOOBIG_when_SQL_exceeds_limit);190  RUN_TEST(test_sqlite3NestedParse_restores_state_after_successful_parse);191  RUN_TEST(test_sqlite3NestedParse_handles_maximum_supported_nesting_minus_one);192  return UNITY_END();193}