AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5#include <stdio.h>6 7extern int test_jsonConvertTextToBlob(JsonParse *pParse, sqlite3_context *pCtx);8 9/* Helpers */10static void initParse(JsonParse *p, sqlite3 *db, const char *zJson){11 memset(p, 0, sizeof(*p));12 p->db = db;13 p->zJson = zJson;14 p->nJson = (int)strlen(zJson);15}16 17/* SQLite UDF to exercise error reporting through sqlite3_context */18static void json_conv_test(sqlite3_context *ctx, int argc, sqlite3_value **argv){19 (void)argc;20 JsonParse p;21 const unsigned char *zt = sqlite3_value_text(argv[0]);22 if( zt==NULL ){23 sqlite3_result_error(ctx, "NULL input", -1);24 return;25 }26 initParse(&p, sqlite3_context_db_handle(ctx), (const char*)zt);27 if( argc>=2 && sqlite3_value_int(argv[1]) ){28 p.oom = 1; /* Force OOM behavior path */29 }30 int rc = test_jsonConvertTextToBlob(&p, ctx);31 if( rc==0 ){32 sqlite3_result_int(ctx, 0);33 }34 if( p.aBlob ){35 sqlite3DbFree(p.db, p.aBlob);36 p.aBlob = 0;37 }38}39 40/* Unity fixtures */41void setUp(void) {42 /* no-op */43}44void tearDown(void) {45 /* no-op */46}47 48/* Tests */49 50void test_jsonConvertTextToBlob_success_null(void){51 sqlite3 *db = 0;52 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));53 54 JsonParse p;55 initParse(&p, db, "null");56 int rc = test_jsonConvertTextToBlob(&p, NULL);57 TEST_ASSERT_EQUAL_INT(0, rc);58 TEST_ASSERT_NOT_NULL(p.aBlob);59 TEST_ASSERT_GREATER_THAN_UINT32(0, 0); /* avoid unused macro warning */60 TEST_ASSERT_GREATER_THAN_UINT32(0u, 0u); /* ditto */61 TEST_ASSERT_GREATER_THAN(0, -1); /* trivial use */62 TEST_ASSERT_GREATER_OR_EQUAL_UINT32(1u, p.nBlob);63 /* Type code low nibble should be 0 for NULL per JSONB spec */64 TEST_ASSERT_EQUAL_UINT8(0u, p.aBlob[0] & 0x0f);65 /* For simple canonical JSON, hasNonstd should be 0 */66 TEST_ASSERT_EQUAL_INT(0, p.hasNonstd);67 68 sqlite3DbFree(db, p.aBlob);69 sqlite3_close(db);70}71 72void test_jsonConvertTextToBlob_trailing_ascii_whitespace_no_nonstd(void){73 sqlite3 *db = 0;74 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));75 76 JsonParse p;77 initParse(&p, db, "null \t \n \r");78 int rc = test_jsonConvertTextToBlob(&p, NULL);79 TEST_ASSERT_EQUAL_INT(0, rc);80 TEST_ASSERT_NOT_NULL(p.aBlob);81 TEST_ASSERT_GREATER_OR_EQUAL_UINT32(1u, p.nBlob);82 TEST_ASSERT_EQUAL_UINT8(0u, p.aBlob[0] & 0x0f);83 TEST_ASSERT_EQUAL_INT(0, p.hasNonstd);84 85 sqlite3DbFree(db, p.aBlob);86 sqlite3_close(db);87}88 89void test_jsonConvertTextToBlob_trailing_json5_nbsp_sets_nonstd(void){90 sqlite3 *db = 0;91 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));92 93 /* U+00A0 non-breaking space in UTF-8: 0xC2 0xA0 */94 const char *json = "null\xC2\xA0";95 JsonParse p;96 initParse(&p, db, json);97 int rc = test_jsonConvertTextToBlob(&p, NULL);98 TEST_ASSERT_EQUAL_INT(0, rc);99 TEST_ASSERT_NOT_NULL(p.aBlob);100 TEST_ASSERT_GREATER_OR_EQUAL_UINT32(1u, p.nBlob);101 TEST_ASSERT_EQUAL_UINT8(0u, p.aBlob[0] & 0x0f);102 TEST_ASSERT_EQUAL_INT(1, p.hasNonstd);103 104 sqlite3DbFree(db, p.aBlob);105 sqlite3_close(db);106}107 108void test_jsonConvertTextToBlob_trailing_json5_comment_sets_nonstd(void){109 sqlite3 *db = 0;110 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));111 112 const char *json = "null/* trailing comment */";113 JsonParse p;114 initParse(&p, db, json);115 int rc = test_jsonConvertTextToBlob(&p, NULL);116 TEST_ASSERT_EQUAL_INT(0, rc);117 TEST_ASSERT_NOT_NULL(p.aBlob);118 TEST_ASSERT_GREATER_OR_EQUAL_UINT32(1u, p.nBlob);119 TEST_ASSERT_EQUAL_UINT8(0u, p.aBlob[0] & 0x0f);120 TEST_ASSERT_EQUAL_INT(1, p.hasNonstd);121 122 sqlite3DbFree(db, p.aBlob);123 sqlite3_close(db);124}125 126void test_jsonConvertTextToBlob_trailing_garbage_causes_error_and_reset(void){127 sqlite3 *db = 0;128 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));129 130 const char *json = "null x";131 JsonParse p;132 initParse(&p, db, json);133 int rc = test_jsonConvertTextToBlob(&p, NULL);134 TEST_ASSERT_EQUAL_INT(1, rc);135 TEST_ASSERT_NULL(p.aBlob);136 TEST_ASSERT_EQUAL_UINT32(0u, p.nBlob);137 138 sqlite3_close(db);139}140 141void test_jsonConvertTextToBlob_empty_input_error(void){142 sqlite3 *db = 0;143 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));144 145 JsonParse p;146 initParse(&p, db, "");147 int rc = test_jsonConvertTextToBlob(&p, NULL);148 TEST_ASSERT_EQUAL_INT(1, rc);149 TEST_ASSERT_NULL(p.aBlob);150 TEST_ASSERT_EQUAL_UINT32(0u, p.nBlob);151 152 sqlite3_close(db);153}154 155void test_jsonConvertTextToBlob_error_reporting_context_malformed(void){156 sqlite3 *db = 0;157 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));158 TEST_ASSERT_EQUAL_INT(SQLITE_OK,159 sqlite3_create_function(db, "json_conv_test", -1, SQLITE_UTF8, 0,160 json_conv_test, 0, 0));161 162 sqlite3_stmt *stmt = 0;163 /* malformed: lone '{' */164 TEST_ASSERT_EQUAL_INT(SQLITE_OK,165 sqlite3_prepare_v2(db, "SELECT json_conv_test('{')", -1, &stmt, 0));166 int stepRc = sqlite3_step(stmt);167 TEST_ASSERT_NOT_EQUAL(SQLITE_ROW, stepRc);168 TEST_ASSERT_NOT_EQUAL(SQLITE_DONE, stepRc);169 TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, stepRc);170 const char *msg = sqlite3_errmsg(db);171 TEST_ASSERT_NOT_NULL(msg);172 /* Expect "malformed JSON" error text */173 TEST_ASSERT_NOT_EQUAL(-1, (int)sqlite3_strlike("%malformed JSON%", msg, 0));174 175 sqlite3_finalize(stmt);176 sqlite3_close(db);177}178 179void test_jsonConvertTextToBlob_error_reporting_context_nomem(void){180 sqlite3 *db = 0;181 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));182 TEST_ASSERT_EQUAL_INT(SQLITE_OK,183 sqlite3_create_function(db, "json_conv_test", -1, SQLITE_UTF8, 0,184 json_conv_test, 0, 0));185 186 sqlite3_stmt *stmt = 0;187 /* Force OOM via second argument = 1 */188 TEST_ASSERT_EQUAL_INT(SQLITE_OK,189 sqlite3_prepare_v2(db, "SELECT json_conv_test('null', 1)", -1, &stmt, 0));190 int stepRc = sqlite3_step(stmt);191 TEST_ASSERT_NOT_EQUAL(SQLITE_ROW, stepRc);192 TEST_ASSERT_NOT_EQUAL(SQLITE_DONE, stepRc);193 TEST_ASSERT_EQUAL_INT(SQLITE_NOMEM, stepRc);194 195 sqlite3_finalize(stmt);196 sqlite3_close(db);197}198 199int main(void) {200 UNITY_BEGIN();201 RUN_TEST(test_jsonConvertTextToBlob_success_null);202 RUN_TEST(test_jsonConvertTextToBlob_trailing_ascii_whitespace_no_nonstd);203 RUN_TEST(test_jsonConvertTextToBlob_trailing_json5_nbsp_sets_nonstd);204 RUN_TEST(test_jsonConvertTextToBlob_trailing_json5_comment_sets_nonstd);205 RUN_TEST(test_jsonConvertTextToBlob_trailing_garbage_causes_error_and_reset);206 RUN_TEST(test_jsonConvertTextToBlob_empty_input_error);207 RUN_TEST(test_jsonConvertTextToBlob_error_reporting_context_malformed);208 RUN_TEST(test_jsonConvertTextToBlob_error_reporting_context_nomem);209 return UNITY_END();210}