fuzzerDetach.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #include "RyanJson.h"
  2. #include "RyanJsonFuzzer.h"
  3. /**
  4. * @brief 节点分离测试
  5. *
  6. * 测试 RyanJson 的节点分离功能(DetachByKey、DetachByIndex)。
  7. * 与 Delete 不同,Detach 不释放内存,而是将节点从树中摘除并返回。
  8. * 覆盖场景:
  9. * 异常分离:测试无效参数、越界索引等错误。
  10. * 递归分离:随机分离子节点,并立即释放分离出的节点以防止内存泄漏。
  11. *
  12. * @param state Fuzzer 状态上下文
  13. * @param pJson 当前正在操作的 Json 节点
  14. * @param size 输入数据大小
  15. */
  16. RyanJsonBool_e RyanJsonFuzzerTestDetach(RyanJson_t pJson, uint32_t size)
  17. {
  18. // 故障注入与异常参数测试
  19. if (RyanJsonFuzzerShouldFail(100))
  20. {
  21. // 错误的 DetachByKey 调用
  22. assert(RyanJsonFalse == RyanJsonDetachByKey(NULL, NULL));
  23. assert(RyanJsonFalse == RyanJsonDetachByKey(pJson, NULL));
  24. assert(RyanJsonFalse == RyanJsonDetachByKey(NULL, "NULL"));
  25. if (RyanJsonFalse == RyanJsonIsObject(pJson)) // 类型错误
  26. {
  27. assert(NULL == RyanJsonDetachByKey(pJson, "NULL"));
  28. }
  29. // 错误的 DetachByIndex 调用
  30. assert(NULL == RyanJsonDetachByIndex(NULL, 10));
  31. if (RyanJsonFalse == RyanJsonIsArray(pJson) && RyanJsonFalse == RyanJsonIsObject(pJson)) // 类型错误
  32. {
  33. assert(NULL == RyanJsonDetachByIndex(pJson, 0));
  34. }
  35. }
  36. // 仅处理容器类型(Object/Array)
  37. if (RyanJsonFalse == RyanJsonIsArray(pJson) && RyanJsonFalse == RyanJsonIsObject(pJson)) { return RyanJsonTrue; }
  38. // 递归遍历
  39. // 先递归处理子节点
  40. RyanJson_t item = NULL;
  41. RyanJson_t lastItem = NULL;
  42. RyanJsonObjectForEach(pJson, item)
  43. {
  44. RyanJsonFuzzerTestDetach(item, size);
  45. lastItem = item;
  46. }
  47. // 节点分离
  48. // 按 key 分离(仅 Object)
  49. if (RyanJsonTrue == RyanJsonIsObject(pJson))
  50. {
  51. // 尝试分离最后一个子节点
  52. if (NULL != lastItem && RyanJsonTrue == RyanJsonIsKey(lastItem))
  53. {
  54. RyanJson_t detachedItem = RyanJsonDetachByKey(pJson, RyanJsonGetKey(lastItem));
  55. // 重要:Detach 仅分离节点,不释放内存,必须手动 Delete 防止泄漏
  56. if (NULL != detachedItem) { RyanJsonDelete(detachedItem); }
  57. }
  58. }
  59. // 按 index 分离(Array/Object)
  60. {
  61. uint32_t idx = 0;
  62. uint32_t currentSize = RyanJsonGetSize(pJson);
  63. if (0 != currentSize)
  64. {
  65. idx = size % currentSize;
  66. RyanJson_t detachedItem = RyanJsonDetachByIndex(pJson, idx);
  67. if (NULL != detachedItem) { RyanJsonDelete(detachedItem); }
  68. }
  69. }
  70. return RyanJsonTrue;
  71. }