annotate src/dbmodecheck.sml @ 2297:6d56080f495c

Fix a read-after-free bug using a timestamp check
author Adam Chlipala <adam@chlipala.net>
date Thu, 19 Nov 2015 13:18:58 -0500
parents e843a04499d4
children
rev   line source
adam@2056 1 (* Copyright (c) 2014, Adam Chlipala
adam@2056 2 * All rights reserved.
adam@2056 3 *
adam@2056 4 * Redistribution and use in source and binary forms, with or without
adam@2056 5 * modification, are permitted provided that the following conditions are met:
adam@2056 6 *
adam@2056 7 * - Redistributions of source code must retain the above copyright notice,
adam@2056 8 * this list of conditions and the following disclaimer.
adam@2056 9 * - Redistributions in binary form must reproduce the above copyright notice,
adam@2056 10 * this list of conditions and the following disclaimer in the documentation
adam@2056 11 * and/or other materials provided with the distribution.
adam@2056 12 * - The names of contributors may not be used to endorse or promote products
adam@2056 13 * derived from this software without specific prior written permission.
adam@2056 14 *
adam@2056 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
adam@2056 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
adam@2056 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
adam@2056 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
ziv@2252 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
adam@2056 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
adam@2056 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
adam@2056 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
adam@2056 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
adam@2056 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
adam@2056 25 * POSSIBILITY OF SUCH DAMAGE.
adam@2056 26 *)
adam@2056 27
adam@2056 28 structure DbModeCheck :> DB_MODE_CHECK = struct
adam@2056 29
adam@2056 30 open Mono
adam@2056 31
adam@2056 32 structure IM = IntBinaryMap
adam@2056 33
ziv@2252 34 fun classify (ds, ps) =
adam@2056 35 let
adam@2056 36 fun mergeModes (m1, m2) =
adam@2056 37 case (m1, m2) of
adam@2056 38 (NoDb, _) => m2
adam@2056 39 | (_, NoDb) => m1
adam@2056 40 | _ => AnyDb
adam@2056 41
adam@2056 42 fun modeOf modes =
adam@2056 43 MonoUtil.Exp.fold {typ = fn (_, dbm) => dbm,
adam@2056 44 exp = fn (EQuery _, dbm) => mergeModes (OneQuery, dbm)
adam@2056 45 | (EDml _, _) => AnyDb
adam@2056 46 | (ENextval _, _) => AnyDb
adam@2056 47 | (ESetval _, _) => AnyDb
adam@2056 48 | (ENamed n, dbm) =>
adam@2056 49 (case IM.find (modes, n) of
adam@2056 50 NONE => dbm
adam@2056 51 | SOME dbm' => mergeModes (dbm, dbm'))
adam@2056 52 | (_, dbm) => dbm} NoDb
adam@2056 53
adam@2056 54 fun decl ((d, _), modes) =
adam@2056 55 case d of
adam@2056 56 DVal (x, n, _, e, _) => IM.insert (modes, n, modeOf modes e)
adam@2056 57 | DValRec xes =>
adam@2056 58 let
adam@2056 59 val mode = foldl (fn ((_, _, _, e, _), mode) =>
adam@2056 60 let
adam@2056 61 val mode' = modeOf modes e
adam@2056 62 in
adam@2056 63 case mode' of
adam@2056 64 NoDb => mode
adam@2056 65 | _ => AnyDb
adam@2056 66 end) NoDb xes
adam@2056 67 in
adam@2056 68 foldl (fn ((_, n, _, _, _), modes) => IM.insert (modes, n, mode)) modes xes
adam@2056 69 end
adam@2056 70 | _ => modes
adam@2056 71
adam@2056 72 val modes = foldl decl IM.empty ds
adam@2056 73
adam@2056 74 val (ps, modes) = ListUtil.foldlMap (fn ((n, side, _), modes) =>
adam@2056 75 case IM.find (modes, n) of
adam@2056 76 NONE => ((n, side, AnyDb), modes)
adam@2056 77 | SOME mode => ((n, side, mode), #1 (IM.remove (modes, n))))
adam@2056 78 modes ps
adam@2056 79
adam@2056 80 val ps = IM.foldli (fn (n, mode, ps) => (n, ServerOnly, mode) :: ps) ps modes
adam@2056 81 in
ziv@2252 82 (ds, ps)
adam@2056 83 end
adam@2056 84
adam@2056 85 end
ziv@2252 86