From 3c47dff96e508d8e908db164a8c1826cf22348a0 Mon Sep 17 00:00:00 2001 From: Bob Farrell Date: Sun, 17 Mar 2024 10:26:10 +0000 Subject: [PATCH] Fix Headers.getFirstValue Bugfix to resolve issue with undefined behaviour when calling `getFirstValue` - first header would always be returned. Add regression test. --- src/jetzig/http/Headers.zig | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/jetzig/http/Headers.zig b/src/jetzig/http/Headers.zig index 864e166..8fbcfd5 100644 --- a/src/jetzig/http/Headers.zig +++ b/src/jetzig/http/Headers.zig @@ -20,10 +20,10 @@ pub fn deinit(self: *Self) void { // Gets the first value for a given header identified by `name`. Case-insensitive string comparison. pub fn getFirstValue(self: *Self, name: []const u8) ?[]const u8 { - for (self.headers.items) |header| { + headers: for (self.headers.items) |header| { if (name.len != header.name.len) continue; for (name, header.name) |expected, actual| { - if (std.ascii.toLower(expected) != std.ascii.toLower(actual)) continue; + if (std.ascii.toLower(expected) != std.ascii.toLower(actual)) continue :headers; } return header.value; } @@ -82,6 +82,15 @@ test "append" { try std.testing.expectEqualStrings(headers.getFirstValue("foo").?, "bar"); } +test "getFirstValue with multiple headers (bugfix regression test)" { + const allocator = std.testing.allocator; + var headers = Self.init(allocator); + defer headers.deinit(); + try headers.append("foo", "bar"); + try headers.append("bar", "baz"); + try std.testing.expectEqualStrings(headers.getFirstValue("bar").?, "baz"); +} + test "case-insensitive matching" { const allocator = std.testing.allocator; var headers = Self.init(allocator);