Mercurial > urweb
diff 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 |
line wrap: on
line diff
--- a/src/monoize.sml Thu Apr 16 19:12:12 2009 -0400 +++ b/src/monoize.sml Thu Apr 23 14:10:10 2009 -0400 @@ -34,6 +34,7 @@ structure L' = Mono structure IM = IntBinaryMap +structure IS = IntBinarySet val urlPrefix = ref "/" @@ -538,6 +539,8 @@ fun strcatR loc e xs = strcatComma loc (map (fn (x, _) => (L'.EField (e, x), loc)) xs) +val readCookie = ref IS.empty + fun monoExp (env, st, fm) (all as (e, loc)) = let val strcat = strcat loc @@ -2453,53 +2456,64 @@ | _ => findSubmit xml) | _ => NotFound - val (action, fm) = case findSubmit xml of - NotFound => ((L'.EPrim (Prim.String ""), loc), fm) + val (func, action, fm) = case findSubmit xml of + NotFound => (0, (L'.EPrim (Prim.String ""), loc), fm) | Error => raise Fail "Not ready for multi-submit lforms yet" | Found (action, actionT) => let + val func = case #1 action of + L.EClosure (n, _) => n + | _ => raise Fail "Monoize: Action is not a closure" val actionT = monoType env actionT val (action, fm) = monoExp (env, st, fm) action val (action, fm) = urlifyExp env fm (action, actionT) in - ((L'.EStrcat ((L'.EPrim (Prim.String " action=\""), loc), + (func, + (L'.EStrcat ((L'.EPrim (Prim.String " action=\""), loc), (L'.EStrcat (action, (L'.EPrim (Prim.String "\""), loc)), loc)), loc), fm) end - - fun inFields s = List.exists (fn ((L.CName s', _), _) => s' = s - | _ => true) fields - - fun getSigName () = - let - fun getSigName' n = - let - val s = "Sig" ^ Int.toString n - in - if inFields s then - getSigName' (n + 1) - else - s - end - in - if inFields "Sig" then - getSigName' 0 - else - "Sig" - end - - val sigName = getSigName () - val sigSet = (L'.EFfiApp ("Basis", "sigString", [(L'.ERecord [], loc)]), loc) - val sigSet = (L'.EStrcat ((L'.EPrim (Prim.String ("<input type=\"hidden\" name=\"" - ^ sigName - ^ "\" value=\"")), loc), - sigSet), loc) - val sigSet = (L'.EStrcat (sigSet, - (L'.EPrim (Prim.String "\">"), loc)), loc) val (xml, fm) = monoExp (env, st, fm) xml - val xml = (L'.EStrcat (sigSet, xml), loc) + + val xml = + if IS.member (!readCookie, func) then + let + fun inFields s = List.exists (fn ((L.CName s', _), _) => s' = s + | _ => true) fields + + fun getSigName () = + let + fun getSigName' n = + let + val s = "Sig" ^ Int.toString n + in + if inFields s then + getSigName' (n + 1) + else + s + end + in + if inFields "Sig" then + getSigName' 0 + else + "Sig" + end + + val sigName = getSigName () + val sigSet = (L'.EFfiApp ("Basis", "sigString", [(L'.ERecord [], loc)]), loc) + val sigSet = (L'.EStrcat ((L'.EPrim (Prim.String ("<input type=\"hidden\" name=\"" + ^ sigName + ^ "\" value=\"")), loc), + sigSet), loc) + val sigSet = (L'.EStrcat (sigSet, + (L'.EPrim (Prim.String "\">"), loc)), loc) + in + (L'.EStrcat (sigSet, xml), loc) + end + else + xml in ((L'.EStrcat ((L'.EStrcat ((L'.EPrim (Prim.String "<form method=\"post\""), loc), (L'.EStrcat (action, @@ -2793,6 +2807,15 @@ else () + (* Calculate which exported functions need cookie signature protection *) + val rcook = foldl (fn ((d, _), rcook) => + case d of + L.DExport (L.Action L.ReadCookieWrite, n) => IS.add (rcook, n) + | L.DExport (L.Rpc L.ReadCookieWrite, n) => IS.add (rcook, n) + | _ => rcook) + IS.empty file + val () = readCookie := rcook + val loc = E.dummySpan val client = (L'.TFfi ("Basis", "client"), loc) val unit = (L'.TRecord [], loc)