Mercurial > urweb
comparison src/c/urweb.c @ 801:5f49a6b759cb
Fix nasty bugs with longjmp() looping for uw_set_input(); and bad variable indexes for nested JavaScript in jscomp
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Thu, 14 May 2009 18:13:09 -0400 |
parents | d20d6afc1206 |
children | 395a5d450cc0 |
comparison
equal
deleted
inserted
replaced
800:e92cfac1608f | 801:5f49a6b759cb |
---|---|
480 ctx->headers = headers; | 480 ctx->headers = headers; |
481 } | 481 } |
482 | 482 |
483 int uw_db_begin(uw_context); | 483 int uw_db_begin(uw_context); |
484 | 484 |
485 static void uw_set_error(uw_context ctx, const char *fmt, ...) { | |
486 va_list ap; | |
487 va_start(ap, fmt); | |
488 | |
489 vsnprintf(ctx->error_message, ERROR_BUF_LEN, fmt, ap); | |
490 } | |
491 | |
485 __attribute__((noreturn)) void uw_error(uw_context ctx, failure_kind fk, const char *fmt, ...) { | 492 __attribute__((noreturn)) void uw_error(uw_context ctx, failure_kind fk, const char *fmt, ...) { |
486 cleanup *cl; | 493 cleanup *cl; |
487 | 494 |
488 va_list ap; | 495 va_list ap; |
489 va_start(ap, fmt); | 496 va_start(ap, fmt); |
656 ctx->subinputs[ctx->used_subinputs++].kind = UNUSED; | 663 ctx->subinputs[ctx->used_subinputs++].kind = UNUSED; |
657 | 664 |
658 return r; | 665 return r; |
659 } | 666 } |
660 | 667 |
661 void uw_set_input(uw_context ctx, const char *name, char *value) { | 668 int uw_set_input(uw_context ctx, const char *name, char *value) { |
662 if (!strcasecmp(name, ".b")) { | 669 if (!strcasecmp(name, ".b")) { |
663 int n = uw_input_num(value); | 670 int n = uw_input_num(value); |
664 input *inps; | 671 input *inps; |
665 | 672 |
666 if (n < 0) | 673 if (n < 0) { |
667 uw_error(ctx, FATAL, "Bad subform name %s", value); | 674 uw_set_error(ctx, "Bad subform name %s", value); |
668 | 675 return -1; |
669 if (n >= uw_inputs_len) | 676 } |
670 uw_error(ctx, FATAL, "For subform name %s, index %d is out of range", value, n); | 677 |
678 if (n >= uw_inputs_len) { | |
679 uw_set_error(ctx, "For subform name %s, index %d is out of range", value, n); | |
680 return -1; | |
681 } | |
671 | 682 |
672 inps = check_input_space(ctx, uw_inputs_len); | 683 inps = check_input_space(ctx, uw_inputs_len); |
673 | 684 |
674 INP(ctx)[n].kind = SUBFORM; | 685 INP(ctx)[n].kind = SUBFORM; |
675 INP(ctx)[n].data.subform.parent = ctx->cur_container; | 686 INP(ctx)[n].data.subform.parent = ctx->cur_container; |
676 INP(ctx)[n].data.subform.fields = inps; | 687 INP(ctx)[n].data.subform.fields = inps; |
677 ctx->cur_container = &INP(ctx)[n]; | 688 ctx->cur_container = &INP(ctx)[n]; |
678 } else if (!strcasecmp(name, ".e")) { | 689 } else if (!strcasecmp(name, ".e")) { |
679 input *tmp; | 690 input *tmp; |
680 | 691 |
681 if (ctx->cur_container == NULL) | 692 if (ctx->cur_container == NULL) { |
682 uw_error(ctx, FATAL, "Unmatched subform closer"); | 693 uw_set_error(ctx, "Unmatched subform closer"); |
694 return -1; | |
695 } | |
683 | 696 |
684 tmp = ctx->cur_container; | 697 tmp = ctx->cur_container; |
685 switch (tmp->kind) { | 698 switch (tmp->kind) { |
686 case SUBFORM: | 699 case SUBFORM: |
687 ctx->cur_container = tmp->data.subform.parent; | 700 ctx->cur_container = tmp->data.subform.parent; |
693 break; | 706 break; |
694 case ENTRY: | 707 case ENTRY: |
695 ctx->cur_container = tmp->data.entry.parent; | 708 ctx->cur_container = tmp->data.entry.parent; |
696 break; | 709 break; |
697 default: | 710 default: |
698 uw_error(ctx, FATAL, "uw_set_input: Wrong kind"); | 711 uw_set_error(ctx, "uw_set_input: Wrong kind"); |
712 return -1; | |
699 } | 713 } |
700 } else if (!strcasecmp(name, ".s")) { | 714 } else if (!strcasecmp(name, ".s")) { |
701 int n = uw_input_num(value); | 715 int n = uw_input_num(value); |
702 | 716 |
703 if (n < 0) | 717 if (n < 0) { |
704 uw_error(ctx, FATAL, "Bad subforms name %s", value); | 718 uw_set_error(ctx, "Bad subforms name %s", value); |
705 | 719 return -1; |
706 if (n >= uw_inputs_len) | 720 } |
707 uw_error(ctx, FATAL, "For subforms name %s, index %d is out of range", value, n); | 721 |
722 if (n >= uw_inputs_len) { | |
723 uw_set_error(ctx, "For subforms name %s, index %d is out of range", value, n); | |
724 return -1; | |
725 } | |
708 | 726 |
709 INP(ctx)[n].kind = SUBFORMS; | 727 INP(ctx)[n].kind = SUBFORMS; |
710 INP(ctx)[n].data.subforms.parent = ctx->cur_container; | 728 INP(ctx)[n].data.subforms.parent = ctx->cur_container; |
711 INP(ctx)[n].data.subforms.entries = NULL; | 729 INP(ctx)[n].data.subforms.entries = NULL; |
712 ctx->cur_container = &INP(ctx)[n]; | 730 ctx->cur_container = &INP(ctx)[n]; |
713 } else if (!strcasecmp(name, ".i")) { | 731 } else if (!strcasecmp(name, ".i")) { |
714 input *inps; | 732 input *inps; |
715 | 733 |
716 if (!ctx->cur_container) | 734 if (!ctx->cur_container) { |
717 uw_error(ctx, FATAL, "New entry without container"); | 735 uw_set_error(ctx, "New entry without container"); |
718 | 736 return -1; |
719 if (ctx->cur_container->kind != SUBFORMS) | 737 } |
720 uw_error(ctx, FATAL, "Bad kind for entry parent"); | 738 |
739 if (ctx->cur_container->kind != SUBFORMS) { | |
740 uw_set_error(ctx, "Bad kind for entry parent"); | |
741 return -1; | |
742 } | |
721 | 743 |
722 inps = check_input_space(ctx, uw_inputs_len + 1); | 744 inps = check_input_space(ctx, uw_inputs_len + 1); |
723 | 745 |
724 inps->kind = ENTRY; | 746 inps->kind = ENTRY; |
725 inps->data.entry.parent = ctx->cur_container; | 747 inps->data.entry.parent = ctx->cur_container; |
729 inps->data.entry.fields = inps+1; | 751 inps->data.entry.fields = inps+1; |
730 ctx->cur_container = inps; | 752 ctx->cur_container = inps; |
731 } else { | 753 } else { |
732 int n = uw_input_num(name); | 754 int n = uw_input_num(name); |
733 | 755 |
734 if (n < 0) | 756 if (n < 0) { |
735 uw_error(ctx, FATAL, "Bad input name %s", name); | 757 uw_set_error(ctx, "Bad input name %s", name); |
736 | 758 return -1; |
737 if (n >= uw_inputs_len) | 759 } |
738 uw_error(ctx, FATAL, "For input name %s, index %d is out of range", name, n); | 760 |
761 if (n >= uw_inputs_len) { | |
762 uw_set_error(ctx, "For input name %s, index %d is out of range", name, n); | |
763 return -1; | |
764 } | |
739 | 765 |
740 INP(ctx)[n].kind = NORMAL; | 766 INP(ctx)[n].kind = NORMAL; |
741 INP(ctx)[n].data.normal = value; | 767 INP(ctx)[n].data.normal = value; |
742 } | 768 } |
769 | |
770 return 0; | |
743 } | 771 } |
744 | 772 |
745 char *uw_get_input(uw_context ctx, int n) { | 773 char *uw_get_input(uw_context ctx, int n) { |
746 if (n < 0) | 774 if (n < 0) |
747 uw_error(ctx, FATAL, "Negative input index %d", n); | 775 uw_error(ctx, FATAL, "Negative input index %d", n); |
788 default: | 816 default: |
789 uw_error(ctx, FATAL, "Impossible input kind"); | 817 uw_error(ctx, FATAL, "Impossible input kind"); |
790 } | 818 } |
791 } | 819 } |
792 | 820 |
793 void uw_set_file_input(uw_context ctx, const char *name, uw_Basis_file f) { | 821 int uw_set_file_input(uw_context ctx, const char *name, uw_Basis_file f) { |
794 int n = uw_input_num(name); | 822 int n = uw_input_num(name); |
795 | 823 |
796 if (n < 0) | 824 if (n < 0) { |
797 uw_error(ctx, FATAL, "Bad file input name %s", name); | 825 uw_set_error(ctx, "Bad file input name %s", name); |
798 | 826 return -1; |
799 if (n >= uw_inputs_len) | 827 } |
800 uw_error(ctx, FATAL, "For file input name %s, index %d is out of range", name, n); | 828 |
829 if (n >= uw_inputs_len) { | |
830 uw_set_error(ctx, "For file input name %s, index %d is out of range", name, n); | |
831 return -1; | |
832 } | |
801 | 833 |
802 ctx->inputs[n].kind = FIL; | 834 ctx->inputs[n].kind = FIL; |
803 ctx->inputs[n].data.file = f; | 835 ctx->inputs[n].data.file = f; |
836 | |
837 return 0; | |
804 } | 838 } |
805 | 839 |
806 void *uw_malloc(uw_context ctx, size_t len); | 840 void *uw_malloc(uw_context ctx, size_t len); |
807 | 841 |
808 | 842 |