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