test_parsecommon.c (18100B)
1 /* Copyright (c) 2001-2004, Roger Dingledine. 2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 /* See LICENSE for licensing information */ 5 6 #include "core/or/or.h" 7 #include "test/test.h" 8 #include "lib/memarea/memarea.h" 9 #include "lib/encoding/binascii.h" 10 #include "feature/dirparse/parsecommon.h" 11 #include "test/log_test_helpers.h" 12 13 static void 14 test_parsecommon_tokenize_string_null(void *arg) 15 { 16 17 memarea_t *area = memarea_new(); 18 smartlist_t *tokens = smartlist_new(); 19 20 (void)arg; 21 22 const char *str_with_null = "a\0bccccccccc"; 23 24 int retval = 25 tokenize_string(area, str_with_null, 26 str_with_null + 3, 27 tokens, NULL, 0); 28 29 tt_int_op(retval, OP_EQ, -1); 30 31 done: 32 memarea_drop_all(area); 33 smartlist_free(tokens); 34 return; 35 } 36 37 static void 38 test_parsecommon_tokenize_string_multiple_lines(void *arg) 39 { 40 memarea_t *area = memarea_new(); 41 smartlist_t *tokens = smartlist_new(); 42 43 (void)arg; 44 45 token_rule_t table[] = { 46 T01("uptime", K_UPTIME, GE(1), NO_OBJ), 47 T01("hibernating", K_HIBERNATING, GE(1), NO_OBJ), 48 T1( "published", K_PUBLISHED, CONCAT_ARGS, NO_OBJ), 49 END_OF_TABLE, 50 }; 51 52 char *str = tor_strdup( 53 "hibernating 0\nuptime 1024\n" 54 "published 2018-10-15 10:00:00\n"); 55 56 int retval = 57 tokenize_string(area, str, NULL, 58 tokens, table, 0); 59 60 tt_int_op(smartlist_len(tokens), OP_EQ, 3); 61 directory_token_t *token = smartlist_get(tokens, 0); 62 63 tt_int_op(token->tp, OP_EQ, K_HIBERNATING); 64 65 token = smartlist_get(tokens, 1); 66 67 tt_int_op(token->tp, OP_EQ, K_UPTIME); 68 69 token = smartlist_get(tokens, 2); 70 71 tt_int_op(token->tp, OP_EQ, K_PUBLISHED); 72 73 tt_int_op(retval, OP_EQ, 0); 74 75 done: 76 tor_free(str); 77 memarea_drop_all(area); 78 smartlist_free(tokens); 79 return; 80 } 81 82 static void 83 test_parsecommon_tokenize_string_min_cnt(void *arg) 84 { 85 memarea_t *area = memarea_new(); 86 smartlist_t *tokens = smartlist_new(); 87 88 (void)arg; 89 90 token_rule_t table[] = { 91 T01("uptime", K_UPTIME, EQ(2), NO_OBJ), 92 T01("hibernating", K_HIBERNATING, GE(1), NO_OBJ), 93 END_OF_TABLE, 94 }; 95 96 // Missing "uptime" 97 char *str = tor_strdup("uptime 1024\nhibernating 0\n"); 98 99 int retval = 100 tokenize_string(area, str, NULL, 101 tokens, table, 0); 102 103 tt_int_op(retval, OP_EQ, -1); 104 105 done: 106 tor_free(str); 107 memarea_drop_all(area); 108 smartlist_free(tokens); 109 return; 110 } 111 112 static void 113 test_parsecommon_tokenize_string_max_cnt(void *arg) 114 { 115 memarea_t *area = memarea_new(); 116 smartlist_t *tokens = smartlist_new(); 117 118 (void)arg; 119 120 token_rule_t table[] = { 121 T01("uptime", K_UPTIME, EQ(1), NO_OBJ), 122 T01("hibernating", K_HIBERNATING, GE(1), NO_OBJ), 123 END_OF_TABLE, 124 }; 125 126 // "uptime" expected once, but occurs twice in input. 127 char *str = tor_strdup( 128 "uptime 1024\nuptime 2048\nhibernating 0\n"); 129 130 int retval = 131 tokenize_string(area, str, NULL, 132 tokens, table, 0); 133 134 tt_int_op(retval, OP_EQ, -1); 135 136 done: 137 tor_free(str); 138 memarea_drop_all(area); 139 smartlist_free(tokens); 140 return; 141 } 142 143 static void 144 test_parsecommon_tokenize_string_at_start(void *arg) 145 { 146 memarea_t *area = memarea_new(); 147 smartlist_t *tokens = smartlist_new(); 148 149 (void)arg; 150 151 token_rule_t table[] = { 152 T1_START("client-name", C_CLIENT_NAME, CONCAT_ARGS, NO_OBJ), 153 T01("uptime", K_UPTIME, EQ(1), NO_OBJ), 154 END_OF_TABLE, 155 }; 156 157 // "client-name" is not the first line. 158 char *str = tor_strdup( 159 "uptime 1024\nclient-name Alice\n"); 160 161 int retval = 162 tokenize_string(area, str, NULL, tokens, table, 0); 163 164 tt_int_op(retval, OP_EQ, -1); 165 166 done: 167 tor_free(str); 168 memarea_drop_all(area); 169 smartlist_free(tokens); 170 return; 171 } 172 173 static void 174 test_parsecommon_tokenize_string_at_end(void *arg) 175 { 176 memarea_t *area = memarea_new(); 177 smartlist_t *tokens = smartlist_new(); 178 179 (void)arg; 180 181 token_rule_t table[] = { 182 T1_END("client-name", C_CLIENT_NAME, CONCAT_ARGS, NO_OBJ), 183 T01("uptime", K_UPTIME, EQ(1), NO_OBJ), 184 END_OF_TABLE, 185 }; 186 187 // "client-name" is not the last line. 188 char *str = tor_strdup( 189 "client-name Alice\nuptime 1024\n"); 190 191 int retval = 192 tokenize_string(area, str, NULL, tokens, table, 0); 193 194 tt_int_op(retval, OP_EQ, -1); 195 196 done: 197 tor_free(str); 198 memarea_drop_all(area); 199 smartlist_free(tokens); 200 return; 201 } 202 203 static void 204 test_parsecommon_tokenize_string_no_annotations(void *arg) 205 { 206 memarea_t *area = memarea_new(); 207 smartlist_t *tokens = smartlist_new(); 208 209 (void)arg; 210 211 token_rule_t table[] = { 212 A01("@last-listed", A_LAST_LISTED, CONCAT_ARGS, NO_OBJ), 213 END_OF_TABLE, 214 }; 215 216 char *str = tor_strdup("@last-listed 2018-09-21 15:30:03\n"); 217 218 int retval = 219 tokenize_string(area, str, NULL, tokens, table, 0); 220 221 tt_int_op(retval, OP_EQ, -1); 222 223 done: 224 tor_free(str); 225 memarea_drop_all(area); 226 smartlist_free(tokens); 227 return; 228 } 229 230 static void 231 test_parsecommon_get_next_token_success(void *arg) 232 { 233 memarea_t *area = memarea_new(); 234 const char *str = "uptime 1024"; 235 const char *end = str + strlen(str); 236 const char **s = &str; 237 token_rule_t table = T01("uptime", K_UPTIME, GE(1), NO_OBJ); 238 (void)arg; 239 240 directory_token_t *token = get_next_token(area, s, end, &table); 241 242 tt_int_op(token->tp, OP_EQ, K_UPTIME); 243 tt_int_op(token->n_args, OP_EQ, 1); 244 tt_str_op(*(token->args), OP_EQ, "1024"); 245 tt_assert(!token->object_type); 246 tt_int_op(token->object_size, OP_EQ, 0); 247 tt_assert(!token->object_body); 248 249 tt_ptr_op(*s, OP_EQ, end); 250 251 done: 252 memarea_drop_all(area); 253 return; 254 } 255 256 static void 257 test_parsecommon_get_next_token_carriage_return(void *arg) 258 { 259 memarea_t *area = memarea_new(); 260 smartlist_t *tokens = smartlist_new(); 261 262 (void)arg; 263 264 token_rule_t table[] = { 265 T01("uptime", K_UPTIME, GE(1), NO_OBJ), 266 T01("hibernating", K_HIBERNATING, GE(1), NO_OBJ), 267 END_OF_TABLE, 268 }; 269 270 char *str = tor_strdup( 271 "hibernating 0\r\nuptime 1024\n" 272 "hibernating 0\ruptime 1024\n"); 273 274 int retval = 275 tokenize_string(area, str, NULL, 276 tokens, table, 0); 277 278 tt_int_op(smartlist_len(tokens), OP_EQ, 3); 279 directory_token_t *token = smartlist_get(tokens, 0); 280 281 tt_int_op(token->tp, OP_EQ, K_HIBERNATING); 282 283 token = smartlist_get(tokens, 1); 284 285 tt_int_op(token->tp, OP_EQ, K_UPTIME); 286 287 token = smartlist_get(tokens, 2); 288 289 tt_int_op(token->tp, OP_EQ, K_HIBERNATING); 290 291 tt_int_op(retval, OP_EQ, -1); 292 293 done: 294 tor_free(str); 295 memarea_drop_all(area); 296 smartlist_free(tokens); 297 return; 298 } 299 300 static void 301 test_parsecommon_get_next_token_concat_args(void *arg) 302 { 303 memarea_t *area = memarea_new(); 304 const char *str = "proto A=1 B=2"; 305 const char *end = str + strlen(str); 306 const char **s = &str; 307 token_rule_t rule = T01("proto", K_PROTO, CONCAT_ARGS, NO_OBJ); 308 (void)arg; 309 310 directory_token_t *token = get_next_token(area, s, end, &rule); 311 312 tt_int_op(token->tp, OP_EQ, K_PROTO); 313 tt_int_op(token->n_args, OP_EQ, 1); 314 tt_str_op(*(token->args), OP_EQ, "A=1 B=2"); 315 316 done: 317 memarea_drop_all(area); 318 } 319 320 static void 321 test_parsecommon_get_next_token_parse_keys(void *arg) 322 { 323 (void)arg; 324 325 memarea_t *area = memarea_new(); 326 const char *str = 327 "onion-key\n" 328 "-----BEGIN RSA PUBLIC KEY-----\n" 329 "MIGJAoGBAMDdIya33BfNlHOkzoTKSTT8EjD64waMfUr372syVHiFjHhObwKwGA5u\n" 330 "sHaMIe9r+Ij/4C1dKyuXkcz3DOl6gWNhTD7dZ89I+Okoh1jWe30jxCiAcywC22p5\n" 331 "XLhrDkX1A63Z7XCH9ltwU2WMqWsVM98N2GR6MTujP7wtqdLExYN1AgMBAAE=\n" 332 "-----END RSA PUBLIC KEY-----\n"; 333 334 const char *end = str + strlen(str); 335 const char **s = (const char **)&str; 336 directory_token_t *token = NULL; 337 directory_token_t *token2 = NULL; 338 339 token_rule_t rule = T1("onion-key", R_IPO_ONION_KEY, NO_ARGS, NEED_KEY_1024); 340 341 token = get_next_token(area, s, end, &rule); 342 tt_assert(token); 343 344 tt_int_op(token->tp, OP_EQ, R_IPO_ONION_KEY); 345 tt_int_op(token->n_args, OP_EQ, 0); 346 tt_str_op(token->object_type, OP_EQ, "RSA PUBLIC KEY"); 347 tt_int_op(token->object_size, OP_EQ, 140); 348 tt_assert(token->object_body); 349 tt_assert(token->key); 350 tt_assert(!token->error); 351 352 const char *str2 = 353 "client-key\n" 354 "-----BEGIN RSA PRIVATE KEY-----\n" 355 "MIICXAIBAAKBgQCwS810a2auH2PQchOBz9smNgjlDu31aq0IYlUohSYbhcv5AJ+d\n" 356 "DY0nfZWzS+mZPwzL3UiEnTt6PVv7AgoZ5V9ZJWJTKIURjJpkK0mstfJKHKIZhf84\n" 357 "pmFfRej9GQViB6NLtp1obOXJgJixSlMfw9doDI4NoAnEISCyH/tD77Qs2wIDAQAB\n" 358 "AoGAbDg8CKkdQOnX9c7xFpCnsE8fKqz9eddgHHNwXw1NFTwOt+2gDWKSMZmv2X5S\n" 359 "CVZg3owZxf5W0nT0D6Ny2+6nliak7foYAvkD0BsCiBhgftwC0zAo6k5rIbUKB3PJ\n" 360 "QLFXgpJhqWuXkODyt/hS/GTernR437WVSEGp1bnALqiFabECQQDaqHOxzoWY/nvH\n" 361 "KrfUi8EhqCnqERlRHwrW0MQZ1RPvF16OPPma+xa+ht/amfh3vYN5tZY82Zm43gGl\n" 362 "XWL5cZhNAkEAzmdSootYVnqLLLRMfHKXnO1XbaEcA/08MDNKGlSclBJixFenE8jX\n" 363 "iQsUbHwMJuGONvzWpRGPBP2f8xBd28ZtxwJARY+LZshtpfNniz/ixYJESaHG28je\n" 364 "xfjbKOW3TQSFV+2WTifFvHEeljQwKMoMyoMGvYRwLCGJjs9JtMLVxsdFjQJBAKwD\n" 365 "3BBvBQ39TuPQ1zWX4tb7zjMlY83HTFP3Sriq71tP/1QWoL2SUl56B2lp8E6vB/C3\n" 366 "wsMK4SCNprHRYAd7VZ0CQDKn6Zhd11P94PLs0msybFEh1VXr6CEW/BrxBgbL4ls6\n" 367 "dbX5XO0z4Ra8gYXgObgimhyMDYO98Idt5+Z3HIdyrSc=\n" 368 "-----END RSA PRIVATE KEY-----\n"; 369 370 const char *end2 = str2 + strlen(str2); 371 const char **s2 = (const char **)&str2; 372 373 token_rule_t rule2 = T01("client-key", C_CLIENT_KEY, NO_ARGS, OBJ_OK); 374 token2 = get_next_token(area, s2, end2, &rule2); 375 tt_assert(token2); 376 tt_int_op(token2->tp, OP_EQ, C_CLIENT_KEY); 377 tt_int_op(token2->n_args, OP_EQ, 0); 378 tt_str_op(token2->object_type, OP_EQ, "RSA PRIVATE KEY"); 379 tt_int_op(token2->object_size, OP_EQ, 608); 380 tt_assert(token2->object_body); 381 tt_assert(token2->key == NULL); 382 tt_assert(!token->error); 383 384 done: 385 if (token) token_clear(token); 386 if (token2) token_clear(token2); 387 memarea_drop_all(area); 388 } 389 390 static void 391 test_parsecommon_get_next_token_object(void *arg) 392 { 393 memarea_t *area = memarea_new(); 394 395 const char *str = 396 "directory-signature 0232AF901C31A04EE9848595AF9BB7620D4C5B2E " 397 "CD1FD971855430880D3C31E0331C5C55800C2F79\n" 398 "-----BEGIN SIGNATURE-----\n" 399 "dLTbc1Lad/OWKBJhA/dERzDHumswTAzBFAWAz2vnQhLsebs1SOm0W/vceEsiEkiF\n" 400 "A+JJSzIyfywJc6Mnk7aKMEIFjOO/MaxuAp4zv+q+JonJkF0ExjMqvKR0D6pSFmfN\n" 401 "cnemnxGHxNuPDnKl0imbWKmWDsHtwgi4zWeTq3MekfMOXKi6gIh+bDFzCs9/Vquh\n" 402 "uNKJI1jW/A2DEKeaSAODEv9VoCsYSvbVVEuHCBWjeNAurd5aL26BrAolW6m7pkD6\n" 403 "I+cQ8dQG6Wa/Zt6gLXtBbOP2o/iDI7ahDP9diNkBI/rm4nfp9j4piTwsqpi7xz9J\n" 404 "Ua9DEZB9KbJHVX1rGShrLA==\n" 405 "-----END SIGNATURE-----\n"; 406 407 const char *end = str + strlen(str); 408 const char **s = &str; 409 token_rule_t rule = T("directory-signature", K_DIRECTORY_SIGNATURE, 410 GE(2), NEED_OBJ); 411 (void)arg; 412 413 directory_token_t *token = get_next_token(area, s, end, &rule); 414 415 tt_int_op(token->tp, OP_EQ, K_DIRECTORY_SIGNATURE); 416 tt_int_op(token->n_args, OP_EQ, 2); 417 tt_str_op(token->args[0], OP_EQ, 418 "0232AF901C31A04EE9848595AF9BB7620D4C5B2E"); 419 tt_str_op(token->args[1], OP_EQ, 420 "CD1FD971855430880D3C31E0331C5C55800C2F79"); 421 422 tt_assert(!token->error); 423 424 char decoded[256]; 425 const char *signature = 426 "dLTbc1Lad/OWKBJhA/dERzDHumswTAzBFAWAz2vnQhLsebs1SOm0W/vceEsiEkiF\n" 427 "A+JJSzIyfywJc6Mnk7aKMEIFjOO/MaxuAp4zv+q+JonJkF0ExjMqvKR0D6pSFmfN\n" 428 "cnemnxGHxNuPDnKl0imbWKmWDsHtwgi4zWeTq3MekfMOXKi6gIh+bDFzCs9/Vquh\n" 429 "uNKJI1jW/A2DEKeaSAODEv9VoCsYSvbVVEuHCBWjeNAurd5aL26BrAolW6m7pkD6\n" 430 "I+cQ8dQG6Wa/Zt6gLXtBbOP2o/iDI7ahDP9diNkBI/rm4nfp9j4piTwsqpi7xz9J\n" 431 "Ua9DEZB9KbJHVX1rGShrLA==\n"; 432 tt_assert(signature); 433 size_t signature_len = strlen(signature); 434 base64_decode(decoded, sizeof(decoded), signature, signature_len); 435 436 tt_str_op(token->object_type, OP_EQ, "SIGNATURE"); 437 tt_int_op(token->object_size, OP_EQ, 256); 438 tt_mem_op(token->object_body, OP_EQ, decoded, 256); 439 440 tt_assert(!token->key); 441 442 done: 443 memarea_drop_all(area); 444 } 445 446 static void 447 test_parsecommon_get_next_token_err_too_many_args(void *arg) 448 { 449 memarea_t *area = memarea_new(); 450 const char *str = "uptime 1024 1024 1024"; 451 const char *end = str + strlen(str); 452 const char **s = &str; 453 token_rule_t table = T01("uptime", K_UPTIME, EQ(1), NO_OBJ); 454 (void)arg; 455 456 directory_token_t *token = get_next_token(area, s, end, &table); 457 458 tt_int_op(token->tp, OP_EQ, ERR_); 459 tt_str_op(token->error, OP_EQ, "Too many arguments to uptime"); 460 461 done: 462 memarea_drop_all(area); 463 return; 464 } 465 466 static void 467 test_parsecommon_get_next_token_err_too_few_args(void *arg) 468 { 469 memarea_t *area = memarea_new(); 470 const char *str = "uptime"; 471 const char *end = str + strlen(str); 472 const char **s = &str; 473 token_rule_t table = T01("uptime", K_UPTIME, EQ(1), NO_OBJ); 474 (void)arg; 475 476 directory_token_t *token = get_next_token(area, s, end, &table); 477 478 tt_int_op(token->tp, OP_EQ, ERR_); 479 tt_str_op(token->error, OP_EQ, "Too few arguments to uptime"); 480 481 done: 482 memarea_drop_all(area); 483 return; 484 } 485 486 static void 487 test_parsecommon_get_next_token_err_obj_missing_endline(void *arg) 488 { 489 memarea_t *area = memarea_new(); 490 491 const char *str = 492 "directory-signature 0232AF901C31A04EE9848595AF9BB7620D4C5B2E " 493 "CD1FD971855430880D3C31E0331C5C55800C2F79\n" 494 "-----BEGIN SIGNATURE-----\n" 495 "dLTbc1Lad/OWKBJhA/dERzDHumswTAzBFAWAz2vnQhLsebs1SOm0W/vceEsiEkiF\n" 496 "A+JJSzIyfywJc6Mnk7aKMEIFjOO/MaxuAp4zv+q+JonJkF0ExjMqvKR0D6pSFmfN\n" 497 "cnemnxGHxNuPDnKl0imbWKmWDsHtwgi4zWeTq3MekfMOXKi6gIh+bDFzCs9/Vquh\n" 498 "uNKJI1jW/A2DEKeaSAODEv9VoCsYSvbVVEuHCBWjeNAurd5aL26BrAolW6m7pkD6\n" 499 "I+cQ8dQG6Wa/Zt6gLXtBbOP2o/iDI7ahDP9diNkBI/rm4nfp9j4piTwsqpi7xz9J\n" 500 "Ua9DEZB9KbJHVX1rGShrLA==\n"; 501 502 const char *end = str + strlen(str); 503 const char **s = &str; 504 token_rule_t rule = T("directory-signature", K_DIRECTORY_SIGNATURE, 505 GE(2), NEED_OBJ); 506 (void)arg; 507 508 directory_token_t *token = get_next_token(area, s, end, &rule); 509 510 tt_int_op(token->tp, OP_EQ, ERR_); 511 tt_str_op(token->error, OP_EQ, "Malformed object: missing object end line"); 512 513 done: 514 memarea_drop_all(area); 515 return; 516 } 517 518 static void 519 test_parsecommon_get_next_token_err_bad_beginline(void *arg) 520 { 521 memarea_t *area = memarea_new(); 522 523 const char *str = 524 "directory-signature 0232AF901C31A04EE9848595AF9BB7620D4C5B2E " 525 "CD1FD971855430880D3C31E0331C5C55800C2F79\n" 526 "-----BEGIN SIGNATURE-Z---\n" 527 "dLTbc1Lad/OWKBJhA/dERzDHumswTAzBFAWAz2vnQhLsebs1SOm0W/vceEsiEkiF\n" 528 "A+JJSzIyfywJc6Mnk7aKMEIFjOO/MaxuAp4zv+q+JonJkF0ExjMqvKR0D6pSFmfN\n" 529 "cnemnxGHxNuPDnKl0imbWKmWDsHtwgi4zWeTq3MekfMOXKi6gIh+bDFzCs9/Vquh\n" 530 "uNKJI1jW/A2DEKeaSAODEv9VoCsYSvbVVEuHCBWjeNAurd5aL26BrAolW6m7pkD6\n" 531 "I+cQ8dQG6Wa/Zt6gLXtBbOP2o/iDI7ahDP9diNkBI/rm4nfp9j4piTwsqpi7xz9J\n" 532 "Ua9DEZB9KbJHVX1rGShrLA==\n" 533 "-----END SIGNATURE-----\n"; 534 535 const char *end = str + strlen(str); 536 const char **s = &str; 537 token_rule_t rule = T("directory-signature", K_DIRECTORY_SIGNATURE, 538 GE(2), NEED_OBJ); 539 (void)arg; 540 541 directory_token_t *token = get_next_token(area, s, end, &rule); 542 543 tt_int_op(token->tp, OP_EQ, ERR_); 544 tt_str_op(token->error, OP_EQ, "Malformed object: bad begin line"); 545 546 done: 547 memarea_drop_all(area); 548 return; 549 } 550 551 static void 552 test_parsecommon_get_next_token_err_tag_mismatch(void *arg) 553 { 554 memarea_t *area = memarea_new(); 555 556 const char *str = 557 "directory-signature 0232AF901C31A04EE9848595AF9BB7620D4C5B2E " 558 "CD1FD971855430880D3C31E0331C5C55800C2F79\n" 559 "-----BEGIN SIGNATURE-----\n" 560 "dLTbc1Lad/OWKBJhA/dERzDHumswTAzBFAWAz2vnQhLsebs1SOm0W/vceEsiEkiF\n" 561 "A+JJSzIyfywJc6Mnk7aKMEIFjOO/MaxuAp4zv+q+JonJkF0ExjMqvKR0D6pSFmfN\n" 562 "cnemnxGHxNuPDnKl0imbWKmWDsHtwgi4zWeTq3MekfMOXKi6gIh+bDFzCs9/Vquh\n" 563 "uNKJI1jW/A2DEKeaSAODEv9VoCsYSvbVVEuHCBWjeNAurd5aL26BrAolW6m7pkD6\n" 564 "I+cQ8dQG6Wa/Zt6gLXtBbOP2o/iDI7ahDP9diNkBI/rm4nfp9j4piTwsqpi7xz9J\n" 565 "Ua9DEZB9KbJHVX1rGShrLA==\n" 566 "-----END SOMETHINGELSE-----\n"; 567 568 const char *end = str + strlen(str); 569 const char **s = &str; 570 token_rule_t rule = T("directory-signature", K_DIRECTORY_SIGNATURE, 571 GE(2), NEED_OBJ); 572 (void)arg; 573 574 directory_token_t *token = get_next_token(area, s, end, &rule); 575 576 tt_int_op(token->tp, OP_EQ, ERR_); 577 tt_str_op(token->error, OP_EQ, 578 "Malformed object: mismatched end tag SIGNATURE"); 579 580 done: 581 memarea_drop_all(area); 582 return; 583 } 584 585 static void 586 test_parsecommon_get_next_token_err_bad_base64(void *arg) 587 { 588 memarea_t *area = memarea_new(); 589 590 const char *str = 591 "directory-signature 0232AF901C31A04EE9848595AF9BB7620D4C5B2E " 592 "CD1FD971855430880D3C31E0331C5C55800C2F79\n" 593 "-----BEGIN SIGNATURE-----\n" 594 "%%@%%%%%%%!!!'\n" 595 "-----END SIGNATURE-----\n"; 596 597 const char *end = str + strlen(str); 598 const char **s = &str; 599 token_rule_t rule = T("directory-signature", K_DIRECTORY_SIGNATURE, 600 GE(2), NEED_OBJ); 601 (void)arg; 602 603 directory_token_t *token = get_next_token(area, s, end, &rule); 604 605 tt_int_op(token->tp, OP_EQ, ERR_); 606 tt_str_op(token->error, OP_EQ, "Malformed object: bad base64-encoded data"); 607 608 done: 609 memarea_drop_all(area); 610 return; 611 } 612 613 #define PARSECOMMON_TEST(name) \ 614 { #name, test_parsecommon_ ## name, 0, NULL, NULL } 615 616 struct testcase_t parsecommon_tests[] = { 617 PARSECOMMON_TEST(tokenize_string_null), 618 PARSECOMMON_TEST(get_next_token_carriage_return), 619 PARSECOMMON_TEST(tokenize_string_multiple_lines), 620 PARSECOMMON_TEST(tokenize_string_min_cnt), 621 PARSECOMMON_TEST(tokenize_string_max_cnt), 622 PARSECOMMON_TEST(tokenize_string_at_start), 623 PARSECOMMON_TEST(tokenize_string_at_end), 624 PARSECOMMON_TEST(tokenize_string_no_annotations), 625 PARSECOMMON_TEST(get_next_token_success), 626 PARSECOMMON_TEST(get_next_token_concat_args), 627 PARSECOMMON_TEST(get_next_token_parse_keys), 628 PARSECOMMON_TEST(get_next_token_object), 629 PARSECOMMON_TEST(get_next_token_err_too_many_args), 630 PARSECOMMON_TEST(get_next_token_err_too_few_args), 631 PARSECOMMON_TEST(get_next_token_err_obj_missing_endline), 632 PARSECOMMON_TEST(get_next_token_err_bad_beginline), 633 PARSECOMMON_TEST(get_next_token_err_tag_mismatch), 634 PARSECOMMON_TEST(get_next_token_err_bad_base64), 635 END_OF_TESTCASES 636 };