aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/postprocessor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/postprocessor.c')
-rw-r--r--src/microhttpd/postprocessor.c96
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;