changeset 1942:a671e5258a2c

Raise exception when recv()ing from someone else's channel; improve setting of client ID in RPCs
author Adam Chlipala <adam@chlipala.net>
date Fri, 27 Dec 2013 12:10:03 -0500
parents 9f3597979e98
children 3ecd0b6360eb
files lib/js/urweb.js src/c/urweb.c tests/channelThief.ur tests/channelThief.urp tests/channelThief.urs
diffstat 5 files changed, 64 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/lib/js/urweb.js	Wed Dec 25 13:11:43 2013 -0500
+++ b/lib/js/urweb.js	Fri Dec 27 12:10:03 2013 -0500
@@ -1575,7 +1575,7 @@
         er("May not 'recv' in main thread of 'code' for <active>");
 
     if (chn == null)
-        return;
+        er("Client-side code tried to recv() from a channel belonging to a different page view.");
 
     if (chn < 0)
         whine("Out-of-bounds channel receive");
--- a/src/c/urweb.c	Wed Dec 25 13:11:43 2013 -0500
+++ b/src/c/urweb.c	Fri Dec 27 12:10:03 2013 -0500
@@ -734,36 +734,34 @@
 char *uw_Basis_htmlifyString(uw_context, const char *);
 
 void uw_login(uw_context ctx) {
-  if (ctx->needs_push) {
-    char *id_s, *pass_s;
-
-    if ((id_s = uw_Basis_requestHeader(ctx, "UrWeb-Client"))
-        && (pass_s = uw_Basis_requestHeader(ctx, "UrWeb-Pass"))) {
-      unsigned id = atoi(id_s);
-      int pass = atoi(pass_s);
-      client *c = find_client(id);
-
-      if (c == NULL)
-        uw_error(ctx, FATAL, "Unknown client ID in HTTP headers (%s, %s)", uw_Basis_htmlifyString(ctx, id_s), uw_Basis_htmlifyString(ctx, pass_s));
-      else {
-        use_client(c);
-        ctx->client = c;
-
-        if (c->mode != USED)
-          uw_error(ctx, FATAL, "Stale client ID (%u) in subscription request", id);
-        if (c->pass != pass)
-          uw_error(ctx, FATAL, "Wrong client password (%u, %d) in subscription request", id, pass);
-      }
-    } else {
-      client *c = new_client();
-
-      if (c == NULL)
-        uw_error(ctx, FATAL, "Limit exceeded on number of message-passing clients");
-
+  char *id_s, *pass_s;
+
+  if ((id_s = uw_Basis_requestHeader(ctx, "UrWeb-Client"))
+      && (pass_s = uw_Basis_requestHeader(ctx, "UrWeb-Pass"))) {
+    unsigned id = atoi(id_s);
+    int pass = atoi(pass_s);
+    client *c = find_client(id);
+
+    if (c == NULL)
+      uw_error(ctx, FATAL, "Unknown client ID in HTTP headers (%s, %s)", uw_Basis_htmlifyString(ctx, id_s), uw_Basis_htmlifyString(ctx, pass_s));
+    else {
       use_client(c);
-      uw_copy_client_data(c->data, ctx->client_data);
       ctx->client = c;
+
+      if (c->mode != USED)
+        uw_error(ctx, FATAL, "Stale client ID (%u) in subscription request", id);
+      if (c->pass != pass)
+        uw_error(ctx, FATAL, "Wrong client password (%u, %d) in subscription request", id, pass);
     }
+  } else if (ctx->needs_push) {
+    client *c = new_client();
+
+    if (c == NULL)
+      uw_error(ctx, FATAL, "Limit exceeded on number of message-passing clients");
+
+    use_client(c);
+    uw_copy_client_data(c->data, ctx->client_data);
+    ctx->client = c;
   }
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/channelThief.ur	Fri Dec 27 12:10:03 2013 -0500
@@ -0,0 +1,32 @@
+table t : { Ch : channel string }
+
+fun go () =
+    let
+        fun overwrite () =
+            dml (DELETE FROM t WHERE TRUE);
+            ch <- channel;
+            dml (INSERT INTO t (Ch) VALUES ({[ch]}));
+            return ch
+
+        fun retrieve () =
+            oneRowE1 (SELECT (t.Ch) FROM t)
+
+        fun transmit () =
+            ch <- retrieve ();
+            send ch "Test"
+
+        fun listenOn ch =
+            s <- recv ch;
+            alert s
+    in
+        ch <- overwrite ();
+        return <xml><body onload={listenOn ch}>
+          <button value="overwrite" onclick={fn _ => ch <- rpc (overwrite ()); listenOn ch}/>
+          <button value="retrieve" onclick={fn _ => ch <- rpc (retrieve ()); listenOn ch}/>
+          <button value="transmit" onclick={fn _ => rpc (transmit ())}/>
+        </body></xml>
+    end
+
+fun main () = return <xml><body>
+  <form><submit action={go}/></form>
+</body></xml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/channelThief.urp	Fri Dec 27 12:10:03 2013 -0500
@@ -0,0 +1,5 @@
+database dbname=test
+sql channelThief.sql
+rewrite url ChannelThief/*
+
+channelThief
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/channelThief.urs	Fri Dec 27 12:10:03 2013 -0500
@@ -0,0 +1,1 @@
+val main : unit -> transaction page