Commit 572875e
Fix use-after-free bug in postgres example (14-02.zig) (#127)
The `examples (macos-latest)` CI job was failing in `run exe
examples-14-02` with `ERROR: invalid input syntax for type integer: ""`
because `color_id` held a dangling pointer into a freed `PGresult`
buffer.
## Root cause
`color_id` was extracted via `std.mem.span(c.PQgetvalue(res, 0, 0))`
inside a `blk:` block that also had `defer c.PQclear(res)`. The defer
fires when the block exits — including on `break :blk` — so by the time
`color_id` was used in the inner loop, the `PGresult` buffer it pointed
into was already freed. On macOS, freed memory is zeroed, so `color_id`
read as `""`, and PostgreSQL rejected it as an invalid integer.
## Fix
Remove the `blk:` scope. Execute `PQexecPrepared` for
`insert_cat_colors` directly in the outer `inline for` body and defer
`PQclear(color_res)` there, so `color_id` stays valid for the full
duration of the inner loop.
```zig
// Before: PQclear fires at break :blk, before color_id is used
const color_id = blk: {
const res = c.PQexecPrepared(...);
defer c.PQclear(res); // ← fires here, freeing res's buffer
...
break :blk std.mem.span(c.PQgetvalue(res, 0, 0));
};
// color_id is now a dangling pointer
// After: PQclear deferred to outer loop scope
const color_res = c.PQexecPrepared(...);
defer c.PQclear(color_res); // ← fires at end of inline for iteration
const color_id = std.mem.span(c.PQgetvalue(color_res, 0, 0));
// color_id remains valid through the inner loop
```
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jiacai2050 <dev@liujiacai.net>1 parent eb75a2a commit 572875e
2 files changed
Lines changed: 25 additions & 20 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
28 | 32 | | |
29 | 33 | | |
30 | 34 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | | - | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | 82 | | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
101 | 102 | | |
102 | 103 | | |
103 | 104 | | |
| |||
0 commit comments