fuzzerMinify.c 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include "RyanJson.h"
  2. #include "RyanJsonFuzzer.h"
  3. /**
  4. * @brief 压缩测试
  5. *
  6. * 测试 RyanJson 的 Minify 功能(去除空白字符)。
  7. * 覆盖场景:
  8. * Minify 功能:将原始 Json 字符串压缩,验证是否能成功压缩。
  9. * 再次解析:解析压缩后的字符串,验证压缩未破坏 Json 结构。
  10. *
  11. * @param state Fuzzer 状态上下文
  12. * @param data 原始输入数据字符串
  13. * @param size 输入数据长度
  14. */
  15. RyanJsonBool_e RyanJsonFuzzerTestMinify(const char *data, uint32_t size)
  16. {
  17. // 一次性覆盖 textLen 无额外 '\0' 空间时的边界路径
  18. static RyanJsonBool_e minifyBoundaryCovered = RyanJsonFalse;
  19. if (RyanJsonFalse == minifyBoundaryCovered)
  20. {
  21. uint8_t rawBuf[8] = {'{', '\"', 'a', '\"', ':', '1', '}', '#'};
  22. assert(7 == RyanJsonMinify((char *)rawBuf, 7));
  23. assert('#' == rawBuf[7]);
  24. // 返回值小于 textLen 时,应写入 '\0'
  25. uint8_t rawBuf2[5] = {'a', ' ', 'b', 'c', '#'};
  26. assert(3 == RyanJsonMinify((char *)rawBuf2, 4));
  27. assert('a' == rawBuf2[0]);
  28. assert('b' == rawBuf2[1]);
  29. assert('c' == rawBuf2[2]);
  30. assert('\0' == rawBuf2[3]);
  31. assert('#' == rawBuf2[4]);
  32. assert(0 == RyanJsonMinify(NULL, 0));
  33. assert(0 == RyanJsonMinify(NULL, 10));
  34. assert(0 == RyanJsonMinify(NULL, -10));
  35. minifyBoundaryCovered = RyanJsonTrue;
  36. }
  37. // 准备缓冲区并拷贝数据
  38. // 分配比原始数据稍大的缓冲区,防止边界溢出
  39. char *buf = (char *)malloc(size + 100);
  40. if (!buf) { return RyanJsonFalse; }
  41. memcpy(buf, data, size);
  42. // 确保有足够的终止符与安全填充
  43. memset(buf + size, 0, 100);
  44. // 边界与异常参数测试
  45. // 测试负数长度输入
  46. assert(0 == RyanJsonMinify(buf, -10));
  47. // 执行 Minify
  48. // RyanJsonMinify 会原地修改缓冲区并移除空白字符
  49. uint32_t len = RyanJsonMinify(buf, (int32_t)size);
  50. assert(len > 0);
  51. assert(len <= size);
  52. // 验证 Minify 后数据有效性
  53. // 尝试解析压缩后的字符串,确认结构未被破坏
  54. // 注意:Minify 只是去空格,如果原串合法,Minify 后也应合法。
  55. // 这里使用可选尾部模式(不强制 Null Terminator,虽然已补终止符)
  56. RyanJson_t pJson = RyanJsonParseOptions(buf, len, size % 2 ? RyanJsonTrue : RyanJsonFalse, NULL);
  57. free(buf);
  58. if (NULL != pJson)
  59. {
  60. // 如果解析成功,尝试打印回来,确保对象结构完整
  61. uint32_t lenPrint = 0;
  62. char *jsonStr = RyanJsonPrint(pJson, 100, RyanJsonFalse, &lenPrint);
  63. RyanJsonCheckCode(NULL != jsonStr && lenPrint > 0, {
  64. RyanJsonDelete(pJson);
  65. return RyanJsonFalse;
  66. });
  67. RyanJsonFree(jsonStr);
  68. RyanJsonDelete(pJson);
  69. }
  70. else
  71. {
  72. // 如果输入本身非法,解析失败是预期行为
  73. return RyanJsonFalse;
  74. }
  75. return RyanJsonTrue;
  76. }