Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_printf_sqlite3RCStrUnref.c138 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5#include <stdint.h>6 7/* Target under test */8void sqlite3RCStrUnref(void *z);9 10/* Helper: allocate an RCStr header plus payload and return both the header and the z pointer */11static RCStr* helper_alloc_rcstr(int refCount, size_t payloadSize, void **pzOut){12  size_t nByte = sizeof(RCStr) + payloadSize;13  RCStr *p = (RCStr*)sqlite3_malloc(nByte ? nByte : 1);14  TEST_ASSERT_NOT_NULL_MESSAGE(p, "sqlite3_malloc for RCStr failed");15  /* Zero the header only; payload can be anything */16  memset(p, 0, sizeof(RCStr));17  p->nRCRef = refCount;18  char *z = (char*)&p[1];19  if( payloadSize>0 ){20    memset(z, 0xAB, payloadSize);21    z[payloadSize-1] = 0; /* ensure a trailing 0 if size>0 for safety */22  }23  *pzOut = (void*)z;24  return p;25}26 27void setUp(void) {28  /* no-op */29}30void tearDown(void) {31  /* no-op */32}33 34/* Test: When nRCRef==2, it decrements to 1 and does not free */35void test_sqlite3RCStrUnref_decrement_from_two(void){36  void *z = NULL;37  RCStr *p = helper_alloc_rcstr(2, 16, &z);38 39  /* Sanity: pointer arithmetic expectation */40  RCStr *calc = (RCStr*)z;41  calc--;42  TEST_ASSERT_EQUAL_PTR(p, calc);43 44  sqlite3RCStrUnref(z);45  TEST_ASSERT_EQUAL_INT(1, p->nRCRef);46 47  /* Final unref should free. Do not access p after this call. */48  sqlite3RCStrUnref(z);49}50 51/* Test: When nRCRef>2 (e.g., 5), it decrements by exactly 1 and remains valid */52void test_sqlite3RCStrUnref_decrement_from_five(void){53  void *z = NULL;54  RCStr *p = helper_alloc_rcstr(5, 8, &z);55 56  sqlite3RCStrUnref(z);57  TEST_ASSERT_EQUAL_INT(4, p->nRCRef);58 59  sqlite3RCStrUnref(z);60  TEST_ASSERT_EQUAL_INT(3, p->nRCRef);61 62  /* Clean up remaining references: two more to reach 1, then final free */63  sqlite3RCStrUnref(z); /* 3->2 */64  TEST_ASSERT_EQUAL_INT(2, p->nRCRef);65  sqlite3RCStrUnref(z); /* 2->1 */66  TEST_ASSERT_EQUAL_INT(1, p->nRCRef);67 68  /* Final unref frees memory. Do not touch p after this. */69  sqlite3RCStrUnref(z);70}71 72/* Test: When nRCRef==1, it frees the allocation (no crash) */73void test_sqlite3RCStrUnref_free_on_one(void){74  void *z = NULL;75  RCStr *p = helper_alloc_rcstr(1, 4, &z);76  (void)p; /* not used further to avoid use-after-free */77 78  /* This should free the RCStr; success is absence of crash. */79  sqlite3RCStrUnref(z);80 81  /* Do not dereference p here; it has been freed. */82}83 84/* Test: Multiple independent RCStr objects do not interfere with each other */85void test_sqlite3RCStrUnref_multiple_independent(void){86  void *z1 = NULL;87  void *z2 = NULL;88  RCStr *p1 = helper_alloc_rcstr(3, 12, &z1);89  RCStr *p2 = helper_alloc_rcstr(2, 12, &z2);90 91  /* Unref first object once */92  sqlite3RCStrUnref(z1);93  TEST_ASSERT_EQUAL_INT(2, p1->nRCRef);94  TEST_ASSERT_EQUAL_INT(2, p2->nRCRef); /* unaffected */95 96  /* Unref second object once */97  sqlite3RCStrUnref(z2);98  TEST_ASSERT_EQUAL_INT(2, p1->nRCRef);99  TEST_ASSERT_EQUAL_INT(1, p2->nRCRef);100 101  /* Finalize second object (free) */102  sqlite3RCStrUnref(z2);103  /* Do not access p2 beyond this point */104 105  /* Clean up first object: decrement to 1 then final free */106  sqlite3RCStrUnref(z1); /* 2->1 */107  TEST_ASSERT_EQUAL_INT(1, p1->nRCRef);108  sqlite3RCStrUnref(z1); /* 1->free */109}110 111/* A simple stress: create and release several RCStr objects (nRCRef==2) */112void test_sqlite3RCStrUnref_stress_small_batch(void){113  enum { N = 10 };114  RCStr *headers[N];115  void *ptrs[N];116  memset(headers, 0, sizeof(headers));117  memset(ptrs, 0, sizeof(ptrs));118  for(int i=0;i<N;i++){119    headers[i] = helper_alloc_rcstr(2, 16, &ptrs[i]);120  }121  for(int i=0;i<N;i++){122    sqlite3RCStrUnref(ptrs[i]); /* 2->1 */123    TEST_ASSERT_EQUAL_INT(1, headers[i]->nRCRef);124  }125  for(int i=0;i<N;i++){126    sqlite3RCStrUnref(ptrs[i]); /* 1->free */127  }128}129 130int main(void){131  UNITY_BEGIN();132  RUN_TEST(test_sqlite3RCStrUnref_decrement_from_two);133  RUN_TEST(test_sqlite3RCStrUnref_decrement_from_five);134  RUN_TEST(test_sqlite3RCStrUnref_free_on_one);135  RUN_TEST(test_sqlite3RCStrUnref_multiple_independent);136  RUN_TEST(test_sqlite3RCStrUnref_stress_small_batch);137  return UNITY_END();138}