AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3 4#include <string.h>5#include <stdlib.h>6 7/* Unity setup/teardown */8void setUp(void) {9 /* Setup code here, or leave empty */10}11void tearDown(void) {12 /* Cleanup code here, or leave empty */13}14 15/* Helper: open in-memory database */16static sqlite3* open_memory_db(void){17 sqlite3 *db = NULL;18 int rc = sqlite3_open(":memory:", &db);19 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");20 TEST_ASSERT_NOT_NULL(db);21 return db;22}23 24/* Test: basic prepare and step for a simple SELECT */25void test_sqlite3_prepare_v3_basic_select(void){26 sqlite3 *db = open_memory_db();27 sqlite3_stmt *stmt = NULL;28 const char *tail = NULL;29 30 int rc = sqlite3_prepare_v3(db, "SELECT 1;", -1, 0, &stmt, &tail);31 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);32 TEST_ASSERT_NOT_NULL(stmt);33 34 const char *saved = sqlite3_sql(stmt);35 TEST_ASSERT_NOT_NULL(saved);36 TEST_ASSERT_NOT_NULL(strstr(saved, "SELECT"));37 38 rc = sqlite3_step(stmt);39 TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);40 TEST_ASSERT_EQUAL_INT(1, sqlite3_column_int(stmt, 0));41 42 rc = sqlite3_finalize(stmt);43 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);44 sqlite3_close(db);45}46 47/* Test: pzTail with multiple statements and nBytes = -1 */48void test_sqlite3_prepare_v3_pzTail_multiple_statements_nbytes_neg1(void){49 const char *sql = "SELECT 1; SELECT 2;";50 const char *semi = strchr(sql, ';');51 TEST_ASSERT_NOT_NULL_MESSAGE(semi, "No semicolon found in SQL literal");52 53 sqlite3 *db = open_memory_db();54 55 sqlite3_stmt *s1 = NULL;56 const char *tail1 = NULL;57 int rc = sqlite3_prepare_v3(db, sql, -1, 0, &s1, &tail1);58 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);59 TEST_ASSERT_NOT_NULL(s1);60 TEST_ASSERT_TRUE(tail1 == semi + 1); /* points to the space after ';' */61 TEST_ASSERT_EQUAL_CHAR(' ', *tail1);62 63 rc = sqlite3_step(s1);64 TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);65 TEST_ASSERT_EQUAL_INT(1, sqlite3_column_int(s1, 0));66 sqlite3_finalize(s1);67 68 /* Prepare the second statement using tail pointer */69 sqlite3_stmt *s2 = NULL;70 const char *tail2 = NULL;71 rc = sqlite3_prepare_v3(db, tail1, -1, 0, &s2, &tail2);72 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);73 TEST_ASSERT_NOT_NULL(s2);74 75 rc = sqlite3_step(s2);76 TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);77 TEST_ASSERT_EQUAL_INT(2, sqlite3_column_int(s2, 0));78 sqlite3_finalize(s2);79 80 sqlite3_close(db);81}82 83/* Test: syntax error handling */84void test_sqlite3_prepare_v3_syntax_error(void){85 sqlite3 *db = open_memory_db();86 sqlite3_stmt *stmt = NULL;87 88 int rc = sqlite3_prepare_v3(db, "SELEC 1;", -1, 0, &stmt, NULL);89 TEST_ASSERT_NOT_EQUAL_INT(SQLITE_OK, rc);90 TEST_ASSERT_NULL(stmt);91 92 sqlite3_close(db);93}94 95/* Test: SQLITE_TOOBIG via SQLITE_LIMIT_SQL_LENGTH with explicit nBytes and non-NUL last byte */96void test_sqlite3_prepare_v3_too_long_with_limit_and_nbytes(void){97 sqlite3 *db = open_memory_db();98 99 /* Set a small SQL length limit */100 int oldLimit = sqlite3_limit(db, SQLITE_LIMIT_SQL_LENGTH, 20);101 102 int N = 50; /* greater than limit */103 char *buf = (char*)sqlite3_malloc(N);104 TEST_ASSERT_NOT_NULL(buf);105 /* Fill buffer with non-zero bytes; no NUL terminator */106 memset(buf, 'x', (size_t)N);107 108 sqlite3_stmt *stmt = NULL;109 int rc = sqlite3_prepare_v3(db, (const char*)buf, N, 0, &stmt, NULL);110 TEST_ASSERT_EQUAL_INT(SQLITE_TOOBIG, rc);111 TEST_ASSERT_NULL(stmt);112 113 sqlite3_free(buf);114 sqlite3_limit(db, SQLITE_LIMIT_SQL_LENGTH, oldLimit);115 sqlite3_close(db);116}117 118/* Test: empty SQL with nBytes = 0 */119void test_sqlite3_prepare_v3_empty_sql_nbytes_zero(void){120 sqlite3 *db = open_memory_db();121 122 const char *sql = "";123 sqlite3_stmt *stmt = NULL;124 const char *tail = NULL;125 126 int rc = sqlite3_prepare_v3(db, sql, 0, 0, &stmt, &tail);127 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);128 TEST_ASSERT_NULL(stmt);129 TEST_ASSERT_TRUE(tail == sql);130 131 sqlite3_close(db);132}133 134/* Test: zSql == NULL -> SQLITE_MISUSE */135void test_sqlite3_prepare_v3_null_sql_misuse(void){136 sqlite3 *db = open_memory_db();137 138 sqlite3_stmt *stmt = NULL;139 int rc = sqlite3_prepare_v3(db, NULL, -1, 0, &stmt, NULL);140 TEST_ASSERT_EQUAL_INT(SQLITE_MISUSE, rc);141 TEST_ASSERT_NULL(stmt);142 143 sqlite3_close(db);144}145 146/* Test: embedded NUL with explicit nBytes; tail should point at embedded NUL */147void test_sqlite3_prepare_v3_embedded_nul(void){148 sqlite3 *db = open_memory_db();149 150 const char *a = "SELECT 1;";151 const char *b = "SELECT 2;";152 int n1 = (int)strlen(a);153 int n2 = (int)strlen(b);154 int N = n1 + 1 + n2;155 156 char *buf = (char*)sqlite3_malloc(N);157 TEST_ASSERT_NOT_NULL(buf);158 memcpy(buf, a, (size_t)n1);159 buf[n1] = '\0'; /* embedded NUL */160 memcpy(buf + n1 + 1, b, (size_t)n2); /* last byte non-NUL ';' */161 162 sqlite3_stmt *s1 = NULL;163 const char *tail = NULL;164 int rc = sqlite3_prepare_v3(db, (const char*)buf, N, 0, &s1, &tail);165 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);166 TEST_ASSERT_NOT_NULL(s1);167 TEST_ASSERT_TRUE(tail == buf + n1);168 TEST_ASSERT_EQUAL_CHAR('\0', *tail);169 170 rc = sqlite3_step(s1);171 TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);172 TEST_ASSERT_EQUAL_INT(1, sqlite3_column_int(s1, 0));173 sqlite3_finalize(s1);174 175 /* Prepare and run the second statement residing after the embedded NUL */176 sqlite3_stmt *s2 = NULL;177 rc = sqlite3_prepare_v3(db, (const char*)(buf + n1 + 1), n2, 0, &s2, NULL);178 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);179 TEST_ASSERT_NOT_NULL(s2);180 rc = sqlite3_step(s2);181 TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);182 TEST_ASSERT_EQUAL_INT(2, sqlite3_column_int(s2, 0));183 sqlite3_finalize(s2);184 185 sqlite3_free(buf);186 sqlite3_close(db);187}188 189/* Test: using SQLITE_PREPARE_PERSISTENT flag still works and sqlite3_sql() is non-NULL */190void test_sqlite3_prepare_v3_persistent_flag(void){191 sqlite3 *db = open_memory_db();192 193 sqlite3_stmt *stmt = NULL;194 int rc = sqlite3_prepare_v3(db, "SELECT 42;", -1, SQLITE_PREPARE_PERSISTENT, &stmt, NULL);195 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);196 TEST_ASSERT_NOT_NULL(stmt);197 const char *saved = sqlite3_sql(stmt);198 TEST_ASSERT_NOT_NULL(saved);199 TEST_ASSERT_NOT_NULL(strstr(saved, "SELECT"));200 201 rc = sqlite3_step(stmt);202 TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);203 TEST_ASSERT_EQUAL_INT(42, sqlite3_column_int(stmt, 0));204 205 sqlite3_finalize(stmt);206 sqlite3_close(db);207}208 209int main(void){210 UNITY_BEGIN();211 RUN_TEST(test_sqlite3_prepare_v3_basic_select);212 RUN_TEST(test_sqlite3_prepare_v3_pzTail_multiple_statements_nbytes_neg1);213 RUN_TEST(test_sqlite3_prepare_v3_syntax_error);214 RUN_TEST(test_sqlite3_prepare_v3_too_long_with_limit_and_nbytes);215 RUN_TEST(test_sqlite3_prepare_v3_empty_sql_nbytes_zero);216 RUN_TEST(test_sqlite3_prepare_v3_null_sql_misuse);217 RUN_TEST(test_sqlite3_prepare_v3_embedded_nul);218 RUN_TEST(test_sqlite3_prepare_v3_persistent_flag);219 return UNITY_END();220}