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