diff 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
line wrap: on
line diff
--- a/src/c/urweb.c	Thu May 14 13:18:31 2009 -0400
+++ b/src/c/urweb.c	Thu May 14 18:13:09 2009 -0400
@@ -482,6 +482,13 @@
 
 int uw_db_begin(uw_context);
 
+static void uw_set_error(uw_context ctx, const char *fmt, ...) {
+  va_list ap;
+  va_start(ap, fmt);
+
+  vsnprintf(ctx->error_message, ERROR_BUF_LEN, fmt, ap);
+}
+
 __attribute__((noreturn)) void uw_error(uw_context ctx, failure_kind fk, const char *fmt, ...) {
   cleanup *cl;
 
@@ -658,16 +665,20 @@
   return r;
 }
 
-void uw_set_input(uw_context ctx, const char *name, char *value) {
+int uw_set_input(uw_context ctx, const char *name, char *value) {
   if (!strcasecmp(name, ".b")) {
     int n = uw_input_num(value);
     input *inps;
 
-    if (n < 0)
-      uw_error(ctx, FATAL, "Bad subform name %s", value);
-
-    if (n >= uw_inputs_len)
-      uw_error(ctx, FATAL, "For subform name %s, index %d is out of range", value, n);
+    if (n < 0) {
+      uw_set_error(ctx, "Bad subform name %s", value);
+      return -1;
+    }
+
+    if (n >= uw_inputs_len) {
+      uw_set_error(ctx, "For subform name %s, index %d is out of range", value, n);
+      return -1;
+    }
 
     inps = check_input_space(ctx, uw_inputs_len);
 
@@ -678,8 +689,10 @@
   } else if (!strcasecmp(name, ".e")) {
     input *tmp;
 
-    if (ctx->cur_container == NULL)
-      uw_error(ctx, FATAL, "Unmatched subform closer");
+    if (ctx->cur_container == NULL) {
+      uw_set_error(ctx, "Unmatched subform closer");
+      return -1;
+    }
 
     tmp = ctx->cur_container;
     switch (tmp->kind) {
@@ -695,16 +708,21 @@
       ctx->cur_container = tmp->data.entry.parent;
       break;
     default:
-      uw_error(ctx, FATAL, "uw_set_input: Wrong kind");
+      uw_set_error(ctx, "uw_set_input: Wrong kind");
+      return -1;
     }
   } else if (!strcasecmp(name, ".s")) {
     int n = uw_input_num(value);
 
-    if (n < 0)
-      uw_error(ctx, FATAL, "Bad subforms name %s", value);
-
-    if (n >= uw_inputs_len)
-      uw_error(ctx, FATAL, "For subforms name %s, index %d is out of range", value, n);
+    if (n < 0) {
+      uw_set_error(ctx, "Bad subforms name %s", value);
+      return -1;
+    }
+
+    if (n >= uw_inputs_len) {
+      uw_set_error(ctx, "For subforms name %s, index %d is out of range", value, n);
+      return -1;
+    }
 
     INP(ctx)[n].kind = SUBFORMS;
     INP(ctx)[n].data.subforms.parent = ctx->cur_container;
@@ -713,11 +731,15 @@
   } else if (!strcasecmp(name, ".i")) {
     input *inps;
 
-    if (!ctx->cur_container)
-      uw_error(ctx, FATAL, "New entry without container");
-
-    if (ctx->cur_container->kind != SUBFORMS)
-      uw_error(ctx, FATAL, "Bad kind for entry parent");
+    if (!ctx->cur_container) {
+      uw_set_error(ctx, "New entry without container");
+      return -1;
+    }
+
+    if (ctx->cur_container->kind != SUBFORMS) {
+      uw_set_error(ctx, "Bad kind for entry parent");
+      return -1;
+    }
 
     inps = check_input_space(ctx, uw_inputs_len + 1);
 
@@ -731,15 +753,21 @@
   } else {
     int n = uw_input_num(name);
 
-    if (n < 0)
-      uw_error(ctx, FATAL, "Bad input name %s", name);
-
-    if (n >= uw_inputs_len)
-      uw_error(ctx, FATAL, "For input name %s, index %d is out of range", name, n);
+    if (n < 0) {
+      uw_set_error(ctx, "Bad input name %s", name);
+      return -1;
+    }
+
+    if (n >= uw_inputs_len) {
+      uw_set_error(ctx, "For input name %s, index %d is out of range", name, n);
+      return -1;
+    }
 
     INP(ctx)[n].kind = NORMAL;
     INP(ctx)[n].data.normal = value;
   }
+
+  return 0;
 }
 
 char *uw_get_input(uw_context ctx, int n) {
@@ -790,17 +818,23 @@
   }
 }
 
-void uw_set_file_input(uw_context ctx, const char *name, uw_Basis_file f) {
+int uw_set_file_input(uw_context ctx, const char *name, uw_Basis_file f) {
   int n = uw_input_num(name);
 
-  if (n < 0)
-    uw_error(ctx, FATAL, "Bad file input name %s", name);
-
-  if (n >= uw_inputs_len)
-    uw_error(ctx, FATAL, "For file input name %s, index %d is out of range", name, n);
+  if (n < 0) {
+    uw_set_error(ctx, "Bad file input name %s", name);
+    return -1;
+  }
+
+  if (n >= uw_inputs_len) {
+    uw_set_error(ctx, "For file input name %s, index %d is out of range", name, n);
+    return -1;
+  }
 
   ctx->inputs[n].kind = FIL;
   ctx->inputs[n].data.file = f;
+
+  return 0;
 }
 
 void *uw_malloc(uw_context ctx, size_t len);