Skip to content
REFERENCE / ZLIB × LEAN

inflate.c.start.lean

Source snapshot · 3b8e27afda5332c6 · Source at the matching commit ↗

Lean source with line numbers. Follow a line number to locate a statement, or an import to read its dependency.

1import ZlibF.Proof.«inflate.c.end»
2
3/-!
4# inflate.c: `inflateInit2_` and `inflateInit_`
5-/
6
7namespace Zlib.Inflate.Proofs
8open C Zlib.Inflate Zlib.Inflate.Spec
9
10theorem inflateReset2_ok_of {h : Heap} {r : ZStreamRef} {zs : Nat} {z : ZStream} {st : InflateState}
11    (hL : Live h r zs z st) (hf : z.zfree = .fn "zcfree") (hwo : WindowOk h st.window) {w : Int32}
12    {wrap wb : Int32} (hp : reset2Params w = some (wrap, wb)) :
13    inflateReset2 (some r) w h = .ok (Z_OK, setI (r.put (reset2Heap h wb st)
14        (resetKeepStream z (resetPre (reset2Pre wrap wb st)))) zs (resetKeepState zs (resetPre (reset2Pre wrap wb st)))) := by
15  have := inflateReset2_run hL hf hwo w
16  rw [hp] at this
17  exact this.2
18
19theorem inflateReset2_err_of {h : Heap} {r : ZStreamRef} {zs : Nat} {z : ZStream} {st : InflateState}
20    (hL : Live h r zs z st) (hf : z.zfree = .fn "zcfree") (hwo : WindowOk h st.window) {w : Int32}
21    (hp : reset2Params w = none) : inflateReset2 (some r) w h = .ok (Z_STREAM_ERROR, h) := by
22  have := inflateReset2_run hL hf hwo w
23  rw [hp] at this
24  exact this
25
26@[simp] theorem allocIstHeap_streams (h : Heap) (st : InflateState) : (allocIstHeap h st).streams = h.streams := rfl
27@[simp] theorem allocIstHeap_gzstates (h : Heap) (st : InflateState) : (allocIstHeap h st).gzstates = h.gzstates := rfl
28@[simp] theorem allocIstHeap_bytes (h : Heap) (st : InflateState) : (allocIstHeap h st).bytes = h.bytes := rfl
29@[simp] theorem allocIstHeap_ro (h : Heap) (st : InflateState) : (allocIstHeap h st).ro = h.ro := rfl
30@[simp] theorem allocIstHeap_nextBlk (h : Heap) (st : InflateState) : (allocIstHeap h st).nextBlk = h.nextBlk + 1 := rfl
31@[simp] theorem allocIstHeap_nalloc (h : Heap) (st : InflateState) : (allocIstHeap h st).nalloc = h.nalloc + 1 := rfl
32@[simp] theorem allocIstHeap_istates_same (h : Heap) (st : InflateState) : (allocIstHeap h st).istates h.nextBlk = some st := by
33  simp [allocIstHeap]
34@[simp] theorem allocIstHeap_istates_ne (h : Heap) (st : InflateState) (x : Nat) (hx : x ≠ h.nextBlk) :
35    (allocIstHeap h st).istates x = h.istates x := by simp [allocIstHeap, upd_ne _ _ _ _ hx]
36
37@[simp] theorem ZStreamRef.get_allocIst (h : Heap) (st : InflateState) (r : ZStreamRef) :
38    r.get (allocIstHeap h st) = r.get h := by cases r <;> rfl
39
40@[simp] theorem ZStreamRef.put_allocIst (h : Heap) (st : InflateState) (r : ZStreamRef) (v : ZStream) :
41    r.put (allocIstHeap h st) v = allocIstHeap (r.put h v) st := by
42  cases r with
43  | tab i => simp only [ZStreamRef.put, allocIstHeap]; cases hh : h.streams i <;> simp
44  | in_gzstate_strm i => simp only [ZStreamRef.put, allocIstHeap]; cases hh : h.gzstates i <;> simp
45
46@[simp] theorem allocIstHeap_istates_eq (h : Heap) (st : InflateState) (x : Nat) (hx : x = h.nextBlk) :
47    (allocIstHeap h st).istates x = some st := by subst hx; simp
48
49@[simp] theorem setI_allocIst (h : Heap) (g s : InflateState) (x : Nat) (hx : x = h.nextBlk) :
50    setI (allocIstHeap h g) x s = allocIstHeap h s := by
51  subst hx; simp [setI, allocIstHeap, upd_upd]
52
53theorem zfrees_run' {h : Heap} {r : ZStreamRef} {z : ZStream} (hz : r.get h = some z) (hf : z.zfree = .fn "zcfree")
54    (zs : Nat) : ZFREES (some r) (some (.tab zs)) h = freeInflateState (some (.tab zs)) h := by
55  simp [ZFREES, ldZ_eq, hz, hf]
56
57theorem zfrees_run2 {h : Heap} {r : ZStreamRef} (hf : (r.get h).map (·.zfree) = some (.fn "zcfree")) (zs : Nat) :
58    ZFREES (some r) (some (.tab zs)) h = freeInflateState (some (.tab zs)) h := by
59  cases hz : r.get h with
60  | none => simp [hz] at hf
61  | some z =>
62    simp [hz] at hf
63    exact zfrees_run' hz hf zs
64
65theorem freeI_eq (h : Heap) (zs : Nat) : freeInflateState (some (.tab zs)) h =
66    match h.istates zs with
67    | some _ => Except.ok ((), freeIst h zs)
68    | none => Except.error (Fault.ub "free of a freed or invalid pointer (inflate_state)") := rfl
69
70theorem zallocs_run {h : Heap} {r : ZStreamRef} {z : ZStream} (hz : r.get h = some z) (hza : z.zalloc = .fn "zcalloc") :
71    ZALLOCS (some r) h = allocInflateState h := by
72  simp [ZALLOCS, ldZ_eq, hz, hza]
73
74theorem allocIst_ok (h : Heap) (hok : h.allocOk h.nalloc = true) (hF : Fresh h) :
75    allocInflateState h = .ok (some (.tab h.nextBlk), allocIstHeap h (InflateState.garbage (h.garbage h.nalloc))) := by
76  rw [allocInflateState_some hok hF.slotUsed_next]; rfl
77
78theorem allocIst_put {h : Heap} {r : ZStreamRef} {z : ZStream} (hz : r.get h = some z) (hok : h.allocOk h.nalloc = true)
79    (hF : Fresh h) (v : ZStream) :
80    allocInflateState (r.put h v) = .ok (some (.tab h.nextBlk),
81      allocIstHeap (r.put h v) (InflateState.garbage (h.garbage h.nalloc))) := by
82  have hF' : Fresh (r.put h v) := (shape_put hz v).fresh (by simp) hF
83  rw [allocInflateState_some (by simpa using hok) hF'.slotUsed_next]
84  simp [allocIstHeap]
85
86theorem allocIst_fail_put {h : Heap} {r : ZStreamRef} (hok : ¬ h.allocOk h.nalloc = true) (v : ZStream) :
87    allocInflateState (r.put h v) = .ok (none, { r.put h v with nalloc := h.nalloc + 1 }) := by
88  have : ¬ (r.put h v).allocOk (r.put h v).nalloc = true := by simpa using hok
89  rw [allocInflateState_none this]
90  simp
91
92theorem allocIst_fail (h : Heap) (hok : ¬ h.allocOk h.nalloc = true) :
93    allocInflateState h = .ok (none, { h with nalloc := h.nalloc + 1 }) := allocInflateState_none hok
94
95theorem fresh_allocIst {h : Heap} (hF : Fresh h) (st : InflateState) : Fresh (allocIstHeap h st) := by
96  intro b hb hl
97  simp only [allocIstHeap_nextBlk] at hb
98  apply hF b (by omega)
99  have hne : b ≠ h.nextBlk := by omega
100  simpa only [Heap.live, allocIstHeap, upd_ne _ _ _ _ hne] using hl
101
102theorem uniq_allocIst {h : Heap} (hU : Uniq h) (hF : Fresh h) (st : InflateState) : Uniq (allocIstHeap h st) := by
103  intro b
104  by_cases hb : b = h.nextBlk
105  · subst hb
106    have := Heap.not_live.mp (hF _ (Nat.le_refl _))
107    obtain ⟨e0, e1, e2, e3, e4, e5, e6⟩ := this
108    simp [allocIstHeap, e0, e1, e2, e3, e4, e6]
109  · have := hU b
110    simpa only [allocIstHeap, upd_ne _ _ _ _ hb] using this
111
112theorem owns_allocIst {h : Heap} (hF : Fresh h) (st : InflateState) {S : Nat → Prop} (hO : h.Owns S) :
113    (allocIstHeap h st).Owns (fun b => S b ∨ b = h.nextBlk) := by
114  intro b
115  by_cases hb : b = h.nextBlk
116  · subst hb; simp [Heap.live, allocIstHeap]
117  · have := hO b
118    simp only [Heap.live, allocIstHeap, upd_ne _ _ _ _ hb] at this ⊢
119    simp [hb, this]
120
121theorem inflateInit2_success {h : Heap} {r : ZStreamRef} {z : ZStream} {w : Int32} {version : BPtr}
122    (hz : r.get h = some z) (hF : Fresh h) (hok : h.allocOk h.nalloc = true)
123    (hza : z.zalloc = .null ∨ z.zalloc = .fn "zcalloc") (hzf : z.zfree = .null ∨ z.zfree = .fn "zcfree")
124    (hv : version ≠ .null) (hv0 : OkOn h (index8 version 0) 49)
125    {wrap wb : Int32} (hp : reset2Params w = some (wrap, wb)) :
126    inflateInit2_ (some r) w version 112 h = .ok (Z_OK, initOkHeap h r z wrap wb) := by
127  have hv0' : index8 version 0 h = .ok (49, h) := hv0
128  unfold inflateInit2_
129  rcases hza with hza | hza <;> rcases hzf with hzf | hzf <;>
130  isimp [hz, hv, hv0', initStream, hza, hzf, zallocs_run, allocIst_put hz hok hF]
131  all_goals (
132    rw [inflateReset2_ok_of (zs := h.nextBlk) (hp := hp)]
133    rotate_left
134    · exact ⟨by simp [hz]; rfl, allocIstHeap_istates_eq _ _ _ (by simp), by simp [StateRef.ofInflateState], by simp, by simp [HEAD, SYNC], by simp [initStream, hza], by simp [initStream, hza]⟩
135    · simp
136    · exact Or.inl rfl
137    · simp [initOkHeap, initStream2, initState, initStream, hza, hzf, reset2Heap, freeWin_null, StateRef.ofInflateState])
138
139
140theorem inflateInit2_version_null (strm : ZStreamPtr) (w : Int32) (sz : Int32) (h : Heap) :
141    inflateInit2_ strm w .null sz h = .ok (Z_VERSION_ERROR, h) := by
142  simp [inflateInit2_]
143
144theorem inflateInit2_version_char (strm : ZStreamPtr) (w : Int32) (version : BPtr) (sz : Int32) (h : Heap) (c : UInt8)
145    (hv : version ≠ .null) (hc : index8 version 0 h = .ok (c, h)) (hne : c ≠ 49) :
146    inflateInit2_ strm w version sz h = .ok (Z_VERSION_ERROR, h) := by
147  simp [inflateInit2_, hv, hc, hne]
148
149theorem inflateInit2_version_size (strm : ZStreamPtr) (w : Int32) (version : BPtr) (sz : Int32) (h : Heap)
150    (hv : version ≠ .null) (hc : index8 version 0 h = .ok (49, h)) (hne : sz ≠ 112) :
151    inflateInit2_ strm w version sz h = .ok (Z_VERSION_ERROR, h) := by
152  simp [inflateInit2_, hv, hc, hne]
153
154theorem inflateInit2_nullstream (w : Int32) (version : BPtr) (h : Heap)
155    (hv : version ≠ .null) (hc : index8 version 0 h = .ok (49, h)) :
156    inflateInit2_ none w version 112 h = .ok (Z_STREAM_ERROR, h) := by
157  simp [inflateInit2_, hv, hc]
158
159theorem inflateInit2_memfail {h : Heap} {r : ZStreamRef} {z : ZStream} {w : Int32} {version : BPtr}
160    (hz : r.get h = some z) (hF : Fresh h) (hok : ¬ h.allocOk h.nalloc = true)
161    (hza : z.zalloc = .null ∨ z.zalloc = .fn "zcalloc") (hzf : z.zfree = .null ∨ z.zfree = .fn "zcfree")
162    (hv : version ≠ .null) (hv0 : OkOn h (index8 version 0) 49) :
163    inflateInit2_ (some r) w version 112 h = .ok (Z_MEM_ERROR, initMemHeap h r z) := by
164  have hv0' : index8 version 0 h = .ok (49, h) := hv0
165  unfold inflateInit2_
166  rcases hza with hza | hza <;> rcases hzf with hzf | hzf <;>
167  isimp [hz, hv, hv0', initStream, hza, hzf, zallocs_run, allocIst_fail_put (r := r) hok, initMemHeap, initStream]
168
169theorem inflateInit2_badbits {h : Heap} {r : ZStreamRef} {z : ZStream} {w : Int32} {version : BPtr}
170    (hz : r.get h = some z) (hF : Fresh h) (hok : h.allocOk h.nalloc = true)
171    (hza : z.zalloc = .null ∨ z.zalloc = .fn "zcalloc") (hzf : z.zfree = .null ∨ z.zfree = .fn "zcfree")
172    (hv : version ≠ .null) (hv0 : OkOn h (index8 version 0) 49)
173    (hp : reset2Params w = none) :
174    inflateInit2_ (some r) w version 112 h = .ok (Z_STREAM_ERROR, initBadHeap h r z) := by
175  have hv0' : index8 version 0 h = .ok (49, h) := hv0
176  unfold inflateInit2_
177  rcases hza with hza | hza <;> rcases hzf with hzf | hzf <;>
178  isimp [hz, hv, hv0', initStream, hza, hzf, zallocs_run, allocIst_put hz hok hF]
179  all_goals (
180    rw [inflateReset2_err_of (zs := h.nextBlk) (hp := hp)]
181    rotate_left
182    · exact ⟨by simp [hz]; rfl, allocIstHeap_istates_eq _ _ _ (by simp), by simp [StateRef.ofInflateState], by simp, by simp [HEAD, SYNC], by simp [initStream, hza], by simp [initStream, hza]⟩
183    · simp
184    · exact Or.inl rfl
185    · isimp [initBadHeap, initStream2, initState, initStream, hza, hzf, reset2Heap, freeWin_null, StateRef.ofInflateState, zfrees_run2, freeI_eq, Z_STREAM_ERROR, Z_OK, hz])
186
187
188theorem initState_win (r : ZStreamRef) (h : Heap) : WinInv h (initState r) := by
189  refine ⟨?_, Or.inl rfl, fun _ => rfl, Or.inl rfl, ?_, ?_, ?_⟩
190  all_goals simp [initState, InflateState.zeroed, InflateState.garbage, Junk.of]
191
192theorem reset2Heap_null (h : Heap) (wb : Int32) (st : InflateState) (hw : st.window = .null) : reset2Heap h wb st = h := by
193  unfold reset2Heap; split
194  · rw [hw]; rfl
195  · rfl
196
197theorem wf_initState (r : ZStreamRef) : (initState r).WellFormed := by
198  simp [initState, InflateState.WellFormed, InflateState.zeroed, InflateState.garbage]
199
200theorem wf_reset2Pre (wrap wb : Int32) {st : InflateState} (hw : st.WellFormed) : (reset2Pre wrap wb st).WellFormed := by
201  unfold InflateState.WellFormed at *
202  unfold reset2Pre
203  split <;> simpa using hw
204
205theorem reset2Params_bits {w wrap wb : Int32} (hp : reset2Params w = some (wrap, wb)) : badBits wb = false := by
206  unfold reset2Params at hp
207  by_cases h1 : w < 0
208  · by_cases h2 : w < -15
209    · simp [h1, h2] at hp
210    · have e : Int32.ofInt (-w.toInt) = -w := by simp
211      simp only [h1, h2, ite_true, ite_false, e] at hp
212      by_cases hb : badBits (-w) = true
213      · simp [hb] at hp
214      · simp only [hb, Bool.false_eq_true, ite_false, Option.some.injEq, Prod.mk.injEq] at hp
215        obtain ⟨-, rfl⟩ := hp
216        simpa using hb
217  · by_cases h2 : w < 48
218    · simp only [h1, h2, ite_true, ite_false] at hp
219      by_cases hb : badBits (w &&& 15) = true
220      · simp [hb] at hp
221      · simp only [hb, Bool.false_eq_true, ite_false, Option.some.injEq, Prod.mk.injEq] at hp
222        obtain ⟨-, rfl⟩ := hp
223        simpa using hb
224    · simp only [h1, h2, ite_true, ite_false] at hp
225      by_cases hb : badBits w = true
226      · simp [hb] at hp
227      · simp only [hb, Bool.false_eq_true, ite_false, Option.some.injEq, Prod.mk.injEq] at hp
228        obtain ⟨-, rfl⟩ := hp
229        simpa using hb
230
231/-- **inflateInit2_, success.** If the version arguments are right (`version[0]` is `'1'`, `stream_size` is 112), the
232allocation of the state succeeds and `windowBits` is accepted (`reset2Params w = some (wrap, wb)`), the call returns
233`Z_OK` without a fault. The new state is the block `h.nextBlk` (nothing else is allocated), the stream record has the
234default allocator functions and points to it, the stream is initialised with the invariants intact, and the stream
235owns exactly one more block (the state; the window is allocated later by `updatewindow`). The allocator functions
236of the caller's record are `NULL` or the default ones (the model has no others). -/
237theorem inflateInit2_ok {h : Heap} {r : ZStreamRef} {z : ZStream} {w : Int32} {version : BPtr}
238    (hU : Uniq h) (hF : Fresh h) (hz : r.get h = some z) (hok : h.allocOk h.nalloc = true)
239    (hza : z.zalloc = .null ∨ z.zalloc = .fn "zcalloc") (hzf : z.zfree = .null ∨ z.zfree = .fn "zcfree")
240    (hv : version ≠ .null) (hv0 : OkOn h (index8 version 0) 49)
241    {wrap wb : Int32} (hp : reset2Params w = some (wrap, wb)) :
242    ∃ h', C.run (inflateInit2_ (some r) w version 112) h = .ok (Z_OK, h') ∧ h' = initOkHeap h r z wrap wb ∧
243      Good h' r h.nextBlk (resetKeepStream (initStream2 z h.nextBlk)
244        (resetPre (reset2Pre wrap wb (initState r)))) (resetKeepState h.nextBlk (resetPre (reset2Pre wrap wb (initState r)))) ∧
245      (∀ S, h.Owns S → h'.Owns (fun b => S b ∨ b = h.nextBlk)) := by
246  have hrun := inflateInit2_success hz hF hok hza hzf hv hv0 hp
247  have hb : badBits wb = false := reset2Params_bits hp
248  have hza' : (initStream z).zalloc ≠ .null := by
249    rcases hza with hza | hza <;> simp [initStream, hza]
250  have hzf' : (initStream z).zfree ≠ .null := by
251    rcases hzf with hzf | hzf <;> simp [initStream, hzf]
252  obtain ⟨z2, hz2⟩ : ∃ z2 : ZStream, z2 = initStream2 z h.nextBlk := ⟨_, rfl⟩
253  have hzp : r.get (r.put h z2) = some z2 := by simp [hz]
254  have hFp : Fresh (r.put h z2) := (shape_put hz z2).fresh (by simp) hF
255  have hUp : Uniq (r.put h z2) := (shape_put hz z2).uniq hU
256  have hFA := fresh_allocIst hFp (initState r)
257  have hUA := uniq_allocIst hUp hFp (initState r)
258  have e0 : reset2Heap (allocIstHeap (r.put h z2) (initState r)) wb (initState r) = allocIstHeap (r.put h z2) (initState r) :=
259    reset2Heap_null _ _ _ rfl
260  have hwin := winInv_reset2 (h := allocIstHeap (r.put h z2) (initState r)) (initState_win r _) (bits15 hb) wrap
261  have hz0 : r.get (allocIstHeap (r.put h z2) (initState r)) = some z2 := by simp [hz]
262  have hs0 : (allocIstHeap (r.put h z2) (initState r)).istates h.nextBlk = some (initState r) :=
263    allocIstHeap_istates_eq _ _ _ (by simp)
264  refine ⟨_, hrun, rfl, ?_, ?_⟩
265  · unfold initOkHeap
266    simp only [← hz2]
267    rw [e0]
268    refine good_set hz0 hs0 hUA hFA ?_ ?_ ?_ ?_ ?_ ?_
269    · simp [resetKeepStream, hz2, initStream2]
270    · simpa [resetKeepStream, hz2, initStream2] using hza'
271    · simpa [resetKeepStream, hz2, initStream2] using hzf'
272    · simp [resetKeepState, strm_pre, initState]
273    · simpa [resetKeepState] using mode_head
274    · rw [← e0]
275      refine stInv_rk (wf_resetPre (wf_reset2Pre wrap wb (wf_initState r))) hwin ?_
276      simpa [reqbits_resetPre, reset2Pre] using bits15 hb
277  · intro S hO
278    have h1 := owns_allocIst hFp (initState r) ((shape_put hz z2).owns hO)
279    simp only [ZStreamRef.put_nextBlk] at h1
280    unfold initOkHeap
281    simp only [← hz2]
282    rw [e0]
283    exact ((shape_put hz0 _).trans (shape_setI (by simp only [ZStreamRef.put_istates]; exact hs0) _)).owns h1
284
285
286theorem Shape.fresh_le {h h' : Heap} (hS : Shape h h') (hn : h.nextBlk ≤ h'.nextBlk) (hF : Fresh h) : Fresh h' := by
287  intro b hb hl
288  exact hF b (by omega) ((hS.live b).1 hl)
289
290theorem shape_allocfree {H : Heap} (hF : Fresh H) (st : InflateState) :
291    Shape H (freeIst (allocIstHeap H st) H.nextBlk) := by
292  intro b
293  by_cases hb : b = H.nextBlk
294  · subst hb
295    have := Heap.not_live.mp (hF _ (Nat.le_refl _))
296    obtain ⟨e0, e1, e2, e3, e4, e5, e6⟩ := this
297    simp [freeIst, allocIstHeap, e0, e1, e2, e3, e4, e5, e6]
298  · simp [freeIst, allocIstHeap, upd_ne _ _ _ _ hb]
299
300theorem initMem_good {h : Heap} {r : ZStreamRef} {z : ZStream} (hz : r.get h = some z) (hU : Uniq h) (hF : Fresh h) :
301    Uniq (initMemHeap h r z) ∧ Fresh (initMemHeap h r z) ∧ (∀ b, (initMemHeap h r z).live b ↔ h.live b) := by
302  have hS : Shape h (initMemHeap h r z) := by
303    have := shape_put hz (initStream z)
304    intro b; exact this b
305  exact ⟨hS.uniq hU, hS.fresh (by simp [initMemHeap]) hF, hS.live⟩
306
307theorem initBad_good {h : Heap} {r : ZStreamRef} {z : ZStream} (hz : r.get h = some z) (hU : Uniq h) (hF : Fresh h) :
308    Uniq (initBadHeap h r z) ∧ Fresh (initBadHeap h r z) ∧ (∀ b, (initBadHeap h r z).live b ↔ h.live b) := by
309  have hFp : Fresh (r.put h (initStream2 z h.nextBlk)) := (shape_put hz _).fresh (by simp) hF
310  have hS1 := shape_allocfree hFp (initState r)
311  have hS2 : Shape h (initBadHeap h r z) := by
312    unfold initBadHeap
313    simp only [ZStreamRef.put_nextBlk] at hS1
314    exact ((shape_put hz _).trans hS1).trans (shape_put (z0 := initStream2 z h.nextBlk) (by simp [hz]) _)
315  exact ⟨hS2.uniq hU, hS2.fresh_le (by simp [initBadHeap]) hF, hS2.live⟩
316
317/-- **inflateInit2_, safety (every outcome).** For a stream record `z` whose allocator functions are `NULL` or the default
318ones (`zlib.h`: the caller sets them before the call; the model has only the defaults), a `version` that is `NULL` or
319points to a readable byte, any `stream_size` and any `windowBits`, the call never faults and keeps `Uniq` and `Fresh`.
320The outcome is exactly one of: a version error (`version` `NULL`, first character not `'1'`, or `stream_size` not 112:
321nothing changes); `Z_MEM_ERROR` (the allocation oracle says no: no block is allocated, none leaks); `Z_STREAM_ERROR`
322(`windowBits` refused: the state was allocated and is freed again, the stream's state pointer is `NULL`, the live
323blocks are the old ones); `Z_OK` (see `inflateInit2_ok`). -/
324theorem inflateInit2_safe {h : Heap} {r : ZStreamRef} {z : ZStream} {w : Int32} {version : BPtr} {sz : Int32}
325    (hU : Uniq h) (hF : Fresh h) (hz : r.get h = some z)
326    (hza : z.zalloc = .null ∨ z.zalloc = .fn "zcalloc") (hzf : z.zfree = .null ∨ z.zfree = .fn "zcfree")
327    (hv : version = .null ∨ ∃ c, OkOn h (index8 version 0) c) :
328    ∃ v h', C.run (inflateInit2_ (some r) w version sz) h = .ok (v, h') ∧ Uniq h' ∧ Fresh h' ∧
329      ((v = Z_VERSION_ERROR ∧ h' = h ∧ (version = .null ∨ (∃ c, OkOn h (index8 version 0) c ∧ c ≠ 49) ∨ sz ≠ 112)) ∨
330       (v = Z_MEM_ERROR ∧ ¬ h.allocOk h.nalloc = true ∧ h' = initMemHeap h r z ∧ (∀ b, h'.live b ↔ h.live b)) ∨
331       (v = Z_STREAM_ERROR ∧ h.allocOk h.nalloc = true ∧ reset2Params w = none ∧ h' = initBadHeap h r z ∧
332          (∀ b, h'.live b ↔ h.live b)) ∨
333       (v = Z_OK ∧ sz = 112 ∧ h.allocOk h.nalloc = true ∧ ∃ wrap wb, reset2Params w = some (wrap, wb) ∧
334          h' = initOkHeap h r z wrap wb)) := by
335  by_cases hvn : version = .null
336  · subst hvn
337    exact ⟨_, _, by rw [C.run]; exact inflateInit2_version_null _ _ _ _, hU, hF, Or.inl ⟨rfl, rfl, Or.inl rfl⟩⟩
338  have hvc : ∃ c, OkOn h (index8 version 0) c := hv.resolve_left hvn
339  obtain ⟨c, hc⟩ := hvc
340  by_cases hc49 : c = 49
341  · subst hc49
342    by_cases hsz : sz = 112
343    · subst hsz
344      by_cases hok : h.allocOk h.nalloc = true
345      · cases hp : reset2Params w with
346        | none =>
347          obtain ⟨u1, f1, l1⟩ := initBad_good hz hU hF
348          exact ⟨_, _, inflateInit2_badbits hz hF hok hza hzf hvn hc hp, u1, f1,
349            Or.inr (Or.inr (Or.inl ⟨rfl, hok, rfl, rfl, l1⟩))⟩
350        | some p =>
351          obtain ⟨wrap, wb⟩ := p
352          obtain ⟨h', hr, he, hG, hO⟩ := inflateInit2_ok hU hF hz hok hza hzf hvn hc hp
353          refine ⟨_, _, hr, hG.uniq, hG.fresh, Or.inr (Or.inr (Or.inr ⟨rfl, rfl, hok, wrap, wb, rfl, he⟩))⟩
354      · obtain ⟨u1, f1, l1⟩ := initMem_good hz hU hF
355        exact ⟨_, _, inflateInit2_memfail hz hF hok hza hzf hvn hc, u1, f1, Or.inr (Or.inl ⟨rfl, hok, rfl, l1⟩)⟩
356    · exact ⟨_, _, by rw [C.run]; exact inflateInit2_version_size _ _ _ _ _ hvn hc hsz, hU, hF,
357        Or.inl ⟨rfl, rfl, Or.inr (Or.inr hsz)⟩⟩
358  · exact ⟨_, _, by rw [C.run]; exact inflateInit2_version_char _ _ _ _ _ c hvn hc hc49, hU, hF,
359      Or.inl ⟨rfl, rfl, Or.inr (Or.inl ⟨c, hc, hc49⟩)⟩⟩
360
361end Zlib.Inflate.Proofs
ZLIB × LEAN

Global contents

READING NOWinflate.c.start.lean