diff options
Diffstat (limited to 'src/microhttpd/postprocessor.c')
-rw-r--r-- | src/microhttpd/postprocessor.c | 96 |
1 files changed, 58 insertions, 38 deletions
diff --git a/src/microhttpd/postprocessor.c b/src/microhttpd/postprocessor.c index dc01b3f7..d0b018c7 100644 --- a/src/microhttpd/postprocessor.c +++ b/src/microhttpd/postprocessor.c | |||
@@ -48,6 +48,7 @@ enum PP_State | |||
48 | PP_NextBoundary, | 48 | PP_NextBoundary, |
49 | 49 | ||
50 | /* url encoding-states */ | 50 | /* url encoding-states */ |
51 | PP_ProcessKey, | ||
51 | PP_ProcessValue, | 52 | PP_ProcessValue, |
52 | PP_Callback, | 53 | PP_Callback, |
53 | 54 | ||
@@ -512,39 +513,57 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, | |||
512 | abort (); | 513 | abort (); |
513 | break; | 514 | break; |
514 | case PP_Init: | 515 | case PP_Init: |
516 | /* initial phase */ | ||
517 | mhd_assert (NULL == start_key); | ||
518 | mhd_assert (NULL == end_key); | ||
519 | mhd_assert (NULL == start_value); | ||
520 | mhd_assert (NULL == end_value); | ||
521 | switch (post_data[poff]) | ||
522 | { | ||
523 | case '=': | ||
524 | /* Case: (no key)'=' */ | ||
525 | /* Empty key with value */ | ||
526 | pp->state = PP_Error; | ||
527 | continue; | ||
528 | case '&': | ||
529 | /* Case: (no key)'&' */ | ||
530 | /* Empty key without value */ | ||
531 | poff++; | ||
532 | continue; | ||
533 | case '\n': | ||
534 | case '\r': | ||
535 | /* Case: (no key)'\n' or (no key)'\r' */ | ||
536 | pp->state = PP_Done; | ||
537 | poff++; | ||
538 | break; | ||
539 | default: | ||
540 | /* normal character, key start, advance! */ | ||
541 | pp->state = PP_ProcessKey; | ||
542 | start_key = &post_data[poff]; | ||
543 | pp->must_ikvi = true; | ||
544 | poff++; | ||
545 | continue; | ||
546 | } | ||
547 | break; /* end PP_Init */ | ||
548 | case PP_ProcessKey: | ||
515 | /* key phase */ | 549 | /* key phase */ |
550 | mhd_assert (NULL == start_value); | ||
551 | mhd_assert (NULL == end_value); | ||
552 | mhd_assert (NULL != start_key || 0 == poff); | ||
553 | mhd_assert (0 != poff || NULL == start_key); | ||
554 | mhd_assert (NULL == end_key); | ||
516 | switch (post_data[poff]) | 555 | switch (post_data[poff]) |
517 | { | 556 | { |
518 | case '=': | 557 | case '=': |
519 | /* Case: 'key=' */ | 558 | /* Case: 'key=' */ |
520 | if (NULL == start_key) | 559 | if (0 != poff) |
521 | { | ||
522 | if (0 == pp->buffer_pos) | ||
523 | { | ||
524 | /* Empty key with value */ | ||
525 | pp->state = PP_Error; | ||
526 | continue; | ||
527 | } | ||
528 | } | ||
529 | else | ||
530 | end_key = &post_data[poff]; | 560 | end_key = &post_data[poff]; |
531 | poff++; | 561 | poff++; |
532 | pp->state = PP_ProcessValue; | 562 | pp->state = PP_ProcessValue; |
533 | break; | 563 | break; |
534 | case '&': | 564 | case '&': |
535 | /* Case: 'key&' */ | 565 | /* Case: 'key&' */ |
536 | mhd_assert (NULL == start_value); | 566 | if (0 != poff) |
537 | mhd_assert (NULL == end_value); | ||
538 | if (NULL == start_key) | ||
539 | { | ||
540 | if (0 == pp->buffer_pos) | ||
541 | { | ||
542 | /* Empty key without value */ | ||
543 | poff++; | ||
544 | continue; | ||
545 | } | ||
546 | } | ||
547 | else | ||
548 | end_key = &post_data[poff]; | 567 | end_key = &post_data[poff]; |
549 | poff++; | 568 | poff++; |
550 | pp->state = PP_Callback; | 569 | pp->state = PP_Callback; |
@@ -552,25 +571,20 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, | |||
552 | case '\n': | 571 | case '\n': |
553 | case '\r': | 572 | case '\r': |
554 | /* Case: 'key\n' or 'key\r' */ | 573 | /* Case: 'key\n' or 'key\r' */ |
555 | if (NULL != start_key) | 574 | if (0 != poff) |
556 | end_key = &post_data[poff]; | 575 | end_key = &post_data[poff]; |
557 | poff++; | 576 | /* No advance here, 'PP_Done' will be selected by next 'PP_Init' phase */ |
558 | if (pp->must_ikvi) | 577 | pp->state = PP_Callback; |
559 | pp->state = PP_Callback; | ||
560 | else | ||
561 | pp->state = PP_Done; | ||
562 | break; | 578 | break; |
563 | default: | 579 | default: |
564 | /* normal character, advance! */ | 580 | /* normal character, advance! */ |
565 | if (NULL == start_key) | 581 | if (0 == poff) |
566 | { | 582 | start_key = post_data; |
567 | start_key = &post_data[poff]; | ||
568 | pp->must_ikvi = true; | ||
569 | } | ||
570 | poff++; | 583 | poff++; |
571 | continue; | 584 | break; |
572 | } | 585 | } |
573 | break; /* end PP_Init */ | 586 | mhd_assert (NULL == end_key || NULL != start_key); |
587 | break; /* end PP_ProcessKey */ | ||
574 | case PP_ProcessValue: | 588 | case PP_ProcessValue: |
575 | if (NULL == start_value) | 589 | if (NULL == start_value) |
576 | start_value = &post_data[poff]; | 590 | start_value = &post_data[poff]; |
@@ -602,12 +616,14 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, | |||
602 | case '\r': | 616 | case '\r': |
603 | /* Case: 'value\n' or 'value\r' */ | 617 | /* Case: 'value\n' or 'value\r' */ |
604 | end_value = &post_data[poff]; | 618 | end_value = &post_data[poff]; |
605 | poff++; | ||
606 | if (pp->must_ikvi || | 619 | if (pp->must_ikvi || |
607 | (start_value != end_value) ) | 620 | (start_value != end_value) ) |
608 | pp->state = PP_Callback; | 621 | pp->state = PP_Callback; /* No poff advance here to set PP_Done in the next iteration */ |
609 | else | 622 | else |
623 | { | ||
624 | poff++; | ||
610 | pp->state = PP_Done; | 625 | pp->state = PP_Done; |
626 | } | ||
611 | break; | 627 | break; |
612 | case '%': | 628 | case '%': |
613 | last_escape = &post_data[poff]; | 629 | last_escape = &post_data[poff]; |
@@ -668,6 +684,10 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, | |||
668 | pp->must_unescape_key = true; | 684 | pp->must_unescape_key = true; |
669 | } | 685 | } |
670 | } | 686 | } |
687 | #ifdef _DEBUG | ||
688 | else | ||
689 | mhd_assert (0 != pp->buffer_pos); | ||
690 | #endif /* _DEBUG */ | ||
671 | if (pp->must_unescape_key) | 691 | if (pp->must_unescape_key) |
672 | { | 692 | { |
673 | kbuf[pp->buffer_pos] = '\0'; /* 0-terminate key */ | 693 | kbuf[pp->buffer_pos] = '\0'; /* 0-terminate key */ |
@@ -709,7 +729,7 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, | |||
709 | if (NULL != start_key) | 729 | if (NULL != start_key) |
710 | { | 730 | { |
711 | size_t key_len; | 731 | size_t key_len; |
712 | mhd_assert ((PP_Init == pp->state) || (NULL != end_key)); | 732 | mhd_assert ((PP_ProcessKey == pp->state) || (NULL != end_key)); |
713 | if (NULL == end_key) | 733 | if (NULL == end_key) |
714 | end_key = &post_data[poff]; | 734 | end_key = &post_data[poff]; |
715 | key_len = end_key - start_key; | 735 | key_len = end_key - start_key; |