comparison src/iflow.sml @ 1282:a9a500d22ebc

Roll back WHERE checking
author Adam Chlipala <adam@chlipala.net>
date Tue, 27 Jul 2010 14:04:09 -0400
parents 60e19545841b
children acabf3935060
comparison
equal deleted inserted replaced
1281:60e19545841b 1282:a9a500d22ebc
1226 val addPath : check -> unit 1226 val addPath : check -> unit
1227 1227
1228 val allowSend : atom list * exp list -> unit 1228 val allowSend : atom list * exp list -> unit
1229 val send : check -> unit 1229 val send : check -> unit
1230 1230
1231 val allowEqual : { table : string, field : string, known : bool } -> unit
1232 val mayTest : prop -> bool
1233
1234 val allowInsert : atom list -> unit 1231 val allowInsert : atom list -> unit
1235 val insert : ErrorMsg.span -> unit 1232 val insert : ErrorMsg.span -> unit
1236 1233
1237 val allowDelete : atom list -> unit 1234 val allowDelete : atom list -> unit
1238 val delete : ErrorMsg.span -> unit 1235 val delete : ErrorMsg.span -> unit
1507 1504
1508 val deletable = ref ([] : atom list list) 1505 val deletable = ref ([] : atom list list)
1509 fun allowDelete v = deletable := v :: !deletable 1506 fun allowDelete v = deletable := v :: !deletable
1510 val delete = doable deletable 1507 val delete = doable deletable
1511 1508
1512 val testable = ref ([] : { table : string, field : string, known : bool } list)
1513 fun allowEqual v = testable := v :: !testable
1514 fun mayTest p =
1515 case p of
1516 Reln (Eq, [e1, e2]) =>
1517 let
1518 val (_, hs, _) = !hyps
1519
1520 fun tableInHyps (tab, x) = List.exists (fn AReln (Sql tab', [Var x']) => tab' = tab andalso x' = x
1521 | _ => false) hs
1522
1523 fun allowed (tab, v) =
1524 case tab of
1525 Proj (Var tab, fd) =>
1526 List.exists (fn {table = tab', field = fd', known} =>
1527 fd' = fd
1528 andalso tableInHyps (tab', tab)
1529 andalso (not known orelse Cc.check (db, AReln (Known, [v])))) (!testable)
1530 | _ => false
1531 in
1532 if allowed (e1, e2) orelse allowed (e2, e1) then
1533 (assert [AReln (Eq, [e1, e2])];
1534 true)
1535 else
1536 false
1537 end
1538 | _ => false
1539
1540 fun reset () = (Cc.clear db; 1509 fun reset () = (Cc.clear db;
1541 path := []; 1510 path := [];
1542 hyps := (0, [], ref false); 1511 hyps := (0, [], ref false);
1543 nvar := 0; 1512 nvar := 0;
1544 sendable := []; 1513 sendable := [];
1545 testable := [];
1546 insertable := []; 1514 insertable := [];
1547 updatable := []; 1515 updatable := [];
1548 deletable := []) 1516 deletable := [])
1549 1517
1550 fun havocReln r = 1518 fun havocReln r =
1690 Env : exp list, 1658 Env : exp list,
1691 NextVar : unit -> exp, 1659 NextVar : unit -> exp,
1692 Add : atom -> unit, 1660 Add : atom -> unit,
1693 Save : unit -> 'a, 1661 Save : unit -> 'a,
1694 Restore : 'a -> unit, 1662 Restore : 'a -> unit,
1695 Cont : queryMode, 1663 Cont : queryMode
1696 Send : exp -> unit
1697 } 1664 }
1698 1665
1699 fun doQuery (arg : 'a doQuery) (e as (_, loc)) = 1666 fun doQuery (arg : 'a doQuery) (e as (_, loc)) =
1700 let 1667 let
1701 fun default () = ErrorMsg.errorAt loc "Information flow checker can't parse SQL query" 1668 fun default () = ErrorMsg.errorAt loc "Information flow checker can't parse SQL query"
1730 val expIn = expIn (#NextVar arg) (#Env arg) rvOf 1697 val expIn = expIn (#NextVar arg) (#Env arg) rvOf
1731 1698
1732 val saved = #Save arg () 1699 val saved = #Save arg ()
1733 fun addFrom () = app (fn (t, v) => #Add arg (AReln (Sql t, [rvOf v]))) (#From r) 1700 fun addFrom () = app (fn (t, v) => #Add arg (AReln (Sql t, [rvOf v]))) (#From r)
1734 1701
1735 fun leavesE e = 1702 fun usedFields e =
1736 case e of 1703 case e of
1737 Const _ => [] 1704 SqConst _ => []
1738 | Var _ => [] 1705 | SqTrue => []
1739 | Lvar _ => [] 1706 | SqFalse => []
1740 | Func (_, es) => List.concat (map leavesE es) 1707 | Null => []
1741 | Recd xes => List.concat (map (leavesE o #2) xes) 1708 | SqNot e => usedFields e
1742 | Proj _ => [e] 1709 | Field (v, f) => [(false, Proj (rvOf v, f))]
1743 1710 | Computed _ => []
1744 fun leavesP p = 1711 | Binop (_, e1, e2) => usedFields e1 @ usedFields e2
1745 case p of 1712 | SqKnown _ => []
1746 True => [] 1713 | Inj e =>
1747 | False => [] 1714 (case deinj (#Env arg) e of
1748 | Unknown => [] 1715 NONE => (ErrorMsg.errorAt loc "Expression injected into SQL is too complicated";
1749 | And (p1, p2) => leavesP p1 @ leavesP p2 1716 [])
1750 | Or (p1, p2) => leavesP p1 @ leavesP p2 1717 | SOME e => [(true, e)])
1751 | Reln (_, es) => List.concat (map leavesE es) 1718 | SqFunc (_, e) => usedFields e
1752 | Cond (e, p) => e :: leavesP p 1719 | Unmodeled => []
1753 1720
1754 fun normal' () = 1721 fun normal' () =
1755 case #Cont arg of 1722 case #Cont arg of
1756 SomeCol k => 1723 SomeCol k =>
1757 let 1724 let
1800 let 1767 let
1801 val p = case expIn e of 1768 val p = case expIn e of
1802 inl e => Reln (Eq, [e, Func (DtCon0 "Basis.bool.True", [])]) 1769 inl e => Reln (Eq, [e, Func (DtCon0 "Basis.bool.True", [])])
1803 | inr p => p 1770 | inr p => p
1804 1771
1805 fun getConjuncts p =
1806 case p of
1807 And (p1, p2) => getConjuncts p1 @ getConjuncts p2
1808 | _ => [p]
1809
1810 val saved = #Save arg () 1772 val saved = #Save arg ()
1811
1812 val conjs = getConjuncts p
1813 val conjs = List.filter (not o St.mayTest) conjs
1814 in 1773 in
1815 app (fn p => app (#Send arg) (leavesP p)) conjs;
1816 decomp {Save = #Save arg, Restore = #Restore arg, Add = #Add arg} 1774 decomp {Save = #Save arg, Restore = #Restore arg, Add = #Add arg}
1817 p (fn () => final () handle Cc.Contradiction => ()); 1775 p (fn () => final () handle Cc.Contradiction => ());
1818 #Restore arg saved 1776 #Restore arg saved
1819 end) 1777 end)
1820 handle Cc.Contradiction => () 1778 handle Cc.Contradiction => ()
2116 doQuery {Env = env, 2074 doQuery {Env = env,
2117 NextVar = Var o St.nextVar, 2075 NextVar = Var o St.nextVar,
2118 Add = fn a => St.assert [a], 2076 Add = fn a => St.assert [a],
2119 Save = St.stash, 2077 Save = St.stash,
2120 Restore = St.reinstate, 2078 Restore = St.reinstate,
2121 Send = fn e => St.send (e, loc),
2122 Cont = AllCols (fn x => 2079 Cont = AllCols (fn x =>
2123 (St.assert [AReln (Eq, [r, x])]; 2080 (St.assert [AReln (Eq, [r, x])];
2124 evalExp (acc :: r :: env) b k))} q 2081 evalExp (acc :: r :: env) b k))} q
2125 end) 2082 end)
2126 | EDml e => 2083 | EDml e =>
2489 fun doQ k = doQuery {Env = [], 2446 fun doQ k = doQuery {Env = [],
2490 NextVar = rv, 2447 NextVar = rv,
2491 Add = fn a => atoms := a :: !atoms, 2448 Add = fn a => atoms := a :: !atoms,
2492 Save = fn () => !atoms, 2449 Save = fn () => !atoms,
2493 Restore = fn ls => atoms := ls, 2450 Restore = fn ls => atoms := ls,
2494 Send = fn _ => (),
2495 Cont = SomeCol (fn r => k (rev (!atoms), r))} 2451 Cont = SomeCol (fn r => k (rev (!atoms), r))}
2496 2452
2497 fun untab (tab, nams) = List.filter (fn AReln (Sql tab', [Lvar lv]) => 2453 fun untab (tab, nams) = List.filter (fn AReln (Sql tab', [Lvar lv]) =>
2498 tab' <> tab 2454 tab' <> tab
2499 orelse List.all (fn Lvar lv' => lv' <> lv 2455 orelse List.all (fn Lvar lv' => lv' <> lv
2525 val outs = [Lvar 0] 2481 val outs = [Lvar 0]
2526 in 2482 in
2527 St.allowSend ([p], outs) 2483 St.allowSend ([p], outs)
2528 end 2484 end
2529 | _ => ()) 2485 | _ => ())
2530 | PolEqual {table = tab, field = nm, known} =>
2531 (case #1 tab of
2532 EPrim (Prim.String tab) => St.allowEqual {table = String.extract (tab, 3, NONE),
2533 field = nm,
2534 known = known}
2535 | _ => ErrorMsg.errorAt loc "Table for 'equalKnown' policy isn't fully resolved.")
2536 end 2486 end
2537 2487
2538 | _ => () 2488 | _ => ()
2539 in 2489 in
2540 app decl file 2490 app decl file