|
|
#include "sqliteInt.h" |
|
|
#include "unity.h" |
|
|
#include <stdlib.h> |
|
|
#include <string.h> |
|
|
|
|
|
|
|
|
extern int test_skipCreateTable(sqlite3_context *ctx, const u8 *zSql, int *piOff); |
|
|
|
|
|
void setUp(void) { |
|
|
|
|
|
} |
|
|
|
|
|
void tearDown(void) { |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static int call_skip_with_null_ctx(const char *zSql, int *piOff){ |
|
|
return test_skipCreateTable(NULL, (const unsigned char*)zSql, piOff); |
|
|
} |
|
|
|
|
|
|
|
|
void test_skipCreateTable_basic_simple(void) { |
|
|
const char *zSql = "CREATE TABLE t(a INTEGER, b TEXT)"; |
|
|
int off = -1; |
|
|
int rc = call_skip_with_null_ctx(zSql, &off); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
TEST_ASSERT_TRUE(off > 0); |
|
|
TEST_ASSERT_EQUAL_CHAR('(', zSql[off-1]); |
|
|
|
|
|
|
|
|
const char *pFirst = strchr(zSql, '('); |
|
|
TEST_ASSERT_NOT_NULL(pFirst); |
|
|
TEST_ASSERT_EQUAL_INT((int)(pFirst - zSql + 1), off); |
|
|
} |
|
|
|
|
|
|
|
|
void test_skipCreateTable_with_schema_and_quotes(void) { |
|
|
const char *zSql = " CREATE TEMP TABLE IF NOT EXISTS main.\"t name\" ( col1 INTEGER )"; |
|
|
int off = -1; |
|
|
int rc = call_skip_with_null_ctx(zSql, &off); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
TEST_ASSERT_TRUE(off > 0); |
|
|
TEST_ASSERT_EQUAL_CHAR('(', zSql[off-1]); |
|
|
|
|
|
const char *pFirst = strchr(zSql, '('); |
|
|
TEST_ASSERT_NOT_NULL(pFirst); |
|
|
TEST_ASSERT_EQUAL_INT((int)(pFirst - zSql + 1), off); |
|
|
} |
|
|
|
|
|
|
|
|
void test_skipCreateTable_ignores_paren_inside_string_literal(void) { |
|
|
|
|
|
|
|
|
const char *zSql = "CREATE TABLE t 'ignore (this) completely' (x INT)"; |
|
|
int off = -1; |
|
|
int rc = call_skip_with_null_ctx(zSql, &off); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
TEST_ASSERT_TRUE(off > 0); |
|
|
TEST_ASSERT_EQUAL_CHAR('(', zSql[off-1]); |
|
|
|
|
|
|
|
|
const char *pLast = strrchr(zSql, '('); |
|
|
TEST_ASSERT_NOT_NULL(pLast); |
|
|
TEST_ASSERT_EQUAL_INT((int)(pLast - zSql + 1), off); |
|
|
} |
|
|
|
|
|
|
|
|
void test_skipCreateTable_ignores_paren_inside_quoted_identifier(void) { |
|
|
const char *zSql = "CREATE TABLE [a(b)] (c TEXT)"; |
|
|
int off = -1; |
|
|
int rc = call_skip_with_null_ctx(zSql, &off); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
TEST_ASSERT_TRUE(off > 0); |
|
|
TEST_ASSERT_EQUAL_CHAR('(', zSql[off-1]); |
|
|
|
|
|
|
|
|
const char *pLast = strrchr(zSql, '('); |
|
|
TEST_ASSERT_NOT_NULL(pLast); |
|
|
TEST_ASSERT_EQUAL_INT((int)(pLast - zSql + 1), off); |
|
|
} |
|
|
|
|
|
|
|
|
void test_skipCreateTable_null_input_returns_error(void) { |
|
|
int off = 1234; |
|
|
int rc = test_skipCreateTable(NULL, NULL, &off); |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc); |
|
|
TEST_ASSERT_EQUAL_INT(1234, off); |
|
|
} |
|
|
|
|
|
|
|
|
static int g_rc_from_udf = 0; |
|
|
static int g_off_from_udf = 0; |
|
|
|
|
|
|
|
|
static void udf_call_skip(sqlite3_context *ctx, int argc, sqlite3_value **argv){ |
|
|
(void)argc; |
|
|
const unsigned char *zSql = sqlite3_value_text(argv[0]); |
|
|
int off = -1; |
|
|
int rc = test_skipCreateTable(ctx, zSql, &off); |
|
|
g_rc_from_udf = rc; |
|
|
g_off_from_udf = off; |
|
|
|
|
|
|
|
|
sqlite3_result_int(ctx, rc); |
|
|
} |
|
|
|
|
|
|
|
|
void test_skipCreateTable_no_open_paren_illegal_token_via_udf(void) { |
|
|
sqlite3 *db = NULL; |
|
|
sqlite3_stmt *stmt = NULL; |
|
|
|
|
|
int rc = sqlite3_open(":memory:", &db); |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
|
|
|
rc = sqlite3_create_function_v2(db, "xskip", 1, SQLITE_UTF8, NULL, |
|
|
udf_call_skip, NULL, NULL, NULL); |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
|
|
|
|
|
|
const char *sql = "SELECT xskip('CREATE TABLE t')"; |
|
|
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0); |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
|
|
|
int steprc = sqlite3_step(stmt); |
|
|
|
|
|
|
|
|
|
|
|
(void)steprc; |
|
|
|
|
|
rc = sqlite3_finalize(stmt); |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
|
|
|
sqlite3_close(db); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, g_rc_from_udf); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(-1, g_off_from_udf); |
|
|
} |
|
|
|
|
|
int main(void) { |
|
|
UNITY_BEGIN(); |
|
|
RUN_TEST(test_skipCreateTable_basic_simple); |
|
|
RUN_TEST(test_skipCreateTable_with_schema_and_quotes); |
|
|
RUN_TEST(test_skipCreateTable_ignores_paren_inside_string_literal); |
|
|
RUN_TEST(test_skipCreateTable_ignores_paren_inside_quoted_identifier); |
|
|
RUN_TEST(test_skipCreateTable_null_input_returns_error); |
|
|
RUN_TEST(test_skipCreateTable_no_open_paren_illegal_token_via_udf); |
|
|
return UNITY_END(); |
|
|
} |