AryaWu/sqlite
0
1/* tests_json_jsonBlobMakeEditable.c */2#include "sqliteInt.h"3#include "unity.h"4#include <string.h>5#include <stdint.h>6#include <stdio.h>7 8/* Wrapper for the static function provided by the module */9extern int test_jsonBlobMakeEditable(JsonParse *pParse, u32 nExtra);10 11static sqlite3 *gDb = NULL;12 13void setUp(void) {14 int rc = sqlite3_open(":memory:", &gDb);15 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);16 TEST_ASSERT_NOT_NULL(gDb);17}18 19void tearDown(void) {20 if (gDb) {21 sqlite3_close(gDb);22 gDb = NULL;23 }24}25 26/* Helper to initialize a JsonParse structure safely */27static void jp_init(JsonParse *p){28 memset(p, 0, sizeof(*p));29 p->db = gDb;30 p->bReadOnly = 0; /* Must be false per assert in target function */31 p->oom = 0;32}33 34/* 1) Returns failure immediately if oom already set. No state change. */35void test_jsonBlobMakeEditable_returns_early_if_oom_set(void){36 JsonParse jp;37 jp_init(&jp);38 jp.oom = 1;39 jp.nBlobAlloc = 0;40 jp.nBlob = 1;41 jp.aBlob = (u8*)"X"; /* read-only source */42 43 u8 *oldPtr = jp.aBlob;44 u32 oldAlloc = jp.nBlobAlloc;45 46 int rc = test_jsonBlobMakeEditable(&jp, 10);47 TEST_ASSERT_EQUAL_INT(0, rc);48 TEST_ASSERT_EQUAL_PTR(oldPtr, jp.aBlob);49 TEST_ASSERT_EQUAL_UINT32(oldAlloc, jp.nBlobAlloc);50 TEST_ASSERT_EQUAL_INT(1, jp.oom);51}52 53/* 2) No-op if already editable (nBlobAlloc>0). Pointer and alloc unchanged. */54void test_jsonBlobMakeEditable_noop_if_already_editable(void){55 JsonParse jp;56 jp_init(&jp);57 58 jp.nBlobAlloc = 200;59 jp.nBlob = 5;60 jp.aBlob = (u8*)sqlite3DbMallocZero(gDb, jp.nBlobAlloc);61 TEST_ASSERT_NOT_NULL(jp.aBlob);62 memcpy(jp.aBlob, "abcde", 5);63 64 u8 *oldPtr = jp.aBlob;65 u32 oldAlloc = jp.nBlobAlloc;66 67 int rc = test_jsonBlobMakeEditable(&jp, 50);68 TEST_ASSERT_EQUAL_INT(1, rc);69 TEST_ASSERT_EQUAL_PTR(oldPtr, jp.aBlob);70 TEST_ASSERT_EQUAL_UINT32(oldAlloc, jp.nBlobAlloc);71 TEST_ASSERT_EQUAL_UINT32(5, jp.nBlob);72 TEST_ASSERT_EQUAL_INT(0, memcmp(jp.aBlob, "abcde", 5));73 74 sqlite3DbFree(gDb, oldPtr);75}76 77/* 3) Makes copy and expands for small N (nBlob + nExtra <= 100) */78void test_jsonBlobMakeEditable_makes_copy_and_expands_small(void){79 JsonParse jp;80 jp_init(&jp);81 82 const char *src = "0123456789";83 jp.nBlobAlloc = 0;84 jp.nBlob = 10;85 jp.aBlob = (u8*)src;86 87 int rc = test_jsonBlobMakeEditable(&jp, 50); /* N = 60 -> alloc 100 */88 TEST_ASSERT_EQUAL_INT(1, rc);89 TEST_ASSERT_NOT_NULL(jp.aBlob);90 TEST_ASSERT(jp.aBlob != (u8*)src);91 TEST_ASSERT_EQUAL_UINT32(100, jp.nBlobAlloc);92 TEST_ASSERT_EQUAL_INT(0, memcmp(jp.aBlob, src, jp.nBlob));93 94 sqlite3DbFree(gDb, jp.aBlob);95}96 97/* 4) Makes copy and expands for larger N (expect nBlobAlloc = N + 100) */98void test_jsonBlobMakeEditable_makes_copy_and_expands_large(void){99 JsonParse jp;100 jp_init(&jp);101 102 const u32 nBlob = 1000;103 const u32 nExtra = 100; /* N = 1100 -> alloc 1200 */104 u8 *src = (u8*)sqlite3_malloc(nBlob);105 TEST_ASSERT_NOT_NULL(src);106 for(u32 i = 0; i < nBlob; i++) src[i] = (u8)(i & 0xFF);107 108 jp.nBlobAlloc = 0;109 jp.nBlob = nBlob;110 jp.aBlob = src;111 112 int rc = test_jsonBlobMakeEditable(&jp, nExtra);113 TEST_ASSERT_EQUAL_INT(1, rc);114 TEST_ASSERT_NOT_NULL(jp.aBlob);115 TEST_ASSERT(jp.aBlob != src);116 TEST_ASSERT_EQUAL_UINT32(nBlob + nExtra + 100, jp.nBlobAlloc);117 TEST_ASSERT_EQUAL_INT(0, memcmp(jp.aBlob, src, nBlob));118 119 sqlite3DbFree(gDb, jp.aBlob);120 sqlite3_free(src);121}122 123/* 5) Allocates when starting empty (nBlob==0) with positive nExtra */124void test_jsonBlobMakeEditable_allocates_from_empty_with_extra(void){125 JsonParse jp;126 jp_init(&jp);127 128 jp.nBlobAlloc = 0;129 jp.nBlob = 0;130 jp.aBlob = NULL;131 132 int rc = test_jsonBlobMakeEditable(&jp, 10); /* N = 10 -> alloc 100 */133 TEST_ASSERT_EQUAL_INT(1, rc);134 TEST_ASSERT_NOT_NULL(jp.aBlob);135 TEST_ASSERT_EQUAL_UINT32(100, jp.nBlobAlloc);136 TEST_ASSERT_EQUAL_UINT32(0, jp.nBlob);137 138 sqlite3DbFree(gDb, jp.aBlob);139}140 141int main(void) {142 UNITY_BEGIN();143 RUN_TEST(test_jsonBlobMakeEditable_returns_early_if_oom_set);144 RUN_TEST(test_jsonBlobMakeEditable_noop_if_already_editable);145 RUN_TEST(test_jsonBlobMakeEditable_makes_copy_and_expands_small);146 RUN_TEST(test_jsonBlobMakeEditable_makes_copy_and_expands_large);147 RUN_TEST(test_jsonBlobMakeEditable_allocates_from_empty_with_extra);148 return UNITY_END();149}