comparison src/monoize.sml @ 735:5ccb67665d05

Only use cookie signatures when cookies might be read
author Adam Chlipala <adamc@hcoop.net>
date Thu, 23 Apr 2009 14:10:10 -0400
parents f2a2be93331c
children 796e42c93c48
comparison
equal deleted inserted replaced
734:f2a2be93331c 735:5ccb67665d05
32 32
33 structure L = Core 33 structure L = Core
34 structure L' = Mono 34 structure L' = Mono
35 35
36 structure IM = IntBinaryMap 36 structure IM = IntBinaryMap
37 structure IS = IntBinarySet
37 38
38 val urlPrefix = ref "/" 39 val urlPrefix = ref "/"
39 40
40 val dummyTyp = (L'.TDatatype (0, ref (L'.Enum, [])), E.dummySpan) 41 val dummyTyp = (L'.TDatatype (0, ref (L'.Enum, [])), E.dummySpan)
41 42
535 (L'.EStrcat ((L'.EPrim (Prim.String ", "), loc), e'), loc)), loc)) 536 (L'.EStrcat ((L'.EPrim (Prim.String ", "), loc), e'), loc)), loc))
536 e1 es 537 e1 es
537 end 538 end
538 539
539 fun strcatR loc e xs = strcatComma loc (map (fn (x, _) => (L'.EField (e, x), loc)) xs) 540 fun strcatR loc e xs = strcatComma loc (map (fn (x, _) => (L'.EField (e, x), loc)) xs)
541
542 val readCookie = ref IS.empty
540 543
541 fun monoExp (env, st, fm) (all as (e, loc)) = 544 fun monoExp (env, st, fm) (all as (e, loc)) =
542 let 545 let
543 val strcat = strcat loc 546 val strcat = strcat loc
544 val strcatComma = strcatComma loc 547 val strcatComma = strcatComma loc
2451 NotFound => Found et 2454 NotFound => Found et
2452 | _ => Error) 2455 | _ => Error)
2453 | _ => findSubmit xml) 2456 | _ => findSubmit xml)
2454 | _ => NotFound 2457 | _ => NotFound
2455 2458
2456 val (action, fm) = case findSubmit xml of 2459 val (func, action, fm) = case findSubmit xml of
2457 NotFound => ((L'.EPrim (Prim.String ""), loc), fm) 2460 NotFound => (0, (L'.EPrim (Prim.String ""), loc), fm)
2458 | Error => raise Fail "Not ready for multi-submit lforms yet" 2461 | Error => raise Fail "Not ready for multi-submit lforms yet"
2459 | Found (action, actionT) => 2462 | Found (action, actionT) =>
2460 let 2463 let
2464 val func = case #1 action of
2465 L.EClosure (n, _) => n
2466 | _ => raise Fail "Monoize: Action is not a closure"
2461 val actionT = monoType env actionT 2467 val actionT = monoType env actionT
2462 val (action, fm) = monoExp (env, st, fm) action 2468 val (action, fm) = monoExp (env, st, fm) action
2463 val (action, fm) = urlifyExp env fm (action, actionT) 2469 val (action, fm) = urlifyExp env fm (action, actionT)
2464 in 2470 in
2465 ((L'.EStrcat ((L'.EPrim (Prim.String " action=\""), loc), 2471 (func,
2472 (L'.EStrcat ((L'.EPrim (Prim.String " action=\""), loc),
2466 (L'.EStrcat (action, 2473 (L'.EStrcat (action,
2467 (L'.EPrim (Prim.String "\""), loc)), loc)), loc), 2474 (L'.EPrim (Prim.String "\""), loc)), loc)), loc),
2468 fm) 2475 fm)
2469 end 2476 end
2470
2471 fun inFields s = List.exists (fn ((L.CName s', _), _) => s' = s
2472 | _ => true) fields
2473
2474 fun getSigName () =
2475 let
2476 fun getSigName' n =
2477 let
2478 val s = "Sig" ^ Int.toString n
2479 in
2480 if inFields s then
2481 getSigName' (n + 1)
2482 else
2483 s
2484 end
2485 in
2486 if inFields "Sig" then
2487 getSigName' 0
2488 else
2489 "Sig"
2490 end
2491
2492 val sigName = getSigName ()
2493 val sigSet = (L'.EFfiApp ("Basis", "sigString", [(L'.ERecord [], loc)]), loc)
2494 val sigSet = (L'.EStrcat ((L'.EPrim (Prim.String ("<input type=\"hidden\" name=\""
2495 ^ sigName
2496 ^ "\" value=\"")), loc),
2497 sigSet), loc)
2498 val sigSet = (L'.EStrcat (sigSet,
2499 (L'.EPrim (Prim.String "\">"), loc)), loc)
2500 2477
2501 val (xml, fm) = monoExp (env, st, fm) xml 2478 val (xml, fm) = monoExp (env, st, fm) xml
2502 val xml = (L'.EStrcat (sigSet, xml), loc) 2479
2480 val xml =
2481 if IS.member (!readCookie, func) then
2482 let
2483 fun inFields s = List.exists (fn ((L.CName s', _), _) => s' = s
2484 | _ => true) fields
2485
2486 fun getSigName () =
2487 let
2488 fun getSigName' n =
2489 let
2490 val s = "Sig" ^ Int.toString n
2491 in
2492 if inFields s then
2493 getSigName' (n + 1)
2494 else
2495 s
2496 end
2497 in
2498 if inFields "Sig" then
2499 getSigName' 0
2500 else
2501 "Sig"
2502 end
2503
2504 val sigName = getSigName ()
2505 val sigSet = (L'.EFfiApp ("Basis", "sigString", [(L'.ERecord [], loc)]), loc)
2506 val sigSet = (L'.EStrcat ((L'.EPrim (Prim.String ("<input type=\"hidden\" name=\""
2507 ^ sigName
2508 ^ "\" value=\"")), loc),
2509 sigSet), loc)
2510 val sigSet = (L'.EStrcat (sigSet,
2511 (L'.EPrim (Prim.String "\">"), loc)), loc)
2512 in
2513 (L'.EStrcat (sigSet, xml), loc)
2514 end
2515 else
2516 xml
2503 in 2517 in
2504 ((L'.EStrcat ((L'.EStrcat ((L'.EPrim (Prim.String "<form method=\"post\""), loc), 2518 ((L'.EStrcat ((L'.EStrcat ((L'.EPrim (Prim.String "<form method=\"post\""), loc),
2505 (L'.EStrcat (action, 2519 (L'.EStrcat (action,
2506 (L'.EPrim (Prim.String ">"), loc)), loc)), loc), 2520 (L'.EPrim (Prim.String ">"), loc)), loc)), loc),
2507 (L'.EStrcat (xml, 2521 (L'.EStrcat (xml,
2790 urlPrefix := "/" 2804 urlPrefix := "/"
2791 else if String.sub (p, size p - 1) <> #"/" then 2805 else if String.sub (p, size p - 1) <> #"/" then
2792 urlPrefix := p ^ "/" 2806 urlPrefix := p ^ "/"
2793 else 2807 else
2794 () 2808 ()
2809
2810 (* Calculate which exported functions need cookie signature protection *)
2811 val rcook = foldl (fn ((d, _), rcook) =>
2812 case d of
2813 L.DExport (L.Action L.ReadCookieWrite, n) => IS.add (rcook, n)
2814 | L.DExport (L.Rpc L.ReadCookieWrite, n) => IS.add (rcook, n)
2815 | _ => rcook)
2816 IS.empty file
2817 val () = readCookie := rcook
2795 2818
2796 val loc = E.dummySpan 2819 val loc = E.dummySpan
2797 val client = (L'.TFfi ("Basis", "client"), loc) 2820 val client = (L'.TFfi ("Basis", "client"), loc)
2798 val unit = (L'.TRecord [], loc) 2821 val unit = (L'.TRecord [], loc)
2799 2822