aboutsummaryrefslogtreecommitdiff
path: root/tests/programs/capture_long.zc
blob: 52736a4d4cb26e6793fc69f113ee5daa649da940 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
namespace;
include rt, std;

// a capture holds 256 characters and drops the rest. end() must still put its
// 0 inside the buffer, even when the capture was full: the length is 256 and the
// last kept character is the 256th one written (index 255, 'a' + 255 % 26 = 'v').
// a block allocated right after the buffer is checked afterwards: a 0 written one
// word past the buffer would land in its header and read as a bad or freed block.
memdebug on;		// header checks make a write into a neighbouring block visible
fn capture_long() {
	let buf = std.capture.start();
	int* next = rt.new(8);
	int i = 0;
	while (i < 300) { rt.put_c('a' + i % 26); i++; }
	std.capture.end(buf);
	next[0] = 7;				// stops with "bad heap pointer" if its header was overwritten
	rt.put_n(next[0]); rt.put_c(10);		// 7
	return buf;
}
memdebug off;		// the header check only searches 64 words back, so the long buffer is read unchecked
fn main() {
	char* buf = capture_long();
	rt.put_n(rt.len_w(buf)); rt.put_c(10);		// 256
	rt.put_c(buf[255]); rt.put_c(10);		// v
	return 0;
}