hb-set-fuzzer.cc 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include "hb-fuzzer.hh"
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <assert.h>
  6. #include "hb.h"
  7. // Only allow ~5,000 set values between the two input sets.
  8. // Arbitrarily long input sets do not trigger any meaningful
  9. // differences in behaviour so there's no benefit from allowing
  10. // the fuzzer to create super large sets.
  11. #define MAX_INPUT_SIZE 20000
  12. enum set_operation_t : uint8_t
  13. {
  14. INTERSECT = 0,
  15. UNION = 1,
  16. SUBTRACT = 2,
  17. SYMMETRIC_DIFFERENCE = 3
  18. };
  19. struct instructions_t
  20. {
  21. set_operation_t operation;
  22. uint32_t first_set_size;
  23. };
  24. static hb_set_t *create_set (const uint32_t *value_array, int count)
  25. {
  26. hb_set_t *set = hb_set_create ();
  27. for (int i = 0; i < count; i++)
  28. hb_set_add (set, value_array[i]);
  29. return set;
  30. }
  31. extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
  32. {
  33. alloc_state = _fuzzing_alloc_state (data, size);
  34. if (size < sizeof (instructions_t))
  35. return 0;
  36. if (size > MAX_INPUT_SIZE)
  37. return 0;
  38. #pragma GCC diagnostic push
  39. #pragma GCC diagnostic ignored "-Wstrict-aliasing"
  40. const instructions_t &instructions = reinterpret_cast<const instructions_t &> (data);
  41. #pragma GCC diagnostic pop
  42. data += sizeof (instructions_t);
  43. size -= sizeof (instructions_t);
  44. const uint32_t *values = reinterpret_cast<const uint32_t *> (data);
  45. size = size / sizeof (uint32_t);
  46. if (size < instructions.first_set_size)
  47. return 0;
  48. hb_set_t *set_a = create_set (values, instructions.first_set_size);
  49. values += instructions.first_set_size;
  50. size -= instructions.first_set_size;
  51. hb_set_t *set_b = create_set (values, size);
  52. switch (instructions.operation)
  53. {
  54. case INTERSECT:
  55. hb_set_intersect (set_a, set_b);
  56. break;
  57. case UNION:
  58. hb_set_union (set_a, set_b);
  59. break;
  60. case SUBTRACT:
  61. hb_set_subtract (set_a, set_b);
  62. break;
  63. case SYMMETRIC_DIFFERENCE:
  64. hb_set_symmetric_difference (set_a, set_b);
  65. break;
  66. default:
  67. break;
  68. }
  69. hb_set_destroy (set_a);
  70. hb_set_destroy (set_b);
  71. return 0;
  72. }