Skip to content

Commit bbb1500

Browse files
Merge branch 'main' into claude/pin-toolchain-clippy
2 parents e122c48 + 2204e1d commit bbb1500

7 files changed

Lines changed: 436 additions & 18 deletions

File tree

docs/proofs/verification/AUDIT.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,13 @@ treatment as the Lean file.
185185
- Coq models floats as ```value_eq_dec` is fully decidable (`Req_EM_T`),
186186
at the cost of the classical-reals axioms above. (Lean models `Float` as
187187
opaque IEEE and decides equality classically via `by_cases`.)
188-
- Coq is **behind on binops**: only `add`/`eq`/`and` have rules — none of
189-
`sub/mul/div/mod` or the comparisons/`or` the Lean file now has.
188+
- Coq is now **at parity on integer binops** (landed 2026-06-15): on top of
189+
`add`/`eq`/`and` it gains `or`, `sub`, `mul`, `div`/`mod` (which panic to
190+
`VOops` on a zero divisor, mirroring the proven unwrap-of-oops fragment) and
191+
the comparisons `lt`/`gt`/`le`/`ge` (`Z``bool`) — each with a `has_type`
192+
rule, a `step` rule, and full `progress`/`preservation` coverage, axiom-free.
193+
Float arithmetic variants remain unmodelled on both sides, and `BNeq` is a
194+
symmetric gap (neither Lean nor Coq has it).
190195

191196
- **`cap_subsumes` bug fixed.** Its catch-all was `TODO: false`, so the relation
192197
was **not even reflexive** (`cap_subsumes CapProcess CapProcess = false`).
@@ -199,7 +204,10 @@ treatment as the Lean file.
199204
large brute-force `try solve [...]` pile ending in a literal *"Nuclear
200205
option"* — it compiles and is axiom-honest, but is fragile and unreviewable.
201206
A clean per-case rewrite (in the style of the Lean `preservation`) is worth
202-
doing. Also: bring the Coq binops up to parity with the extended Lean set.
207+
doing — the binop-parity work (2026-06-15) extended its `first [...]`
208+
reconstruction block and added an early literal-result closer rather than
209+
rewriting it. (That cascade also scales badly: the new ops had to be closed
210+
early and deterministically to avoid a multi-minute typecheck.)
203211

204212
## Status
205213

docs/proofs/verification/WokeLang.v

Lines changed: 334 additions & 0 deletions
Large diffs are not rendered by default.

src/main.rs

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,13 @@ fn main() -> Result<()> {
151151
}
152152

153153
fn run_program(file: &PathBuf) -> Result<()> {
154-
let source = fs::read_to_string(file).expect("Failed to read file");
154+
let source = {
155+
use std::io::Read;
156+
let mut file_handle = std::fs::File::open(file).expect("Failed to open file");
157+
let mut buf = String::new();
158+
file_handle.take(10 * 1024 * 1024).read_to_string(&mut buf).expect("Failed to read file");
159+
buf
160+
};
155161
let lexer = Lexer::new(&source);
156162

157163
let tokens = match lexer.tokenize() {
@@ -189,7 +195,13 @@ fn run_program(file: &PathBuf) -> Result<()> {
189195
}
190196

191197
fn compile_program(file: &PathBuf, _output: Option<PathBuf>) -> Result<()> {
192-
let source = fs::read_to_string(file).expect("Failed to read file");
198+
let source = {
199+
use std::io::Read;
200+
let mut file_handle = std::fs::File::open(file).expect("Failed to open file");
201+
let mut buf = String::new();
202+
file_handle.take(10 * 1024 * 1024).read_to_string(&mut buf).expect("Failed to read file");
203+
buf
204+
};
193205
let lexer = Lexer::new(&source);
194206

195207
let tokens = match lexer.tokenize() {
@@ -245,7 +257,13 @@ fn compile_program(file: &PathBuf, _output: Option<PathBuf>) -> Result<()> {
245257
}
246258

247259
fn run_vm(file: &PathBuf) -> Result<()> {
248-
let source = fs::read_to_string(file).expect("Failed to read file");
260+
let source = {
261+
use std::io::Read;
262+
let mut file_handle = std::fs::File::open(file).expect("Failed to open file");
263+
let mut buf = String::new();
264+
file_handle.take(10 * 1024 * 1024).read_to_string(&mut buf).expect("Failed to read file");
265+
buf
266+
};
249267

250268
// Use the vm::run_vm helper which compiles and runs
251269
match wokelang::vm::run_vm(&source) {
@@ -261,7 +279,13 @@ fn run_vm(file: &PathBuf) -> Result<()> {
261279
}
262280

263281
fn disassemble(file: &PathBuf) -> Result<()> {
264-
let source = fs::read_to_string(file).expect("Failed to read file");
282+
let source = {
283+
use std::io::Read;
284+
let mut file_handle = std::fs::File::open(file).expect("Failed to open file");
285+
let mut buf = String::new();
286+
file_handle.take(10 * 1024 * 1024).read_to_string(&mut buf).expect("Failed to read file");
287+
buf
288+
};
265289

266290
// Compile to bytecode
267291
let compiled = match wokelang::vm::compile(&source) {
@@ -280,7 +304,13 @@ fn disassemble(file: &PathBuf) -> Result<()> {
280304
}
281305

282306
fn typecheck_program(file: &PathBuf) -> Result<()> {
283-
let source = fs::read_to_string(file).expect("Failed to read file");
307+
let source = {
308+
use std::io::Read;
309+
let mut file_handle = std::fs::File::open(file).expect("Failed to open file");
310+
let mut buf = String::new();
311+
file_handle.take(10 * 1024 * 1024).read_to_string(&mut buf).expect("Failed to read file");
312+
buf
313+
};
284314
let lexer = Lexer::new(&source);
285315

286316
let tokens = match lexer.tokenize() {
@@ -314,7 +344,13 @@ fn typecheck_program(file: &PathBuf) -> Result<()> {
314344
}
315345

316346
fn lint_program(file: &PathBuf) -> Result<()> {
317-
let source = fs::read_to_string(file).expect("Failed to read file");
347+
let source = {
348+
use std::io::Read;
349+
let mut file_handle = std::fs::File::open(file).expect("Failed to open file");
350+
let mut buf = String::new();
351+
file_handle.take(10 * 1024 * 1024).read_to_string(&mut buf).expect("Failed to read file");
352+
buf
353+
};
318354
let lexer = Lexer::new(&source);
319355

320356
let tokens = match lexer.tokenize() {
@@ -355,7 +391,13 @@ fn lint_program(file: &PathBuf) -> Result<()> {
355391
}
356392

357393
fn tokenize_file(file: &PathBuf) -> Result<()> {
358-
let source = fs::read_to_string(file).expect("Failed to read file");
394+
let source = {
395+
use std::io::Read;
396+
let mut file_handle = std::fs::File::open(file).expect("Failed to open file");
397+
let mut buf = String::new();
398+
file_handle.take(10 * 1024 * 1024).read_to_string(&mut buf).expect("Failed to read file");
399+
buf
400+
};
359401
let lexer = Lexer::new(&source);
360402

361403
let tokens = match lexer.tokenize() {
@@ -381,7 +423,13 @@ fn tokenize_file(file: &PathBuf) -> Result<()> {
381423
/// - `sexpr` / `sexp`: S-expression representation
382424
/// - `json`: JSON serialization via serde_json
383425
fn parse_file(file: &PathBuf, format: &str) -> Result<()> {
384-
let source = fs::read_to_string(file).expect("Failed to read file");
426+
let source = {
427+
use std::io::Read;
428+
let mut file_handle = std::fs::File::open(file).expect("Failed to open file");
429+
let mut buf = String::new();
430+
file_handle.take(10 * 1024 * 1024).read_to_string(&mut buf).expect("Failed to read file");
431+
buf
432+
};
385433
let lexer = Lexer::new(&source);
386434

387435
let tokens = match lexer.tokenize() {

src/modules.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,15 @@ impl ModuleLoader {
138138
self.loading.insert(path.clone());
139139

140140
// Load and parse the file
141-
let source = fs::read_to_string(&path)
142-
.map_err(|e| ModuleError::IoError(format!("Failed to read {}: {}", path.display(), e)))?;
141+
let source = {
142+
use std::io::Read;
143+
let mut file = std::fs::File::open(&path)
144+
.map_err(|e| ModuleError::IoError(format!("Failed to open {}: {}", path.display(), e)))?;
145+
let mut buf = String::new();
146+
file.take(5 * 1024 * 1024).read_to_string(&mut buf)
147+
.map_err(|e| ModuleError::IoError(format!("Failed to read {}: {}", path.display(), e)))?;
148+
buf
149+
};
143150

144151
let lexer = Lexer::new(&source);
145152
let tokens = lexer
@@ -186,8 +193,15 @@ impl ModuleLoader {
186193
}
187194

188195
// Load and parse
189-
let source = fs::read_to_string(&path)
190-
.map_err(|e| ModuleError::IoError(format!("Failed to read {}: {}", path.display(), e)))?;
196+
let source = {
197+
use std::io::Read;
198+
let mut file = std::fs::File::open(&path)
199+
.map_err(|e| ModuleError::IoError(format!("Failed to open {}: {}", path.display(), e)))?;
200+
let mut buf = String::new();
201+
file.take(5 * 1024 * 1024).read_to_string(&mut buf)
202+
.map_err(|e| ModuleError::IoError(format!("Failed to read {}: {}", path.display(), e)))?;
203+
buf
204+
};
191205

192206
let lexer = Lexer::new(&source);
193207
let tokens = lexer

src/security/consent.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,13 @@ impl ConsentStore {
9999
return Ok(());
100100
}
101101

102-
let content = fs::read_to_string(&self.path)?;
102+
let content = {
103+
use std::io::Read;
104+
let mut file = std::fs::File::open(&self.path)?;
105+
let mut buf = String::new();
106+
file.take(1024 * 1024).read_to_string(&mut buf)?;
107+
buf
108+
};
103109

104110
for line in content.lines() {
105111
if line.trim().is_empty() || line.starts_with('#') {

src/stdlib/io.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,14 @@ pub fn read_file(args: &[Value], caps: &mut CapabilityRegistry) -> Result<Value,
9595
// Check file size to prevent memory exhaustion
9696
check_file_size(&validated_path)?;
9797

98-
match fs::read_to_string(&validated_path) {
98+
match {
99+
use std::io::Read;
100+
std::fs::File::open(&validated_path).and_then(|mut f| {
101+
let mut buf = String::new();
102+
f.take(10 * 1024 * 1024).read_to_string(&mut buf)?;
103+
Ok(buf)
104+
})
105+
} {
99106
Ok(contents) => Ok(Value::String(contents)),
100107
Err(e) => Err(StdlibError::IoError(e.to_string())),
101108
}

src/stdlib/net.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,9 +364,10 @@ fn http_request_binary_with_body(
364364
.map_err(|e| StdlibError::NetworkError(format!("Read body failed: {}", e)))?;
365365
buf
366366
} else {
367-
// Read until connection closes
367+
// Read until connection closes (limit to 5MB)
368368
let mut buf = Vec::new();
369369
reader
370+
.take(5 * 1024 * 1024)
370371
.read_to_end(&mut buf)
371372
.map_err(|e| StdlibError::NetworkError(format!("Read body failed: {}", e)))?;
372373
buf

0 commit comments

Comments
 (0)