fuzzerDuplicate.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #include "RyanJson.h"
  2. #include "RyanJsonFuzzer.h"
  3. /**
  4. * @brief duplicate/compare 模块的一次性最小自检
  5. *
  6. * 这里只恢复运行期 harness 结构上不容易构造的比较拓扑:
  7. * 自比较、标量值不相等、Object 乱序匹配,以及嵌套 Object 缺少匹配 key 的失败路径。
  8. */
  9. void RyanJsonFuzzerSelfTestDuplicateCases(void)
  10. {
  11. {
  12. RyanJson_t selfObj = RyanJsonCreateObject();
  13. assert(NULL != selfObj);
  14. assert(RyanJsonTrue == RyanJsonAddIntToObject(selfObj, "k", 1));
  15. assert(RyanJsonTrue == RyanJsonCompare(selfObj, selfObj));
  16. assert(RyanJsonTrue == RyanJsonCompareOnlyKey(selfObj, selfObj));
  17. assert(RyanJsonFalse == RyanJsonCompare(NULL, selfObj));
  18. assert(RyanJsonFalse == RyanJsonCompare(selfObj, NULL));
  19. assert(RyanJsonFalse == RyanJsonCompare(NULL, NULL));
  20. assert(RyanJsonFalse == RyanJsonCompareOnlyKey(NULL, selfObj));
  21. assert(RyanJsonFalse == RyanJsonCompareOnlyKey(selfObj, NULL));
  22. assert(RyanJsonFalse == RyanJsonCompareOnlyKey(NULL, NULL));
  23. assert(NULL == RyanJsonDuplicate(NULL));
  24. assert(0 == RyanJsonGetSize(NULL));
  25. RyanJsonDelete(selfObj);
  26. }
  27. {
  28. RyanJson_t leftType = RyanJsonCreateInt(NULL, 1);
  29. RyanJson_t rightType = RyanJsonCreateString(NULL, "1");
  30. RyanJson_t leftBool = RyanJsonCreateBool(NULL, RyanJsonTrue);
  31. RyanJson_t rightBool = RyanJsonCreateBool(NULL, RyanJsonFalse);
  32. RyanJson_t leftInt = RyanJsonCreateInt(NULL, 11);
  33. RyanJson_t rightInt = RyanJsonCreateInt(NULL, 22);
  34. RyanJson_t leftDouble = RyanJsonCreateDouble(NULL, 1.25);
  35. RyanJson_t rightDouble = RyanJsonCreateDouble(NULL, 2.5);
  36. RyanJson_t leftString = RyanJsonCreateString(NULL, "left");
  37. RyanJson_t rightString = RyanJsonCreateString(NULL, "right");
  38. assert(NULL != leftType && NULL != rightType);
  39. assert(NULL != leftBool && NULL != rightBool);
  40. assert(NULL != leftInt && NULL != rightInt);
  41. assert(NULL != leftDouble && NULL != rightDouble);
  42. assert(NULL != leftString && NULL != rightString);
  43. assert(RyanJsonFalse == RyanJsonCompare(leftType, rightType));
  44. assert(RyanJsonFalse == RyanJsonCompare(leftBool, rightBool));
  45. assert(RyanJsonFalse == RyanJsonCompare(leftInt, rightInt));
  46. assert(RyanJsonFalse == RyanJsonCompare(leftDouble, rightDouble));
  47. assert(RyanJsonFalse == RyanJsonCompare(leftString, rightString));
  48. RyanJsonDelete(leftType);
  49. RyanJsonDelete(rightType);
  50. RyanJsonDelete(leftBool);
  51. RyanJsonDelete(rightBool);
  52. RyanJsonDelete(leftInt);
  53. RyanJsonDelete(rightInt);
  54. RyanJsonDelete(leftDouble);
  55. RyanJsonDelete(rightDouble);
  56. RyanJsonDelete(leftString);
  57. RyanJsonDelete(rightString);
  58. }
  59. {
  60. RyanJson_t objLeft = RyanJsonCreateObject();
  61. RyanJson_t objRightUnordered = RyanJsonCreateObject();
  62. assert(NULL != objLeft && NULL != objRightUnordered);
  63. assert(RyanJsonTrue == RyanJsonAddIntToObject(objLeft, "a", 1));
  64. assert(RyanJsonTrue == RyanJsonAddIntToObject(objLeft, "b", 2));
  65. assert(RyanJsonTrue == RyanJsonAddIntToObject(objLeft, "c", 3));
  66. assert(RyanJsonTrue == RyanJsonAddIntToObject(objRightUnordered, "b", 2));
  67. assert(RyanJsonTrue == RyanJsonAddIntToObject(objRightUnordered, "a", 1));
  68. assert(RyanJsonTrue == RyanJsonAddIntToObject(objRightUnordered, "c", 3));
  69. assert(RyanJsonTrue == RyanJsonCompare(objLeft, objRightUnordered));
  70. assert(RyanJsonTrue == RyanJsonCompareOnlyKey(objLeft, objRightUnordered));
  71. RyanJsonDelete(objLeft);
  72. RyanJsonDelete(objRightUnordered);
  73. }
  74. {
  75. RyanJson_t objNeedKey = RyanJsonCreateObject();
  76. RyanJson_t objMissKey = RyanJsonCreateObject();
  77. assert(NULL != objNeedKey && NULL != objMissKey);
  78. assert(RyanJsonTrue == RyanJsonAddIntToObject(objNeedKey, "a", 1));
  79. assert(RyanJsonTrue == RyanJsonAddIntToObject(objNeedKey, "b", 2));
  80. assert(RyanJsonTrue == RyanJsonAddIntToObject(objMissKey, "a", 1));
  81. assert(RyanJsonTrue == RyanJsonAddIntToObject(objMissKey, "c", 2));
  82. assert(RyanJsonFalse == RyanJsonCompare(objNeedKey, objMissKey));
  83. assert(RyanJsonFalse == RyanJsonCompareOnlyKey(objNeedKey, objMissKey));
  84. RyanJsonDelete(objNeedKey);
  85. RyanJsonDelete(objMissKey);
  86. }
  87. {
  88. RyanJson_t nestedNeedKey = RyanJsonCreateObject();
  89. RyanJson_t nestedMissKey = RyanJsonCreateObject();
  90. RyanJson_t needChild = RyanJsonCreateObject();
  91. RyanJson_t missChild = RyanJsonCreateObject();
  92. assert(NULL != nestedNeedKey && NULL != nestedMissKey);
  93. assert(NULL != needChild && NULL != missChild);
  94. assert(RyanJsonTrue == RyanJsonAddItemToObject(nestedNeedKey, "need", needChild));
  95. assert(RyanJsonTrue == RyanJsonAddItemToObject(nestedMissKey, "miss", missChild));
  96. assert(RyanJsonFalse == RyanJsonCompare(nestedNeedKey, nestedMissKey));
  97. assert(RyanJsonFalse == RyanJsonCompareOnlyKey(nestedNeedKey, nestedMissKey));
  98. RyanJsonDelete(nestedNeedKey);
  99. RyanJsonDelete(nestedMissKey);
  100. }
  101. }
  102. /**
  103. * @brief 复制与比较测试
  104. *
  105. * 测试深度复制与结构比较能力。
  106. * 覆盖场景:
  107. * 深度复制正确性:验证复制后的 Object 与原 Object 在结构和值上完全一致。
  108. * 独立性验证:验证修改复制后的 Object 不会影响原 Object。
  109. * 内存管理:验证复制过程中的内存分配与释放。
  110. *
  111. * @param state Fuzzer 状态上下文
  112. * @param pJson 需要复制的源 Json Object
  113. */
  114. RyanJsonBool_e RyanJsonFuzzerTestDuplicate(RyanJson_t pJson)
  115. {
  116. RyanJsonBool_e result = RyanJsonTrue;
  117. char *jsonStr = NULL;
  118. char *jsonStrDup = NULL;
  119. RyanJson_t pJsonDup = NULL;
  120. uint32_t len = 0;
  121. /* 使用非格式化输出,减少空白差异干扰 */
  122. jsonStr = RyanJsonPrint(pJson, 100, RyanJsonFalse, &len);
  123. RyanJsonCheckGotoExit(NULL != jsonStr);
  124. // 执行深度复制
  125. pJsonDup = RyanJsonDuplicate(pJson);
  126. RyanJsonCheckGotoExit(NULL != pJsonDup);
  127. // 结构完整性验证
  128. // 验证节点数量一致
  129. assert(RyanJsonGetSize(pJson) == RyanJsonGetSize(pJsonDup));
  130. // 执行结构比较
  131. // RyanJsonCompare:比较 key 与 value
  132. // RyanJsonCompareOnlyKey:仅比较 key(结构)
  133. RyanJsonCompare(pJson, pJsonDup);
  134. RyanJsonCompareOnlyKey(pJson, pJsonDup);
  135. // 序列化一致性验证
  136. uint32_t lenDup = 0;
  137. jsonStrDup = RyanJsonPrint(pJsonDup, 100, RyanJsonFalse, &lenDup);
  138. RyanJsonCheckGotoExit(NULL != jsonStrDup && lenDup > 0);
  139. // 验证序列化后的 String 内容完全一致
  140. RyanJsonCheckCode(len == lenDup && 0 == memcmp(jsonStr, jsonStrDup, (size_t)len), { RyanJsonCheckGotoExit(0); });
  141. // 独立性验证
  142. // 修改原 Object(如果可能)或修改副本,验证互不影响
  143. // 这里选择修改副本(pJsonDup),因为后续会销毁副本
  144. if (RyanJsonIsArray(pJson) || RyanJsonIsObject(pJson))
  145. {
  146. // 先执行删除操作
  147. RyanJsonDelete(RyanJsonDetachByIndex(pJsonDup, 0));
  148. if (RyanJsonGetSize(pJsonDup) > 1) { RyanJsonDelete(RyanJsonDetachByIndex(pJsonDup, 1)); }
  149. // 如果修改后仍是容器
  150. if (RyanJsonIsArray(pJsonDup) || RyanJsonIsObject(pJsonDup))
  151. {
  152. RyanJson_t item;
  153. // 修改 key(仅 Object 子节点存在 key 语义)
  154. if (RyanJsonIsObject(pJsonDup))
  155. {
  156. RyanJsonObjectForEach(pJsonDup, item)
  157. {
  158. if (RyanJsonIsKey(item))
  159. {
  160. RyanJsonChangeKey(item, "modify_key_test");
  161. break;
  162. }
  163. }
  164. }
  165. // 修改 Bool 值(Array/Object 都应遍历到)
  166. if (RyanJsonIsArray(pJsonDup))
  167. {
  168. RyanJsonArrayForEach(pJsonDup, item)
  169. {
  170. if (RyanJsonIsBool(item))
  171. {
  172. RyanJsonChangeBoolValue(item, !RyanJsonGetBoolValue(item));
  173. break;
  174. }
  175. }
  176. }
  177. else
  178. {
  179. RyanJsonObjectForEach(pJsonDup, item)
  180. {
  181. if (RyanJsonIsBool(item))
  182. {
  183. RyanJsonChangeBoolValue(item, !RyanJsonGetBoolValue(item));
  184. break;
  185. }
  186. }
  187. }
  188. // 再次修改 Object 节点中的 key
  189. if (RyanJsonIsObject(pJsonDup))
  190. {
  191. RyanJsonObjectForEach(pJsonDup, item)
  192. {
  193. if (RyanJsonIsKey(item) && RyanJsonIsObject(item))
  194. {
  195. RyanJsonChangeKey(item, "modify_obj_key_test");
  196. break;
  197. }
  198. }
  199. }
  200. }
  201. // 验证修改后的副本与原 Object 不再相等
  202. // 注意:如果原 Object 本来就是空的,或者修改没有实际生效(例如没找到对应类型的节点),这里可能会相等
  203. // 所以这里只调用比较函数增加覆盖率,不强制断言 False,因为逻辑极其复杂
  204. RyanJsonCompare(pJson, pJsonDup);
  205. RyanJsonCompareOnlyKey(pJson, pJsonDup);
  206. }
  207. exit__:
  208. if (jsonStr)
  209. {
  210. RyanJsonFree(jsonStr);
  211. jsonStr = NULL;
  212. }
  213. if (pJsonDup)
  214. {
  215. RyanJsonDelete(pJsonDup);
  216. pJsonDup = NULL;
  217. }
  218. if (jsonStrDup)
  219. {
  220. RyanJsonFree(jsonStrDup);
  221. jsonStrDup = NULL;
  222. }
  223. return result;
  224. }