aboutsummaryrefslogtreecommitdiff
path: root/tests/programs/capture_long.zc
diff options
context:
space:
mode:
Diffstat (limited to 'tests/programs/capture_long.zc')
-rw-r--r--tests/programs/capture_long.zc26
1 files changed, 26 insertions, 0 deletions
diff --git a/tests/programs/capture_long.zc b/tests/programs/capture_long.zc
new file mode 100644
index 0000000..52736a4
--- /dev/null
+++ b/tests/programs/capture_long.zc
@@ -0,0 +1,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;
+}