changeset 1451:b6ce8ef0ea88

Before allowing an indirect return, check (dynamically, for now) that we aren't in an RPC handler
author Adam Chlipala <adam@chlipala.net>
date Sun, 17 Apr 2011 13:43:00 -0400
parents d40104c112df
children aae3e3b6a408
files include/urweb.h src/c/urweb.c src/cjr_print.sml
diffstat 3 files changed, 16 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/include/urweb.h	Sun Apr 17 11:21:19 2011 -0400
+++ b/include/urweb.h	Sun Apr 17 13:43:00 2011 -0400
@@ -238,6 +238,7 @@
 int uw_hasPostBody(uw_context);
 uw_Basis_postBody uw_getPostBody(uw_context);
 
+void uw_mayReturnIndirectly(uw_context);
 __attribute__((noreturn)) void uw_return_blob(uw_context, uw_Basis_blob, uw_Basis_string mimeType);
 __attribute__((noreturn)) void uw_redirect(uw_context, uw_Basis_string url);
 
--- a/src/c/urweb.c	Sun Apr 17 11:21:19 2011 -0400
+++ b/src/c/urweb.c	Sun Apr 17 13:43:00 2011 -0400
@@ -414,7 +414,7 @@
   void *get_header_data;
 
   uw_buffer outHeaders, page, heap, script;
-  int returning_indirectly;
+  int allowed_to_return_indirectly, returning_indirectly;
   input *inputs, *subinputs, *cur_container;
   size_t sz_inputs, n_subinputs, used_subinputs;
 
@@ -477,7 +477,7 @@
   ctx->outHeaders.start[0] = 0;
   uw_buffer_init(uw_page_max, &ctx->page, 1);
   ctx->page.start[0] = 0;
-  ctx->returning_indirectly = 0;
+  ctx->allowed_to_return_indirectly = ctx->returning_indirectly = 0;
   uw_buffer_init(uw_heap_max, &ctx->heap, uw_min_heap);
   uw_buffer_init(uw_script_max, &ctx->script, 1);
   ctx->script.start[0] = 0;
@@ -591,7 +591,7 @@
   uw_buffer_reset(&ctx->script);
   ctx->script.start[0] = 0;
   uw_buffer_reset(&ctx->page);
-  ctx->returning_indirectly = 0;
+  ctx->allowed_to_return_indirectly = ctx->returning_indirectly = 0;
   uw_buffer_reset(&ctx->heap);
   ctx->regions = NULL;
   ctx->cleanup_front = ctx->cleanup;
@@ -3418,6 +3418,9 @@
   cleanup *cl;
   int len;
 
+  if (!ctx->allowed_to_return_indirectly)
+    uw_error(ctx, FATAL, "Tried to return a blob from an RPC");
+
   ctx->returning_indirectly = 1;
   uw_buffer_reset(&ctx->outHeaders);
   uw_buffer_reset(&ctx->page);
@@ -3445,6 +3448,9 @@
   cleanup *cl;
   char *s;
 
+  if (!ctx->allowed_to_return_indirectly)
+    uw_error(ctx, FATAL, "Tried to redirect from an RPC");
+
   ctx->returning_indirectly = 1;
   uw_buffer_reset(&ctx->page);
   ctx_uw_buffer_check(ctx, "page", &ctx->page, uw_buffer_used(&ctx->outHeaders)+1);
@@ -3792,3 +3798,7 @@
   } else
     uw_error(ctx, FATAL, "Tried to run nonexistent onError handler");
 }
+
+void uw_mayReturnIndirectly(uw_context ctx) {
+  ctx->allowed_to_return_indirectly = 1;
+}
--- a/src/cjr_print.sml	Sun Apr 17 11:21:19 2011 -0400
+++ b/src/cjr_print.sml	Sun Apr 17 13:43:00 2011 -0400
@@ -2651,6 +2651,8 @@
                                     newline,
                                     string "uw_write(ctx, begin_xhtml);",
                                     newline,
+                                    string "uw_mayReturnIndirectly(ctx);",
+                                    newline,
                                     string "uw_set_script_header(ctx, \"",
                                     let
                                         val scripts =