From 8509b112b84fa8ed44adc5a4843719d643bd6d10 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Sat, 25 Apr 2026 13:22:41 +0800 Subject: [PATCH] Various small fixes Extracted from https://github.com/lightpanda-io/browser/pull/2242 --- .gitignore | 1 + src/browser/Frame.zig | 97 +++++++++++----------- src/browser/StyleManager.zig | 8 +- src/browser/webapi/net/URLSearchParams.zig | 4 +- src/cdp/AXNode.zig | 4 +- src/cdp/Node.zig | 2 +- src/html5ever/lib.rs | 6 +- src/network/Network.zig | 2 +- src/network/cache/FsCache.zig | 1 + 9 files changed, 69 insertions(+), 56 deletions(-) diff --git a/.gitignore b/.gitignore index 66fc22b5..48403d38 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /.zig-cache/ /.lp-cache/ +/zig-pkg/ zig-out lightpanda.id /src/html5ever/target/ diff --git a/src/browser/Frame.zig b/src/browser/Frame.zig index dedb522e..1bea485e 100644 --- a/src/browser/Frame.zig +++ b/src/browser/Frame.zig @@ -1107,7 +1107,7 @@ fn frameDoneCallback(ctx: *anyopaque) !void { const html = try std.mem.concat(parse_arena, u8, &.{ "", + "\">", }); parser.parse(html); self.documentIsComplete(); @@ -1116,7 +1116,7 @@ fn frameDoneCallback(ctx: *anyopaque) !void { self._parse_state = .{ .raw_done = buf.items }; // Use empty an empty HTML document. - parser.parse(""); + parser.parse(""); self.documentIsComplete(); }, .pre => { @@ -1126,7 +1126,7 @@ fn frameDoneCallback(ctx: *anyopaque) !void { self._parse_state = .{ .complete = {} }; // Use empty an empty HTML document. - parser.parse(""); + parser.parse(""); self.documentIsComplete(); }, .err => |err| { @@ -1134,7 +1134,7 @@ fn frameDoneCallback(ctx: *anyopaque) !void { const html = try std.mem.concat(parse_arena, u8, &.{ "

Navigation failed

Reason: ", @errorName(err), - "

", + "

", }); parser.parse(html); @@ -1358,7 +1358,10 @@ pub fn removeElementId(self: *Frame, element: *Element, id: []const u8) void { pub fn removeElementIdWithMaps(self: *Frame, id_maps: ElementIdMaps, id: []const u8) void { if (id_maps.lookup.remove(id)) { - id_maps.removed_ids.put(self.arena, self.dupeString(id) catch return, {}) catch {}; + const owned_id = self.dupeString(id) catch return; + id_maps.removed_ids.put(self.arena, owned_id, {}) catch |err| { + log.warn(.frame, "removeElementIdWithMaps", .{ .err = err }); + }; } } @@ -1698,25 +1701,25 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "b", .{}) catch unreachable, ._tag = .b }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("b"), ._tag = .b }, ), 'i' => return self.createHtmlElementT( Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "i", .{}) catch unreachable, ._tag = .i }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("i"), ._tag = .i }, ), 'q' => return self.createHtmlElementT( Element.Html.Quote, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "q", .{}) catch unreachable, ._tag = .quote }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("q"), ._tag = .quote }, ), 's' => return self.createHtmlElementT( Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "s", .{}) catch unreachable, ._tag = .s }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("s"), ._tag = .s }, ), else => {}, }, @@ -1749,37 +1752,37 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Heading, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "h1", .{}) catch unreachable, ._tag = .h1 }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("h1"), ._tag = .h1 }, ), asUint("h2") => return self.createHtmlElementT( Element.Html.Heading, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "h2", .{}) catch unreachable, ._tag = .h2 }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("h2"), ._tag = .h2 }, ), asUint("h3") => return self.createHtmlElementT( Element.Html.Heading, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "h3", .{}) catch unreachable, ._tag = .h3 }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("h3"), ._tag = .h3 }, ), asUint("h4") => return self.createHtmlElementT( Element.Html.Heading, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "h4", .{}) catch unreachable, ._tag = .h4 }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("h4"), ._tag = .h4 }, ), asUint("h5") => return self.createHtmlElementT( Element.Html.Heading, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "h5", .{}) catch unreachable, ._tag = .h5 }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("h5"), ._tag = .h5 }, ), asUint("h6") => return self.createHtmlElementT( Element.Html.Heading, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "h6", .{}) catch unreachable, ._tag = .h6 }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("h6"), ._tag = .h6 }, ), asUint("hr") => return self.createHtmlElementT( Element.Html.HR, @@ -1791,13 +1794,13 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "em", .{}) catch unreachable, ._tag = .em }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("em"), ._tag = .em }, ), asUint("dd") => return self.createHtmlElementT( Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "dd", .{}) catch unreachable, ._tag = .dd }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("dd"), ._tag = .dd }, ), asUint("dl") => return self.createHtmlElementT( Element.Html.DList, @@ -1809,19 +1812,19 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "dt", .{}) catch unreachable, ._tag = .dt }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("dt"), ._tag = .dt }, ), asUint("td") => return self.createHtmlElementT( Element.Html.TableCell, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "td", .{}) catch unreachable, ._tag = .td }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("td"), ._tag = .td }, ), asUint("th") => return self.createHtmlElementT( Element.Html.TableCell, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "th", .{}) catch unreachable, ._tag = .th }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("th"), ._tag = .th }, ), asUint("tr") => return self.createHtmlElementT( Element.Html.TableRow, @@ -1848,25 +1851,25 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "nav", .{}) catch unreachable, ._tag = .nav }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("nav"), ._tag = .nav }, ), asUint("del") => return self.createHtmlElementT( Element.Html.Mod, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "del", .{}) catch unreachable, ._tag = .del }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("del"), ._tag = .del }, ), asUint("ins") => return self.createHtmlElementT( Element.Html.Mod, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "ins", .{}) catch unreachable, ._tag = .ins }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("ins"), ._tag = .ins }, ), asUint("col") => return self.createHtmlElementT( Element.Html.TableCol, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "col", .{}) catch unreachable, ._tag = .col }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("col"), ._tag = .col }, ), asUint("dir") => return self.createHtmlElementT( Element.Html.Directory, @@ -1890,19 +1893,19 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "sub", .{}) catch unreachable, ._tag = .sub }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("sub"), ._tag = .sub }, ), asUint("sup") => return self.createHtmlElementT( Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "sup", .{}) catch unreachable, ._tag = .sup }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("sup"), ._tag = .sup }, ), asUint("dfn") => return self.createHtmlElementT( Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "dfn", .{}) catch unreachable, ._tag = .dfn }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("dfn"), ._tag = .dfn }, ), else => {}, }, @@ -1959,7 +1962,7 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "main", .{}) catch unreachable, ._tag = .main }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("main"), ._tag = .main }, ), asUint("data") => return self.createHtmlElementT( Element.Html.Data, @@ -1989,7 +1992,7 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "menu", .{}) catch unreachable, ._tag = .menu }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("menu"), ._tag = .menu }, ), asUint("area") => return self.createHtmlElementT( Element.Html.Area, @@ -2007,7 +2010,7 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "code", .{}) catch unreachable, ._tag = .code }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("code"), ._tag = .code }, ), asUint("time") => return self.createHtmlElementT( Element.Html.Time, @@ -2056,7 +2059,7 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "aside", .{}) catch unreachable, ._tag = .aside }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("aside"), ._tag = .aside }, ), asUint("label") => return self.createHtmlElementT( Element.Html.Label, @@ -2086,19 +2089,19 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.TableSection, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "thead", .{}) catch unreachable, ._tag = .thead }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("thead"), ._tag = .thead }, ), asUint("tbody") => return self.createHtmlElementT( Element.Html.TableSection, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "tbody", .{}) catch unreachable, ._tag = .tbody }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("tbody"), ._tag = .tbody }, ), asUint("tfoot") => return self.createHtmlElementT( Element.Html.TableSection, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "tfoot", .{}) catch unreachable, ._tag = .tfoot }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("tfoot"), ._tag = .tfoot }, ), asUint("track") => return self.createHtmlElementT( Element.Html.Track, @@ -2161,19 +2164,19 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "strong", .{}) catch unreachable, ._tag = .strong }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("strong"), ._tag = .strong }, ), asUint("header") => return self.createHtmlElementT( Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "header", .{}) catch unreachable, ._tag = .header }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("header"), ._tag = .header }, ), asUint("footer") => return self.createHtmlElementT( Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "footer", .{}) catch unreachable, ._tag = .footer }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("footer"), ._tag = .footer }, ), asUint("select") => return self.createHtmlElementT( Element.Html.Select, @@ -2197,13 +2200,13 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "figure", .{}) catch unreachable, ._tag = .figure }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("figure"), ._tag = .figure }, ), asUint("hgroup") => return self.createHtmlElementT( Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "hgroup", .{}) catch unreachable, ._tag = .hgroup }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("hgroup"), ._tag = .hgroup }, ), else => {}, }, @@ -2212,13 +2215,13 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "section", .{}) catch unreachable, ._tag = .section }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("section"), ._tag = .section }, ), asUint("article") => return self.createHtmlElementT( Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "article", .{}) catch unreachable, ._tag = .article }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("article"), ._tag = .article }, ), asUint("details") => return self.createHtmlElementT( Element.Html.Details, @@ -2230,7 +2233,7 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "summary", .{}) catch unreachable, ._tag = .summary }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("summary"), ._tag = .summary }, ), asUint("caption") => return self.createHtmlElementT( Element.Html.TableCaption, @@ -2242,13 +2245,13 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "marquee", .{}) catch unreachable, ._tag = .marquee }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("marquee"), ._tag = .marquee }, ), asUint("address") => return self.createHtmlElementT( Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "address", .{}) catch unreachable, ._tag = .address }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("address"), ._tag = .address }, ), asUint("picture") => return self.createHtmlElementT( Element.Html.Picture, @@ -2275,7 +2278,7 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.TableCol, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "colgroup", .{}) catch unreachable, ._tag = .colgroup }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("colgroup"), ._tag = .colgroup }, ), asUint("fieldset") => return self.createHtmlElementT( Element.Html.FieldSet, @@ -2305,7 +2308,7 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Generic, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "noscript", .{}) catch unreachable, ._tag = .noscript }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("noscript"), ._tag = .noscript }, ), else => {}, }, @@ -2314,7 +2317,7 @@ pub fn createElementNS(self: *Frame, namespace: Element.Namespace, name: []const Element.Html.Quote, namespace, attribute_iterator, - .{ ._proto = undefined, ._tag_name = String.init(undefined, "blockquote", .{}) catch unreachable, ._tag = .blockquote }, + .{ ._proto = undefined, ._tag_name = comptime .wrap("blockquote"), ._tag = .blockquote }, ), else => {}, }, diff --git a/src/browser/StyleManager.zig b/src/browser/StyleManager.zig index b6e289c7..d9672e67 100644 --- a/src/browser/StyleManager.zig +++ b/src/browser/StyleManager.zig @@ -219,7 +219,9 @@ pub fn isHidden(self: *StyleManager, el: *Element, cache: ?*VisibilityCache, opt // Store in cache if (cache) |c| { - c.put(self.frame.call_arena, elem, hidden) catch {}; + c.put(self.frame.call_arena, elem, hidden) catch |err| { + log.warn(.browser, "StyleManager cache", .{ .err = err, .src = "isHidden" }); + }; } if (hidden) { @@ -425,7 +427,9 @@ pub fn hasPointerEventsNone(self: *StyleManager, el: *Element, cache: ?*PointerE const pe_none = self.elementHasPointerEventsNone(elem); if (cache) |c| { - c.put(self.frame.call_arena, elem, pe_none) catch {}; + c.put(self.frame.call_arena, elem, pe_none) catch |err| { + log.warn(.browser, "StyleManager cache", .{ .err = err, .src = "hasPointerEventsNone" }); + }; } if (pe_none) { diff --git a/src/browser/webapi/net/URLSearchParams.zig b/src/browser/webapi/net/URLSearchParams.zig index 9762aafc..bd75df46 100644 --- a/src/browser/webapi/net/URLSearchParams.zig +++ b/src/browser/webapi/net/URLSearchParams.zig @@ -203,7 +203,7 @@ fn paramsFromString(allocator: Allocator, input_: []const u8, buf: []u8) !KeyVal value = try unescape(allocator, entry[idx + 1 ..], buf); } else { name = try unescape(allocator, entry, buf); - value = String.init(undefined, "", .{}) catch unreachable; + value = comptime .wrap(""); } // optimized, unescape returns a String directly (Because unescape may @@ -219,7 +219,7 @@ fn paramsFromString(allocator: Allocator, input_: []const u8, buf: []u8) !KeyVal fn unescape(arena: Allocator, value: []const u8, buf: []u8) !String { if (value.len == 0) { - return String.init(undefined, "", .{}); + return comptime .wrap(""); } var has_plus = false; diff --git a/src/cdp/AXNode.zig b/src/cdp/AXNode.zig index f389aea9..5d165c93 100644 --- a/src/cdp/AXNode.zig +++ b/src/cdp/AXNode.zig @@ -232,7 +232,7 @@ pub const Writer = struct { break :blk "relatedElement"; }, .aria_label, .alt, .title, .placeholder, .value => blk: { - // No sure if it's correct for .value case. + // Not sure if it's correct for .value case. try w.objectField("attribute"); try w.write(@tagName(source)); break :blk "attribute"; @@ -1300,7 +1300,7 @@ fn writeString(s: []const u8, w: anytype) !void { fn stripWhitespaces(s: []const u8, writer: anytype) !void { var start: usize = 0; var prev_w: ?bool = null; - var is_w: bool = undefined; + var is_w: bool = false; for (s, 0..) |c, i| { is_w = std.ascii.isWhitespace(c); diff --git a/src/cdp/Node.zig b/src/cdp/Node.zig index 2fbbde95..820318df 100644 --- a/src/cdp/Node.zig +++ b/src/cdp/Node.zig @@ -199,7 +199,7 @@ pub const Search = struct { }; // Need a custom writer, because we can't just serialize the node as-is. -// Sometimes we want to serializ the node without children, sometimes with just +// Sometimes we want to serialize the node without children, sometimes with just // its direct children, and sometimes the entire tree. // (For now, we only support direct children) diff --git a/src/html5ever/lib.rs b/src/html5ever/lib.rs index 9d14e784..63216a1d 100644 --- a/src/html5ever/lib.rs +++ b/src/html5ever/lib.rs @@ -117,7 +117,11 @@ pub extern "C" fn html5ever_parse_document_with_encoding( } let input = unsafe { std::slice::from_raw_parts(html, len) }; - let charset_bytes = unsafe { std::slice::from_raw_parts(charset, charset_len) }; + let charset_bytes = if charset.is_null() { + &[] + } else { + unsafe { std::slice::from_raw_parts(charset, charset_len) } + }; // Decode to UTF-8. Returns Cow - no allocation if already valid UTF-8. let encoding = Encoding::for_label(charset_bytes).unwrap_or(encoding_rs::UTF_8); diff --git a/src/network/Network.zig b/src/network/Network.zig index a3c6d0e5..42756783 100644 --- a/src/network/Network.zig +++ b/src/network/Network.zig @@ -703,7 +703,7 @@ const LineWriter = struct { while (remain.len > 64) { try writer.writeAll(remain[0..64]); try writer.writeByte('\n'); - remain = data[len..]; + remain = remain[64..]; } try writer.writeAll(remain); self.col = col + remain.len; diff --git a/src/network/cache/FsCache.zig b/src/network/cache/FsCache.zig index 4f0b8a8a..c6870a65 100644 --- a/src/network/cache/FsCache.zig +++ b/src/network/cache/FsCache.zig @@ -226,6 +226,7 @@ pub fn put(self: *FsCache, meta: CachedMetadata, body: []const u8) !void { log.err(.cache, "create file", .{ .url = meta.url, .file = &cache_tmp_p, .err = e }); return e; }; + errdefer self.dir.deleteFile(&cache_tmp_p) catch {}; defer file.close(); var writer_buf: [1024]u8 = undefined;