test-blobmsg_check_array.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #include <stdio.h>
  2. #include "blobmsg.h"
  3. /*
  4. * This test tests a blob of this form...
  5. *
  6. {
  7. "array_a" : [
  8. {
  9. "array_b": [
  10. "1"
  11. ]
  12. }
  13. ]
  14. }
  15. *
  16. */
  17. enum {
  18. ARRAY_A = 0,
  19. ARRAY_B = 0,
  20. };
  21. static char const array_a[] = "array_a";
  22. static char const array_b[] = "array_b";
  23. static const struct blobmsg_policy pol_a[] = {
  24. [ARRAY_A] = {
  25. .name = array_a,
  26. .type = BLOBMSG_TYPE_ARRAY
  27. }
  28. };
  29. static const struct blobmsg_policy pol_b[] = {
  30. [ARRAY_B] = {
  31. .name = array_b,
  32. .type = BLOBMSG_TYPE_ARRAY
  33. }
  34. };
  35. #ifndef ARRAY_SIZE
  36. #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
  37. #endif
  38. static int
  39. check_table_a_entries(struct blob_attr *attr)
  40. {
  41. struct blob_attr *cur;
  42. size_t rem;
  43. int entry_number = 0;
  44. blobmsg_for_each_attr(cur, attr, rem) {
  45. int failed = 0;
  46. fprintf(stderr, "Process %s: entry %d\n", array_a, entry_number);
  47. struct blob_attr *tb[ARRAY_SIZE(pol_b)];
  48. if (blobmsg_parse(pol_b, ARRAY_SIZE(pol_b), tb,
  49. blobmsg_data(cur), blobmsg_data_len(cur)) != 0) {
  50. fprintf(stderr, "Policy %s parse failed\n", array_b);
  51. return -1;
  52. }
  53. if (tb[ARRAY_B] == NULL) {
  54. fprintf(stderr, "%s not found\n", array_b);
  55. return -1;
  56. }
  57. /*
  58. * This is the test that fails when blobmsg_check_array() passes the
  59. * length obtained by blob_len(attr).
  60. * It succeeds when blobmsg_check_array() uses blob_len(attr), which is
  61. * equivalent to the origianl code, pre the length check changes.
  62. */
  63. if (blobmsg_check_array(tb[ARRAY_B], BLOBMSG_TYPE_STRING) < 0) {
  64. fprintf(stderr, "Failed blobmsg_check_array() (STRING) on %s\n",
  65. array_b);
  66. failed = 1;
  67. }
  68. /*
  69. * Continue outputting the strings even though the test above might
  70. * have failed.
  71. * This will show that the array does actually contain the expected
  72. * string.
  73. */
  74. struct blob_attr *cur2;
  75. size_t rem2;
  76. blobmsg_for_each_attr(cur2, tb[ARRAY_B], rem2) {
  77. fprintf(stderr, "%s contains string: %s\n",
  78. array_b, blobmsg_get_string(cur2));
  79. }
  80. entry_number++;
  81. if (failed)
  82. return -1;
  83. }
  84. return 0;
  85. }
  86. static int
  87. check_message(struct blob_buf *buf)
  88. {
  89. struct blob_attr *tb[ARRAY_SIZE(pol_a)];
  90. if (blobmsg_parse(pol_a, ARRAY_SIZE(pol_a), tb,
  91. blob_data(buf->head), blobmsg_data_len(buf->head)) != 0) {
  92. fprintf(stderr, "Policy %s parse failed\n", array_a);
  93. return -1;
  94. }
  95. if (tb[ARRAY_A] == NULL) {
  96. fprintf(stderr, "%s not found\n", array_a);
  97. return -1;
  98. }
  99. int const result = blobmsg_check_array(tb[ARRAY_A], BLOBMSG_TYPE_TABLE);
  100. if (result < 0) {
  101. fprintf(stderr, "Failed blobmsg_check_array() (TABLE) on %s (%d)\n",
  102. array_a, result);
  103. return -1;
  104. }
  105. return check_table_a_entries(tb[ARRAY_A]);
  106. }
  107. static void
  108. fill_message(struct blob_buf * const buf)
  109. {
  110. void * const tbl_a = blobmsg_open_array(buf, "array_a");
  111. void * const obj = blobmsg_open_table(buf, NULL);
  112. void * const tbl_b = blobmsg_open_array(buf, "array_b");
  113. blobmsg_add_string(buf, NULL, "1");
  114. blobmsg_close_array(buf, tbl_b);
  115. blobmsg_close_table(buf, obj);
  116. blobmsg_close_array(buf, tbl_a);
  117. }
  118. int main(int argc, char **argv)
  119. {
  120. int result;
  121. static struct blob_buf buf;
  122. blobmsg_buf_init(&buf);
  123. fill_message(&buf);
  124. result = check_message(&buf);
  125. if (result == 0)
  126. fprintf(stderr, "blobmsg_check_array() test passed\n");
  127. if (buf.buf != NULL)
  128. free(buf.buf);
  129. return result ? EXIT_FAILURE : EXIT_SUCCESS;
  130. }