fuzzerCreate.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. #include "RyanJson.h"
  2. #include "RyanJsonFuzzer.h"
  3. /**
  4. * @brief 创建与插入测试
  5. *
  6. * 测试 RyanJson 的节点创建、数据类型设置以及对象/数组的插入操作。
  7. * 覆盖场景:
  8. * 异常参数注入:测试空指针、无效 key、类型不匹配等错误处理。
  9. * 基础类型创建:测试 Bool/Int/Double/String 及其数组的创建与添加。
  10. * 递归结构构建:递归地向对象/数组中添加随机生成的子节点。
  11. * 边界插入测试:覆盖数组头部与中间位置插入。
  12. *
  13. * @param state Fuzzer 状态上下文
  14. * @param pJson 当前正在操作的 Json 节点
  15. * @param size 输入数据大小,用于控制递归深度和随机决策
  16. */
  17. RyanJsonBool_e RyanJsonFuzzerTestCreate(RyanJson_t pJson, uint32_t size)
  18. {
  19. // 覆盖 RyanJsonIsDetachedItem 的防御分支:
  20. // next==NULL 但 IsLast==1 属于非法游离态,应返回 false。
  21. // 该路径只需覆盖一次,避免每轮 fuzz 重复创建节点。
  22. static RyanJsonBool_e detachedFlagBranchCovered = RyanJsonFalse;
  23. if (RyanJsonFalse == detachedFlagBranchCovered)
  24. {
  25. RyanJsonBool_e lastIsEnableMemFail = g_fuzzerState.isEnableMemFail;
  26. g_fuzzerState.isEnableMemFail = false;
  27. RyanJson_t malformedDetached = RyanJsonCreateInt(NULL, 1);
  28. assert(NULL != malformedDetached);
  29. assert(RyanJsonTrue == RyanJsonIsDetachedItem(malformedDetached));
  30. RyanJsonSetPayloadIsLastByFlag(malformedDetached, RyanJsonTrue);
  31. assert(RyanJsonFalse == RyanJsonIsDetachedItem(malformedDetached));
  32. // 恢复 flag,避免后续 Delete 走错链表语义
  33. RyanJsonSetPayloadIsLastByFlag(malformedDetached, RyanJsonFalse);
  34. RyanJsonDelete(malformedDetached);
  35. g_fuzzerState.isEnableMemFail = lastIsEnableMemFail;
  36. detachedFlagBranchCovered = RyanJsonTrue;
  37. }
  38. // 覆盖对象重复 key 防御分支(一次性)
  39. static RyanJsonBool_e duplicateKeyGuardCovered = RyanJsonFalse;
  40. if (RyanJsonFalse == duplicateKeyGuardCovered)
  41. {
  42. RyanJsonBool_e lastIsEnableMemFail = g_fuzzerState.isEnableMemFail;
  43. g_fuzzerState.isEnableMemFail = false;
  44. RyanJson_t obj = RyanJsonCreateObject();
  45. assert(NULL != obj);
  46. assert(RyanJsonTrue == RyanJsonAddIntToObject(obj, "dup", 1));
  47. #if true == RyanJsonStrictObjectKeyCheck
  48. assert(RyanJsonFalse == RyanJsonAddIntToObject(obj, "dup", 2));
  49. assert(RyanJsonFalse == RyanJsonInsert(obj, UINT32_MAX, RyanJsonCreateInt("dup", 3)));
  50. assert(1 == RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "dup")));
  51. #else
  52. assert(RyanJsonTrue == RyanJsonAddIntToObject(obj, "dup", 2));
  53. assert(RyanJsonTrue == RyanJsonInsert(obj, UINT32_MAX, RyanJsonCreateInt("dup", 3)));
  54. assert(3 == RyanJsonGetSize(obj));
  55. #if true == RyanJsonDefaultAddAtHead
  56. assert(2 == RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "dup")));
  57. #else
  58. assert(1 == RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "dup")));
  59. #endif
  60. #endif
  61. RyanJsonDelete(obj);
  62. g_fuzzerState.isEnableMemFail = lastIsEnableMemFail;
  63. duplicateKeyGuardCovered = RyanJsonTrue;
  64. }
  65. // RyanJsonInsert 特殊路径:模拟内存分配失败或无效参数输入
  66. uint32_t index = 6;
  67. if (RyanJsonFuzzerShouldFail(100))
  68. {
  69. assert(RyanJsonFalse == RyanJsonInsert(NULL, UINT32_MAX, RyanJsonCreateString("key", "string")));
  70. assert(RyanJsonFalse == RyanJsonInsert(pJson, UINT32_MAX, NULL));
  71. assert(RyanJsonFalse == RyanJsonInsert(NULL, 0, NULL));
  72. assert(NULL == RyanJsonCreateString(NULL, NULL));
  73. assert(NULL == RyanJsonCreateString("NULL", NULL));
  74. assert(RyanJsonFalse == RyanJsonChangeStringValue(NULL, NULL));
  75. assert(RyanJsonFalse == RyanJsonChangeStringValue(pJson, NULL));
  76. assert(RyanJsonFalse == RyanJsonChangeStringValue(NULL, "NULL"));
  77. if (RyanJsonFalse == RyanJsonIsKey(pJson) && RyanJsonFalse == RyanJsonIsString(pJson)) // pJson 类型错误
  78. {
  79. assert(RyanJsonFalse == RyanJsonChangeStringValue(pJson, "NULL"));
  80. }
  81. assert(RyanJsonFalse == RyanJsonChangeKey(NULL, NULL));
  82. assert(RyanJsonFalse == RyanJsonChangeKey(pJson, NULL));
  83. assert(RyanJsonFalse == RyanJsonChangeKey(NULL, "NULL"));
  84. if (RyanJsonFalse == RyanJsonIsKey(pJson) && RyanJsonFalse == RyanJsonIsString(pJson)) // pJson 类型错误
  85. {
  86. g_fuzzerState.isEnableMemFail = false;
  87. assert(RyanJsonFalse == RyanJsonChangeKey(pJson, "NULL"));
  88. g_fuzzerState.isEnableMemFail = true;
  89. }
  90. // 测试“无 key 但有 strValue”的分支
  91. if (RyanJsonFalse == RyanJsonIsKey(pJson) && RyanJsonTrue == RyanJsonIsString(pJson))
  92. {
  93. g_fuzzerState.isEnableMemFail = false;
  94. assert(RyanJsonFalse == RyanJsonChangeKey(pJson, "NULL"));
  95. g_fuzzerState.isEnableMemFail = true;
  96. }
  97. assert(RyanJsonFalse == RyanJsonChangeIntValue(NULL, 0));
  98. assert(RyanJsonFalse == RyanJsonChangeDoubleValue(NULL, 0));
  99. assert(RyanJsonFalse == RyanJsonChangeBoolValue(NULL, 0));
  100. // Change 接口类型不匹配分支
  101. RyanJson_t mismatchNode = RyanJsonCreateDouble(NULL, 1.0);
  102. assert(RyanJsonFalse == RyanJsonChangeIntValue(mismatchNode, 7));
  103. if (NULL != mismatchNode) { RyanJsonDelete(mismatchNode); }
  104. mismatchNode = RyanJsonCreateInt(NULL, 1);
  105. assert(RyanJsonFalse == RyanJsonChangeDoubleValue(mismatchNode, 7.0));
  106. if (NULL != mismatchNode) { RyanJsonDelete(mismatchNode); }
  107. mismatchNode = RyanJsonCreateInt(NULL, 1);
  108. assert(RyanJsonFalse == RyanJsonChangeBoolValue(mismatchNode, RyanJsonTrue));
  109. if (NULL != mismatchNode) { RyanJsonDelete(mismatchNode); }
  110. mismatchNode = RyanJsonCreateString(NULL, "v");
  111. assert(RyanJsonFalse == RyanJsonChangeKey(mismatchNode, "k2"));
  112. if (NULL != mismatchNode) { RyanJsonDelete(mismatchNode); }
  113. mismatchNode = RyanJsonCreateBool(NULL, RyanJsonTrue);
  114. assert(RyanJsonFalse == RyanJsonChangeStringValue(mismatchNode, "x"));
  115. if (NULL != mismatchNode) { RyanJsonDelete(mismatchNode); }
  116. assert(RyanJsonFalse == RyanJsonAddItemToObject(NULL, NULL, NULL));
  117. assert(RyanJsonFalse == RyanJsonAddItemToObject(pJson, NULL, NULL));
  118. assert(NULL == RyanJsonCreateIntArray(NULL, 0));
  119. assert(NULL == RyanJsonCreateDoubleArray(NULL, 0));
  120. assert(NULL == RyanJsonCreateStringArray(NULL, 0));
  121. // 仅调用,不判断返回值,因为有可能会成功的
  122. RyanJsonHasObjectToKey(NULL, "0", "1", "2", "3");
  123. RyanJsonHasObjectToIndex(NULL, 0, 1, 2, 3);
  124. RyanJsonHasObjectToKey(pJson, "0", "1", "2", "3");
  125. RyanJsonHasObjectToIndex(pJson, 0, 1, 2, 3);
  126. RyanJsonHasObjectToIndex(pJson, 0);
  127. // 已挂树的 item 不应再次 Insert/AddItem
  128. {
  129. g_fuzzerState.isEnableMemFail = false;
  130. RyanJson_t arr1 = RyanJsonCreateArray();
  131. RyanJson_t arr2 = RyanJsonCreateArray();
  132. RyanJson_t attachedArr = RyanJsonCreateArray();
  133. assert(RyanJsonFalse == RyanJsonIsDetachedItem(NULL));
  134. assert(NULL != arr1 && NULL != arr2 && NULL != attachedArr);
  135. assert(RyanJsonTrue == RyanJsonIsDetachedItem(attachedArr));
  136. assert(RyanJsonTrue == RyanJsonInsert(arr1, 0, attachedArr));
  137. assert(RyanJsonFalse == RyanJsonIsDetachedItem(attachedArr));
  138. assert(RyanJsonFalse == RyanJsonInsert(arr2, 0, attachedArr));
  139. assert(RyanJsonFalse == RyanJsonAddItemToArray(arr2, attachedArr));
  140. RyanJson_t detachedArr = RyanJsonDetachByIndex(arr1, 0);
  141. assert(detachedArr == attachedArr);
  142. assert(RyanJsonTrue == RyanJsonIsDetachedItem(detachedArr));
  143. RyanJsonDelete(detachedArr);
  144. RyanJson_t obj1 = RyanJsonCreateObject();
  145. RyanJson_t obj2 = RyanJsonCreateObject();
  146. RyanJson_t attachedObj = RyanJsonInternalCreateObjectAndKey("k");
  147. assert(NULL != obj1 && NULL != obj2 && NULL != attachedObj);
  148. assert(RyanJsonTrue == RyanJsonIsDetachedItem(attachedObj));
  149. assert(RyanJsonTrue == RyanJsonInsert(obj1, 0, attachedObj));
  150. assert(RyanJsonFalse == RyanJsonIsDetachedItem(attachedObj));
  151. assert(RyanJsonFalse == RyanJsonInsert(obj2, 0, attachedObj));
  152. assert(RyanJsonFalse == RyanJsonAddItemToObject(obj2, "dup", attachedObj));
  153. RyanJson_t detachedObj = RyanJsonDetachByIndex(obj1, 0);
  154. assert(detachedObj == attachedObj);
  155. assert(RyanJsonTrue == RyanJsonIsDetachedItem(detachedObj));
  156. RyanJsonDelete(detachedObj);
  157. RyanJsonDelete(arr2);
  158. RyanJsonDelete(obj2);
  159. RyanJsonDelete(arr1);
  160. RyanJsonDelete(obj1);
  161. g_fuzzerState.isEnableMemFail = true;
  162. }
  163. }
  164. char *key = "keyaaa";
  165. RyanJsonAddNullToObject(pJson, key);
  166. // 如果当前节点是 key 类型,尝试获取其 key 字符串作为后续操作 key
  167. if (RyanJsonTrue == RyanJsonIsKey(pJson))
  168. {
  169. // Change 系列测试已在 modify 用例覆盖
  170. key = RyanJsonGetKey(pJson);
  171. }
  172. // 标量类型追加测试
  173. if (RyanJsonTrue == RyanJsonIsBool(pJson) && RyanJsonFuzzerShouldFail(index))
  174. {
  175. if (RyanJsonTrue == RyanJsonAddBoolToObject(pJson, key, RyanJsonGetBoolValue(pJson)))
  176. {
  177. fuzzTestWithMemFail(
  178. assert(RyanJsonGetBoolValue(RyanJsonGetObjectByKey(pJson, key)) == RyanJsonGetBoolValue(pJson)));
  179. }
  180. }
  181. if (RyanJsonTrue == RyanJsonIsNumber(pJson) && RyanJsonFuzzerShouldFail(index))
  182. {
  183. if (RyanJsonTrue == RyanJsonIsInt(pJson))
  184. {
  185. if (RyanJsonTrue == RyanJsonAddIntToObject(pJson, key, RyanJsonGetIntValue(pJson)))
  186. {
  187. fuzzTestWithMemFail(
  188. assert(RyanJsonGetIntValue(RyanJsonGetObjectByKey(pJson, key)) == RyanJsonGetIntValue(pJson)));
  189. }
  190. // 构造测试用 Int 数组
  191. int32_t val = RyanJsonGetIntValue(pJson);
  192. int32_t testIntArray[] = {val, val, val, val, val};
  193. RyanJsonBool_e jsonAddResult = RyanJsonAddItemToObject(
  194. pJson, (0 != size % 2) ? key : "arrayString",
  195. RyanJsonCreateIntArray(testIntArray, sizeof(testIntArray) / sizeof(testIntArray[0])));
  196. if (RyanJsonTrue == jsonAddResult)
  197. {
  198. fuzzTestWithMemFail({
  199. RyanJson_t itemIntArr = RyanJsonGetObjectByKey(pJson, key);
  200. assert(RyanJsonIsArray(itemIntArr));
  201. assert(RyanJsonGetArraySize(itemIntArr) == sizeof(testIntArray) / sizeof(testIntArray[0]));
  202. RyanJson_t item;
  203. RyanJsonArrayForEach(itemIntArr, item)
  204. {
  205. assert(RyanJsonGetIntValue(item) == val);
  206. }
  207. });
  208. }
  209. }
  210. else if (RyanJsonTrue == RyanJsonIsDouble(pJson))
  211. {
  212. if (RyanJsonTrue == RyanJsonAddDoubleToObject(pJson, key, RyanJsonGetDoubleValue(pJson)))
  213. {
  214. fuzzTestWithMemFail(assert(RyanJsonCompareDouble(RyanJsonGetDoubleValue(RyanJsonGetObjectByKey(pJson, key)),
  215. RyanJsonGetDoubleValue(pJson))));
  216. }
  217. // 构造测试用 Double 数组
  218. double val = RyanJsonGetDoubleValue(pJson);
  219. double testDoubleArray[] = {val, val, val, val, val};
  220. RyanJsonBool_e jsonAddResult = RyanJsonAddItemToObject(
  221. pJson, (0 != size % 2) ? key : "arrayString",
  222. RyanJsonCreateDoubleArray(testDoubleArray, sizeof(testDoubleArray) / sizeof(testDoubleArray[0])));
  223. if (RyanJsonTrue == jsonAddResult)
  224. {
  225. fuzzTestWithMemFail({
  226. RyanJson_t itemIntArr = RyanJsonGetObjectByKey(pJson, key);
  227. assert(RyanJsonIsArray(itemIntArr));
  228. assert(RyanJsonGetArraySize(itemIntArr) == sizeof(testDoubleArray) / sizeof(testDoubleArray[0]));
  229. RyanJson_t item;
  230. RyanJsonArrayForEach(itemIntArr, item)
  231. {
  232. assert(RyanJsonCompareDouble(RyanJsonGetDoubleValue(item), val));
  233. }
  234. });
  235. }
  236. }
  237. }
  238. if (RyanJsonTrue == RyanJsonIsString(pJson) && RyanJsonFuzzerShouldFail(index))
  239. {
  240. if (RyanJsonTrue == RyanJsonAddStringToObject(pJson, key, RyanJsonGetStringValue(pJson)))
  241. {
  242. fuzzTestWithMemFail(assert(
  243. 0 == strcmp(RyanJsonGetStringValue(RyanJsonGetObjectByKey(pJson, key)), RyanJsonGetStringValue(pJson))));
  244. }
  245. // 构造测试用 String 数组
  246. const char *val = RyanJsonGetStringValue(pJson);
  247. const char *testStringArray[] = {val, val, val, val, val};
  248. RyanJsonBool_e jsonAddResult = RyanJsonAddItemToObject(
  249. pJson, (0 != size % 2) ? key : "arrayString",
  250. RyanJsonCreateStringArray(testStringArray, sizeof(testStringArray) / sizeof(testStringArray[0])));
  251. if (RyanJsonTrue == jsonAddResult)
  252. {
  253. fuzzTestWithMemFail({
  254. RyanJson_t itemIntArr = RyanJsonGetObjectByKey(pJson, key);
  255. assert(RyanJsonIsArray(itemIntArr));
  256. assert(RyanJsonGetArraySize(itemIntArr) == sizeof(testStringArray) / sizeof(testStringArray[0]));
  257. RyanJson_t item;
  258. RyanJsonArrayForEach(itemIntArr, item)
  259. {
  260. assert(0 == strcmp(RyanJsonGetStringValue(item), val));
  261. }
  262. });
  263. }
  264. }
  265. // 复合类型递归与插入测试
  266. if (RyanJsonTrue == RyanJsonIsArray(pJson) || RyanJsonTrue == RyanJsonIsObject(pJson))
  267. {
  268. RyanJson_t item;
  269. // 递归处理子节点
  270. RyanJsonObjectForEach(pJson, item)
  271. {
  272. RyanJsonFuzzerTestCreate(item, size);
  273. }
  274. // 添加随机生成的节点 (AddItem 方案A: 仅允许 Array/Object,成功后会消费原 item)
  275. uint32_t oldSize = RyanJsonGetSize(pJson);
  276. RyanJson_t newItem = RyanJsonFuzzerCreateRandomNode(pJson);
  277. RyanJson_t newItemDup = NULL;
  278. if (newItem && (RyanJsonIsArray(newItem) || RyanJsonIsObject(newItem))) { newItemDup = RyanJsonDuplicate(newItem); }
  279. RyanJsonBool_e jsonAddResult = RyanJsonAddItemToObject(pJson, key, newItem);
  280. if (RyanJsonTrue == jsonAddResult)
  281. {
  282. fuzzTestWithMemFail({
  283. assert(RyanJsonGetSize(pJson) == oldSize + 1);
  284. #if true == RyanJsonDefaultAddAtHead
  285. RyanJson_t itemJson = RyanJsonGetObjectByIndex(pJson, 0);
  286. #else
  287. RyanJson_t itemJson = RyanJsonGetObjectByIndex(pJson, oldSize);
  288. #endif
  289. assert(NULL != itemJson);
  290. assert(RyanJsonIsArray(itemJson) || RyanJsonIsObject(itemJson));
  291. if (RyanJsonTrue == RyanJsonIsObject(pJson))
  292. {
  293. assert(RyanJsonIsKey(itemJson));
  294. assert(0 == strcmp(RyanJsonGetKey(itemJson), key));
  295. }
  296. if (newItemDup) { assert(RyanJsonCompare(itemJson, newItemDup)); }
  297. });
  298. }
  299. if (newItemDup) { RyanJsonDelete(newItemDup); }
  300. if (RyanJsonTrue == RyanJsonIsArray(pJson))
  301. {
  302. if (RyanJsonFuzzerShouldFail(index / 8) && RyanJsonTrue == RyanJsonAddNullToArray(pJson))
  303. {
  304. fuzzTestWithMemFail({
  305. assert(RyanJsonIsArray(pJson));
  306. #if true == RyanJsonDefaultAddAtHead
  307. assert(RyanJsonIsNull(RyanJsonGetObjectByIndex(pJson, 0)));
  308. #else
  309. assert(RyanJsonIsNull(RyanJsonGetObjectByIndex(pJson, RyanJsonGetSize(pJson) - 1)));
  310. #endif
  311. });
  312. }
  313. if (RyanJsonFuzzerShouldFail(index / 8) &&
  314. RyanJsonTrue == RyanJsonAddBoolToArray(pJson, 0 != size % 2 ? RyanJsonTrue : RyanJsonFalse))
  315. {
  316. fuzzTestWithMemFail({
  317. assert(RyanJsonIsArray(pJson));
  318. #if true == RyanJsonDefaultAddAtHead
  319. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, 0);
  320. #else
  321. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, RyanJsonGetSize(pJson) - 1);
  322. #endif
  323. assert(RyanJsonIsBool(item));
  324. assert(RyanJsonGetBoolValue(item) == (0 != size % 2 ? RyanJsonTrue : RyanJsonFalse));
  325. });
  326. }
  327. if (RyanJsonFuzzerShouldFail(index / 8) && RyanJsonTrue == RyanJsonAddIntToArray(pJson, size))
  328. {
  329. fuzzTestWithMemFail({
  330. assert(RyanJsonIsArray(pJson));
  331. #if true == RyanJsonDefaultAddAtHead
  332. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, 0);
  333. #else
  334. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, RyanJsonGetSize(pJson) - 1);
  335. #endif
  336. assert(RyanJsonIsInt(item));
  337. assert(RyanJsonGetIntValue(item) == size);
  338. });
  339. }
  340. if (RyanJsonFuzzerShouldFail(index / 8) && RyanJsonTrue == RyanJsonAddDoubleToArray(pJson, size * 0.123456))
  341. {
  342. fuzzTestWithMemFail({
  343. assert(RyanJsonIsArray(pJson));
  344. #if true == RyanJsonDefaultAddAtHead
  345. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, 0);
  346. #else
  347. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, RyanJsonGetSize(pJson) - 1);
  348. #endif
  349. assert(RyanJsonIsDouble(item));
  350. assert(RyanJsonCompareDouble(RyanJsonGetDoubleValue(item), size * 0.123456));
  351. });
  352. }
  353. if (RyanJsonFuzzerShouldFail(index / 8) && RyanJsonTrue == RyanJsonAddStringToArray(pJson, "NULL"))
  354. {
  355. fuzzTestWithMemFail({
  356. assert(RyanJsonIsArray(pJson));
  357. #if true == RyanJsonDefaultAddAtHead
  358. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, 0);
  359. #else
  360. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, RyanJsonGetSize(pJson) - 1);
  361. #endif
  362. assert(RyanJsonIsString(item));
  363. assert(0 == strcmp(RyanJsonGetStringValue(item), "NULL"));
  364. });
  365. }
  366. if (RyanJsonFuzzerShouldFail(index / 8) && RyanJsonTrue == RyanJsonAddItemToArray(pJson, RyanJsonCreateArray()))
  367. {
  368. fuzzTestWithMemFail({
  369. assert(RyanJsonIsArray(pJson));
  370. #if true == RyanJsonDefaultAddAtHead
  371. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, 0);
  372. #else
  373. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, RyanJsonGetSize(pJson) - 1);
  374. #endif
  375. assert(RyanJsonIsArray(item));
  376. });
  377. }
  378. if (RyanJsonFuzzerShouldFail(index / 8) && RyanJsonTrue == RyanJsonAddItemToArray(pJson, RyanJsonCreateObject()))
  379. {
  380. fuzzTestWithMemFail({
  381. assert(RyanJsonIsArray(pJson));
  382. #if true == RyanJsonDefaultAddAtHead
  383. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, 0);
  384. #else
  385. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, RyanJsonGetSize(pJson) - 1);
  386. #endif
  387. assert(RyanJsonIsObject(item));
  388. });
  389. }
  390. if (RyanJsonFuzzerShouldFail(index / 8))
  391. {
  392. RyanJson_t randomNode = RyanJsonFuzzerCreateRandomNode(RyanJsonGetArrayValue(pJson));
  393. RyanJson_t randomNodeDup = NULL;
  394. if (randomNode && (RyanJsonIsArray(randomNode) || RyanJsonIsObject(randomNode)))
  395. {
  396. randomNodeDup = RyanJsonDuplicate(randomNode);
  397. }
  398. uint32_t oldLen = RyanJsonGetSize(pJson);
  399. if (RyanJsonTrue == RyanJsonAddItemToArray(pJson, randomNode))
  400. {
  401. fuzzTestWithMemFail({
  402. assert(RyanJsonIsArray(pJson));
  403. assert(RyanJsonGetSize(pJson) == oldLen + 1);
  404. #if true == RyanJsonDefaultAddAtHead
  405. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, 0);
  406. #else
  407. RyanJson_t item = RyanJsonGetObjectByIndex(pJson, oldLen);
  408. #endif
  409. assert(NULL != item);
  410. if (randomNodeDup) { assert(RyanJsonCompare(item, randomNodeDup)); }
  411. });
  412. }
  413. if (randomNodeDup) { RyanJsonDelete(randomNodeDup); }
  414. }
  415. // 获取当前大小,避免重复调用 RyanJsonGetSize(其复杂度为 O(N))
  416. // 在嵌入式场景下应尽量规避 O(N^2) 路径
  417. if (RyanJsonFuzzerShouldFail(index / 8))
  418. {
  419. uint32_t len = RyanJsonGetSize(pJson);
  420. uint32_t idx = len / 2;
  421. // 测试中间位置插入
  422. // 注意:每次插入后,数组长度增加,idx 相对位置其实在变动,
  423. // 这里为简化逻辑保持 index 不变,覆盖随机位置插入行为
  424. RyanJsonInsert(pJson, idx, RyanJsonCreateBool(key, 0 != size % 2 ? RyanJsonTrue : RyanJsonFalse));
  425. RyanJsonInsert(pJson, idx, RyanJsonCreateString(key, "NULL"));
  426. RyanJsonInsert(pJson, idx, RyanJsonCreateInt(key, 0));
  427. RyanJsonInsert(pJson, idx, RyanJsonCreateDouble(key, 0));
  428. RyanJsonInsert(pJson, idx, RyanJsonCreateArray());
  429. RyanJsonInsert(pJson, idx, RyanJsonCreateObject());
  430. // 测试头部插入
  431. RyanJsonInsert(pJson, 0, RyanJsonCreateBool(key, 0 != size % 2 ? RyanJsonTrue : RyanJsonFalse));
  432. RyanJsonInsert(pJson, 0, RyanJsonCreateString(key, "NULL"));
  433. RyanJsonInsert(pJson, 0, RyanJsonCreateInt(key, 0));
  434. RyanJsonInsert(pJson, 0, RyanJsonCreateDouble(key, 0));
  435. RyanJsonInsert(pJson, 0, RyanJsonCreateArray());
  436. RyanJsonInsert(pJson, 0, RyanJsonCreateObject());
  437. }
  438. }
  439. }
  440. return RyanJsonTrue;
  441. }