Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_json_jsonbValidityCheck.c316 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/* Wrapper is provided in the module for static function */8extern u32 test_jsonbValidityCheck(const JsonParse *pParse, u32 i, u32 iEnd, u32 iDepth);9 10void setUp(void) {11  /* no-op */12}13void tearDown(void) {14  /* no-op */15}16 17/* Helpers to build JSONB elements */18static inline u8 hdr_sz1(u8 type, u8 sz){19  return (u8)((sz<<4) | (type&0x0f));20}21static inline u8 hdr_sel(u8 type, u8 sel){ /* sel = 12,13,14 */22  return (u8)((sel<<4) | (type&0x0f));23}24static u32 runCheck(const u8 *buf, u32 n, u32 depth){25  JsonParse p;26  memset(&p, 0, sizeof(p));27  p.aBlob = (u8*)buf;28  p.nBlob = n;29  p.delta = 0;30  return test_jsonbValidityCheck(&p, 0, n, depth);31}32 33/* -------- Tests -------- */34 35void test_jsonbValidityCheck_valid_null_true_false(void){36  /* NULL valid */37  {38    u8 b[] = { hdr_sz1(JSONB_NULL, 0) };39    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));40  }41  /* TRUE with non-zero payload => error at offset 1 (i+1) */42  {43    u8 b[] = { hdr_sz1(JSONB_TRUE, 1), 'X' };44    TEST_ASSERT_EQUAL_UINT32(1, runCheck(b, sizeof(b), 0));45  }46  /* FALSE valid */47  {48    u8 b[] = { hdr_sz1(JSONB_FALSE, 0) };49    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));50  }51}52 53void test_jsonbValidityCheck_int_valid_and_errors(void){54  /* INT valid "123" */55  {56    u8 b[] = { hdr_sz1(JSONB_INT, 3), '1','2','3' };57    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));58  }59  /* INT valid "-7" */60  {61    u8 b[] = { hdr_sz1(JSONB_INT, 2), '-', '7' };62    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));63  }64  /* INT invalid lone '-' -> error at offset 1 */65  {66    u8 b[] = { hdr_sz1(JSONB_INT, 1), '-' };67    TEST_ASSERT_EQUAL_UINT32(1, runCheck(b, sizeof(b), 0));68  }69  /* INT invalid "1a3" -> error at 'a' which is at index 2 (0-based), so return 3 */70  {71    u8 b[] = { hdr_sz1(JSONB_INT, 3), '1', 'a', '3' };72    TEST_ASSERT_EQUAL_UINT32(3, runCheck(b, sizeof(b), 0));73  }74}75 76void test_jsonbValidityCheck_int5_variants(void){77  /* INT5 valid "0x1f" */78  {79    u8 b[] = { hdr_sz1(JSONB_INT5, 4), '0','x','1','f' };80    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));81  }82  /* INT5 valid "-0x1F" */83  {84    u8 b[] = { hdr_sz1(JSONB_INT5, 5), '-', '0','x','1','F' };85    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));86  }87  /* INT5 invalid missing leading '0': "1x0" -> error at i+1 = 1 */88  {89    u8 b[] = { hdr_sz1(JSONB_INT5, 3), '1','x','0' };90    TEST_ASSERT_EQUAL_UINT32(1, runCheck(b, sizeof(b), 0));91  }92  /* INT5 invalid wrong prefix "0y0" -> error returns j+2, here j=1 so 3 */93  {94    u8 b[] = { hdr_sz1(JSONB_INT5, 3), '0','y','0' };95    TEST_ASSERT_EQUAL_UINT32(3, runCheck(b, sizeof(b), 0));96  }97  /* INT5 invalid non-hex "0xG" -> error at index 3 -> returns 4 */98  {99    u8 b[] = { hdr_sz1(JSONB_INT5, 3), '0','x','G' };100    TEST_ASSERT_EQUAL_UINT32(4, runCheck(b, sizeof(b), 0));101  }102}103 104void test_jsonbValidityCheck_float_variants(void){105  /* FLOAT valid "1.2" */106  {107    u8 b[] = { hdr_sz1(JSONB_FLOAT, 3), '1','.','2' };108    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));109  }110  /* FLOAT valid "3e+5" */111  {112    u8 b[] = { hdr_sz1(JSONB_FLOAT, 4), '3','e','+','5' };113    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));114  }115  /* FLOAT invalid no '.' or 'e': "12" -> final seen==0 => i+1 = 1 */116  {117    u8 b[] = { hdr_sz1(JSONB_FLOAT, 2), '1','2' };118    TEST_ASSERT_EQUAL_UINT32(1, runCheck(b, sizeof(b), 0));119  }120  /* FLOAT invalid "0" too short -> sz<2 => i+1 = 1 */121  {122    u8 b[] = { hdr_sz1(JSONB_FLOAT, 1), '0' };123    TEST_ASSERT_EQUAL_UINT32(1, runCheck(b, sizeof(b), 0));124  }125  /* FLOAT invalid trailing '.' in RFC-8259 float: "1." -> error at '.' => index 2 => return 3 */126  {127    u8 b[] = { hdr_sz1(JSONB_FLOAT, 2), '1','.' };128    TEST_ASSERT_EQUAL_UINT32(3, runCheck(b, sizeof(b), 0));129  }130  /* FLOAT5 valid leading '.' ".5" */131  {132    u8 b[] = { hdr_sz1(JSONB_FLOAT5, 2), '.','5' };133    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));134  }135  /* FLOAT5 valid "1." (allowed in JSON5) */136  {137    u8 b[] = { hdr_sz1(JSONB_FLOAT5, 2), '1','.' };138    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));139  }140}141 142void test_jsonbValidityCheck_text_variants(void){143  /* TEXT valid "abc" */144  {145    u8 b[] = { hdr_sz1(JSONB_TEXT, 3), 'a','b','c' };146    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));147  }148  /* TEXT invalid backslash "a\\b" -> error at backslash index 2 -> return 3 */149  {150    u8 b[] = { hdr_sz1(JSONB_TEXT, 3), 'a','\\','b' };151    TEST_ASSERT_EQUAL_UINT32(3, runCheck(b, sizeof(b), 0));152  }153}154 155void test_jsonbValidityCheck_textj_variants(void){156  /* TEXTJ valid with escapes: "a\\n" */157  {158    u8 b[] = { hdr_sz1(JSONB_TEXTJ, 3), 'a','\\','n' };159    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));160  }161  /* TEXTJ valid \\u0041 */162  {163    u8 b[] = { hdr_sz1(JSONB_TEXTJ, 6), '\\','u','0','0','4','1' };164    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));165  }166  /* TEXTJ invalid unescaped double-quote: a"b -> error at quote index 2 => return 3 */167  {168    u8 b[] = { hdr_sz1(JSONB_TEXTJ, 3), 'a','"','b' };169    TEST_ASSERT_EQUAL_UINT32(3, runCheck(b, sizeof(b), 0));170  }171  /* TEXTJ invalid control char 0x1F */172  {173    u8 b[] = { hdr_sz1(JSONB_TEXTJ, 1), 0x1F };174    TEST_ASSERT_EQUAL_UINT32(2, runCheck(b, sizeof(b), 0));175  }176  /* TEXTJ invalid dangling backslash at end: "\\" -> error at j+1 where j=1 => 2 */177  {178    u8 b[] = { hdr_sz1(JSONB_TEXTJ, 1), '\\' };179    TEST_ASSERT_EQUAL_UINT32(2, runCheck(b, sizeof(b), 0));180  }181  /* TEXTJ invalid bad unicode escape: "\\u12G4" -> bad hex at 'G' index 4 => return 5 */182  {183    u8 b[] = { hdr_sz1(JSONB_TEXTJ, 6), '\\','u','1','2','G','4' };184    TEST_ASSERT_EQUAL_UINT32(5, runCheck(b, sizeof(b), 0));185  }186}187 188void test_jsonbValidityCheck_text5_variants(void){189  /* TEXT5 valid \\x41 */190  {191    u8 b[] = { hdr_sz1(JSONB_TEXT5, 4), '\\','x','4','1' };192    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));193  }194  /* TEXT5 valid \\v */195  {196    u8 b[] = { hdr_sz1(JSONB_TEXT5, 2), '\\','v' };197    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));198  }199}200 201void test_jsonbValidityCheck_textraw_always_ok(void){202  /* TEXTRAW accepts any bytes */203  {204    u8 b[] = { hdr_sz1(JSONB_TEXTRAW, 4), 'a','"','\n','\\' };205    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));206  }207}208 209void test_jsonbValidityCheck_array_valid_and_errors(void){210  /* ARRAY valid: [ INT "12", TEXT "ab" ] */211  {212    u8 elem1[] = { hdr_sz1(JSONB_INT, 2), '1','2' };213    u8 elem2[] = { hdr_sz1(JSONB_TEXT, 2), 'a','b' };214    u8 b[1 + sizeof(elem1) + sizeof(elem2)];215    b[0] = hdr_sz1(JSONB_ARRAY, (u8)(sizeof(elem1)+sizeof(elem2)));216    memcpy(&b[1], elem1, sizeof(elem1));217    memcpy(&b[1+sizeof(elem1)], elem2, sizeof(elem2));218    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));219  }220  /* ARRAY invalid: subelement declares size too big for remaining payload */221  {222    u8 sub[] = { hdr_sz1(JSONB_INT, 2), '1' }; /* header says 2, only 1 byte provided */223    u8 b[1 + sizeof(sub)];224    b[0] = hdr_sz1(JSONB_ARRAY, (u8)sizeof(sub)); /* payload size is what we actually provide */225    memcpy(&b[1], sub, sizeof(sub));226    /* Expect error at start of subelement: j = 1 -> j+1 = 2 */227    TEST_ASSERT_EQUAL_UINT32(2, runCheck(b, sizeof(b), 0));228  }229}230 231void test_jsonbValidityCheck_object_valid_and_errors(void){232  /* OBJECT valid: {"k":1} with TEXT key and INT value */233  {234    u8 key[] = { hdr_sz1(JSONB_TEXT, 1), 'k' };235    u8 val[] = { hdr_sz1(JSONB_INT, 1), '1' };236    u8 b[1 + sizeof(key) + sizeof(val)];237    b[0] = hdr_sz1(JSONB_OBJECT, (u8)(sizeof(key)+sizeof(val)));238    memcpy(&b[1], key, sizeof(key));239    memcpy(&b[1+sizeof(key)], val, sizeof(val));240    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));241  }242  /* OBJECT invalid: key is not text (INT), should error at start of key -> return 2 */243  {244    u8 keyBad[] = { hdr_sz1(JSONB_INT, 1), '1' };245    u8 val[]    = { hdr_sz1(JSONB_INT, 1), '2' };246    u8 b[1 + sizeof(keyBad) + sizeof(val)];247    b[0] = hdr_sz1(JSONB_OBJECT, (u8)(sizeof(keyBad)+sizeof(val)));248    memcpy(&b[1], keyBad, sizeof(keyBad));249    memcpy(&b[1+sizeof(keyBad)], val, sizeof(val));250    TEST_ASSERT_EQUAL_UINT32(2, runCheck(b, sizeof(b), 0));251  }252  /* OBJECT invalid: odd number of elements (key only) -> error at j+1 where j==k==iEnd, iEnd=1+2=3 => returns 4 */253  {254    u8 key[] = { hdr_sz1(JSONB_TEXT, 1), 'k' };255    u8 b[1 + sizeof(key)];256    b[0] = hdr_sz1(JSONB_OBJECT, (u8)sizeof(key));257    memcpy(&b[1], key, sizeof(key));258    TEST_ASSERT_EQUAL_UINT32(4, runCheck(b, sizeof(b), 0));259  }260}261 262void test_jsonbValidityCheck_extended_headers(void){263  /* TEXT with 1-byte size (selector 12), size=3 */264  {265    u8 b[] = { hdr_sel(JSONB_TEXT, 12), 3, 'a','b','c' };266    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));267  }268  /* TEXT with 2-byte size (selector 13), size=3 */269  {270    u8 b[] = { hdr_sel(JSONB_TEXT, 13), 0, 3, 'x','y','z' };271    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));272  }273  /* TEXT with 4-byte size (selector 14), size=3 */274  {275    u8 b[] = { hdr_sel(JSONB_TEXT, 14), 0,0,0,3, '1','2','3' };276    TEST_ASSERT_EQUAL_UINT32(0, runCheck(b, sizeof(b), 0));277  }278}279 280void test_jsonbValidityCheck_array_with_truncated_extended_header(void){281  /* ARRAY payload begins with an element using selector 12 but truncated, causing jsonbPayloadSize to return 0 */282  {283    u8 sub_trunc[] = { hdr_sel(JSONB_INT, 12) }; /* missing size byte */284    u8 b[1 + sizeof(sub_trunc)];285    b[0] = hdr_sz1(JSONB_ARRAY, (u8)sizeof(sub_trunc)); /* payload size = 1 */286    memcpy(&b[1], sub_trunc, sizeof(sub_trunc));287    /* Expect error at start of subelement: index 1 -> return 2 */288    TEST_ASSERT_EQUAL_UINT32(2, runCheck(b, sizeof(b), 0));289  }290}291 292void test_jsonbValidityCheck_depth_limit(void){293  /* Any element with iDepth > JSON_MAX_DEPTH returns i+1 (1) */294  {295    u8 b[] = { hdr_sz1(JSONB_NULL, 0) };296    TEST_ASSERT_EQUAL_UINT32(1, runCheck(b, sizeof(b), JSON_MAX_DEPTH+1));297  }298}299 300int main(void){301  UNITY_BEGIN();302  RUN_TEST(test_jsonbValidityCheck_valid_null_true_false);303  RUN_TEST(test_jsonbValidityCheck_int_valid_and_errors);304  RUN_TEST(test_jsonbValidityCheck_int5_variants);305  RUN_TEST(test_jsonbValidityCheck_float_variants);306  RUN_TEST(test_jsonbValidityCheck_text_variants);307  RUN_TEST(test_jsonbValidityCheck_textj_variants);308  RUN_TEST(test_jsonbValidityCheck_text5_variants);309  RUN_TEST(test_jsonbValidityCheck_textraw_always_ok);310  RUN_TEST(test_jsonbValidityCheck_array_valid_and_errors);311  RUN_TEST(test_jsonbValidityCheck_object_valid_and_errors);312  RUN_TEST(test_jsonbValidityCheck_extended_headers);313  RUN_TEST(test_jsonbValidityCheck_array_with_truncated_extended_header);314  RUN_TEST(test_jsonbValidityCheck_depth_limit);315  return UNITY_END();316}