Hello everyone, I found a great way to crash jetzig servers! When a request like /page?crash is received (empty param, crash can be replaced with any word) and the page tries to parse the params with request.params(), the server crashes.
Reproduce
Put _ = try request.params(); in anywhere in a page
Visit the page with an empty param
Observe the server crash
Intended behaviour
The server doesn't crash and returning an empty string seems to be the intended behaviour, as being able to identify if the param is present might be something that the dev want to know.
Error log
See the crash log here:
```log
thread 1318555 panic: integer overflow
/opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/heap/arena_allocator.zig:165:36: 0x1009efdf3 in createNode (frox.tw)
const len = big_enough_len + big_enough_len / 2;
^
/opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/heap/arena_allocator.zig:205:43: 0x100998733 in alloc (frox.tw)
cur_node = self.createNode(cur_buf.len, n + ptr_align) orelse return null;
^
/opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/mem/Allocator.zig:86:29: 0x1009fe8f3 in allocBytesWithAlignment__anon_14112 (frox.tw)
return self.vtable.alloc(self.ptr, len, ptr_align, ret_addr);
^
/opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/mem/Allocator.zig:211:40: 0x1009b20d3 in allocWithSizeAndAlignment__anon_13288 (frox.tw)
return self.allocBytesWithAlignment(alignment, byte_count, return_address);
^
/opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/mem/Allocator.zig:205:75: 0x100927897 in alloc__anon_9363 (frox.tw)
const ptr: [*]align(a) T = @ptrCast(try self.allocWithSizeAndAlignment(@sizeOf(T), a, n, return_address));
^
/opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/mem/Allocator.zig:319:40: 0x100919c13 in dupe__anon_5046 (frox.tw)
const new_buf = try allocator.alloc(T, m.len);
^
/Users/frox/.cache/zig/p/12202cf05fd4ba2482a9b4b89c632b435310a76ac501b7a3d87dfd41006748dd138d/src/zmpl/Data.zig:276:33: 0x10091fb73 in string (frox.tw)
const duped = allocator.dupe(u8, value) catch @panic("Out of memory");
^
/Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Query.zig:76:54: 0x100941d0b in parse (frox.tw
)
try params.put(item.key, self.data.string(item.value));
^
/Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Request.zig:268:29: 0x100942eb7 in parseQueryS
tring (frox.tw)
try self.query.parse();
^
/Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Request.zig:252:35: 0x10094304f in queryParams
(frox.tw)
if (!try self.parseQueryString()) {
^
/Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Request.zig:247:51: 0x1009436ef in params (fro
x.tw)
.HTML, .UNKNOWN => return self.queryParams(),
^
/Users/frox/Dev/zig/frox.tw/zig-cache/o/58fd3656e1229a9b36ef92df2233e50b/src/app/views/root.zig:14:27: 0x100992a8b in index (frox.tw)
_ = try request.params();
^
/Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/views/Route.zig:83:41: 0x100991ba3 in renderFn (fro
x.tw)
.index => |view| return try view(request, request.response_data),
^
/Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Server.zig:256:21: 0x10097e023 in renderView (
frox.tw)
_ = route.render(route.*, request) catch |err| {
^
/Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Server.zig:153:41: 0x10097f80b in renderHTML (
frox.tw)
const rendered = self.renderView(matched_route, request, template) catch |err| {
^
/Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Server.zig:130:40: 0x100980957 in renderRespon
se (frox.tw)
.UNKNOWN => try self.renderHTML(request, route),
^
/Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Server.zig:98:28: 0x10098bf77 in processNextRe
quest (frox.tw)
try self.renderResponse(&request);
^
/Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Server.zig:73:32: 0x10098d13b in processReques
ts (frox.tw)
self.processNextRequest(allocator, &std_http_server) catch |err| {
^
/Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Server.zig:57:29: 0x10098d763 in listen (frox.
tw)
try self.processRequests();
^
/Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/App.zig:83:18: 0x100990637 in start__anon_5063 (fro
x.tw)
server.listen() catch |err| {
^
/Users/frox/Dev/zig/frox.tw/src/main.zig:23:18: 0x100993adf in main (frox.tw)
try app.start(routes, .{});
^
/opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/start.zig:511:37: 0x100993f87 in main (frox.tw)
const result = root.main() catch |err| {
^
???:?:?: 0x18b69d057 in ??? (???)
???:?:?: 0x39137fffffffffff in ??? (???)
```
Hello everyone, I found a great way to crash jetzig servers! When a request like
/page?crash
is received (empty param, crash can be replaced with any word) and the page tries to parse the params withrequest.params()
, the server crashes.Reproduce
_ = try request.params();
in anywhere in a pageIntended behaviour
The server doesn't crash and returning an empty string seems to be the intended behaviour, as being able to identify if the param is present might be something that the dev want to know.
Error log
See the crash log here:
```log thread 1318555 panic: integer overflow /opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/heap/arena_allocator.zig:165:36: 0x1009efdf3 in createNode (frox.tw) const len = big_enough_len + big_enough_len / 2; ^ /opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/heap/arena_allocator.zig:205:43: 0x100998733 in alloc (frox.tw) cur_node = self.createNode(cur_buf.len, n + ptr_align) orelse return null; ^ /opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/mem/Allocator.zig:86:29: 0x1009fe8f3 in allocBytesWithAlignment__anon_14112 (frox.tw) return self.vtable.alloc(self.ptr, len, ptr_align, ret_addr); ^ /opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/mem/Allocator.zig:211:40: 0x1009b20d3 in allocWithSizeAndAlignment__anon_13288 (frox.tw) return self.allocBytesWithAlignment(alignment, byte_count, return_address); ^ /opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/mem/Allocator.zig:205:75: 0x100927897 in alloc__anon_9363 (frox.tw) const ptr: [*]align(a) T = @ptrCast(try self.allocWithSizeAndAlignment(@sizeOf(T), a, n, return_address)); ^ /opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/mem/Allocator.zig:319:40: 0x100919c13 in dupe__anon_5046 (frox.tw) const new_buf = try allocator.alloc(T, m.len); ^ /Users/frox/.cache/zig/p/12202cf05fd4ba2482a9b4b89c632b435310a76ac501b7a3d87dfd41006748dd138d/src/zmpl/Data.zig:276:33: 0x10091fb73 in string (frox.tw) const duped = allocator.dupe(u8, value) catch @panic("Out of memory"); ^ /Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Query.zig:76:54: 0x100941d0b in parse (frox.tw ) try params.put(item.key, self.data.string(item.value)); ^ /Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Request.zig:268:29: 0x100942eb7 in parseQueryS tring (frox.tw) try self.query.parse(); ^ /Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Request.zig:252:35: 0x10094304f in queryParams (frox.tw) if (!try self.parseQueryString()) { ^ /Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Request.zig:247:51: 0x1009436ef in params (fro x.tw) .HTML, .UNKNOWN => return self.queryParams(), ^ /Users/frox/Dev/zig/frox.tw/zig-cache/o/58fd3656e1229a9b36ef92df2233e50b/src/app/views/root.zig:14:27: 0x100992a8b in index (frox.tw) _ = try request.params(); ^ /Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/views/Route.zig:83:41: 0x100991ba3 in renderFn (fro x.tw) .index => |view| return try view(request, request.response_data), ^ /Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Server.zig:256:21: 0x10097e023 in renderView ( frox.tw) _ = route.render(route.*, request) catch |err| { ^ /Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Server.zig:153:41: 0x10097f80b in renderHTML ( frox.tw) const rendered = self.renderView(matched_route, request, template) catch |err| { ^ /Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Server.zig:130:40: 0x100980957 in renderRespon se (frox.tw) .UNKNOWN => try self.renderHTML(request, route), ^ /Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Server.zig:98:28: 0x10098bf77 in processNextRe quest (frox.tw) try self.renderResponse(&request); ^ /Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Server.zig:73:32: 0x10098d13b in processReques ts (frox.tw) self.processNextRequest(allocator, &std_http_server) catch |err| { ^ /Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/http/Server.zig:57:29: 0x10098d763 in listen (frox. tw) try self.processRequests(); ^ /Users/frox/.cache/zig/p/1220d368ce21549ccd721d5f303888986fff5714835b1f266a62e329f85eabec8f19/src/jetzig/App.zig:83:18: 0x100990637 in start__anon_5063 (fro x.tw) server.listen() catch |err| { ^ /Users/frox/Dev/zig/frox.tw/src/main.zig:23:18: 0x100993adf in main (frox.tw) try app.start(routes, .{}); ^ /opt/homebrew/Cellar/zig-nightly/0.12.0-dev.3522+b88ae8dbd/lib/std/start.zig:511:37: 0x100993f87 in main (frox.tw) const result = root.main() catch |err| { ^ ???:?:?: 0x18b69d057 in ??? (???) ???:?:?: 0x39137fffffffffff in ??? (???) ```