Replace (most) bufPrints with allocPrints, which cannot break for large input sizes

This commit is contained in:
IntegratedQuantum 2025-04-27 22:12:34 +02:00
parent 9181b31a6d
commit c7522483b0
4 changed files with 33 additions and 29 deletions

View File

@ -316,13 +316,13 @@ pub fn readAssets(
fn registerItem(assetFolder: []const u8, id: []const u8, zon: ZonElement) !void {
var split = std.mem.splitScalar(u8, id, ':');
const mod = split.first();
var texturePath: []const u8 = &[0]u8{};
var replacementTexturePath: []const u8 = &[0]u8{};
var buf1: [4096]u8 = undefined;
var buf2: [4096]u8 = undefined;
var texturePath: []const u8 = &.{};
defer main.stackAllocator.free(texturePath);
var replacementTexturePath: []const u8 = &.{};
defer main.stackAllocator.free(replacementTexturePath);
if(zon.get(?[]const u8, "texture", null)) |texture| {
texturePath = try std.fmt.bufPrint(&buf1, "{s}/{s}/items/textures/{s}", .{assetFolder, mod, texture});
replacementTexturePath = try std.fmt.bufPrint(&buf2, "assets/{s}/items/textures/{s}", .{mod, texture});
texturePath = try std.fmt.allocPrint(main.stackAllocator.allocator, "{s}/{s}/items/textures/{s}", .{assetFolder, mod, texture});
replacementTexturePath = try std.fmt.allocPrint(main.stackAllocator.allocator, "assets/{s}/items/textures/{s}", .{mod, texture});
}
_ = items_zig.register(assetFolder, texturePath, replacementTexturePath, id, zon);
}

View File

@ -604,8 +604,8 @@ pub const meshes = struct { // MARK: meshes
var splitter = std.mem.splitScalar(u8, textureId, ':');
const mod = splitter.first();
const id = splitter.rest();
var buffer: [1024]u8 = undefined;
var path = try std.fmt.bufPrint(&buffer, "{s}/{s}/blocks/textures/{s}.png", .{assetFolder, mod, id});
var path = try std.fmt.allocPrint(main.stackAllocator.allocator, "{s}/{s}/blocks/textures/{s}.png", .{assetFolder, mod, id});
defer main.stackAllocator.free(path);
// Test if it's already in the list:
for(textureIDs.items, 0..) |other, j| {
if(std.mem.eql(u8, other, path)) {
@ -617,7 +617,8 @@ pub const meshes = struct { // MARK: meshes
if(err != error.FileNotFound) {
std.log.err("Could not open file {s}: {s}", .{path, @errorName(err)});
}
path = try std.fmt.bufPrint(&buffer, "assets/{s}/blocks/textures/{s}.png", .{mod, id}); // Default to global assets.
main.stackAllocator.free(path);
path = try std.fmt.allocPrint(main.stackAllocator.allocator, "assets/{s}/blocks/textures/{s}.png", .{mod, id}); // Default to global assets.
break :blk std.fs.cwd().openFile(path, .{}) catch |err2| {
std.log.err("File not found. Searched in \"{s}\" and also in the assetFolder \"{s}\"", .{path, assetFolder});
return err2;

View File

@ -100,13 +100,15 @@ pub fn onOpen() void {
const list = VerticalList.init(.{padding, 16 + padding}, 300, 8);
var num: usize = 1;
var buf: [32]u8 = undefined;
while(true) {
var dir = std.fs.cwd().openDir(std.fmt.bufPrint(&buf, "saves/Save{}", .{num}) catch unreachable, .{}) catch break;
const path = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/Save{}", .{num}) catch unreachable;
defer main.stackAllocator.free(path);
var dir = std.fs.cwd().openDir(path, .{}) catch break;
dir.close();
num += 1;
}
const name = std.fmt.bufPrint(&buf, "Save{}", .{num}) catch unreachable;
const name = std.fmt.allocPrint(main.stackAllocator.allocator, "Save{}", .{num}) catch unreachable;
defer main.stackAllocator.free(name);
textInput = TextInput.init(.{0, 0}, 128, 22, name, .{.callback = &createWorld});
list.add(textInput);

View File

@ -500,30 +500,29 @@ pub const ServerWorld = struct { // MARK: ServerWorld
var loadArena = main.heap.NeverFailingArenaAllocator.init(main.stackAllocator);
defer loadArena.deinit();
const arenaAllocator = loadArena.allocator();
var buf: [32768]u8 = undefined;
var generatorSettings: ZonElement = undefined;
if(nullGeneratorSettings) |_generatorSettings| {
generatorSettings = _generatorSettings;
// Store generator settings:
try files.writeZon(try std.fmt.bufPrint(&buf, "saves/{s}/generatorSettings.zig.zon", .{name}), generatorSettings);
try files.writeZon(try std.fmt.allocPrint(arenaAllocator.allocator, "saves/{s}/generatorSettings.zig.zon", .{name}), generatorSettings);
} else { // Read the generator settings:
generatorSettings = try files.readToZon(arenaAllocator, try std.fmt.bufPrint(&buf, "saves/{s}/generatorSettings.zig.zon", .{name}));
generatorSettings = try files.readToZon(arenaAllocator, try std.fmt.allocPrint(arenaAllocator.allocator, "saves/{s}/generatorSettings.zig.zon", .{name}));
}
self.wio = WorldIO.init(try files.openDir(try std.fmt.bufPrint(&buf, "saves/{s}", .{name})), self);
self.wio = WorldIO.init(try files.openDir(try std.fmt.allocPrint(arenaAllocator.allocator, "saves/{s}", .{name})), self);
errdefer self.wio.deinit();
const blockPaletteZon = files.readToZon(arenaAllocator, try std.fmt.bufPrint(&buf, "saves/{s}/palette.zig.zon", .{name})) catch .null;
const blockPaletteZon = files.readToZon(arenaAllocator, try std.fmt.allocPrint(arenaAllocator.allocator, "saves/{s}/palette.zig.zon", .{name})) catch .null;
self.blockPalette = try main.assets.Palette.init(main.globalAllocator, blockPaletteZon, "cubyz:air");
errdefer self.blockPalette.deinit();
std.log.info("Loaded save block palette with {} blocks.", .{self.blockPalette.size()});
const itemPaletteZon = files.readToZon(arenaAllocator, try std.fmt.bufPrint(&buf, "saves/{s}/item_palette.zig.zon", .{name})) catch .null;
const itemPaletteZon = files.readToZon(arenaAllocator, try std.fmt.allocPrint(arenaAllocator.allocator, "saves/{s}/item_palette.zig.zon", .{name})) catch .null;
self.itemPalette = try main.assets.Palette.init(main.globalAllocator, itemPaletteZon, null);
errdefer self.itemPalette.deinit();
std.log.info("Loaded save item palette with {} items.", .{self.itemPalette.size()});
const biomePaletteZon = files.readToZon(arenaAllocator, try std.fmt.bufPrint(&buf, "saves/{s}/biome_palette.zig.zon", .{name})) catch .null;
const biomePaletteZon = files.readToZon(arenaAllocator, try std.fmt.allocPrint(arenaAllocator.allocator, "saves/{s}/biome_palette.zig.zon", .{name})) catch .null;
self.biomePalette = try main.assets.Palette.init(main.globalAllocator, biomePaletteZon, null);
errdefer self.biomePalette.deinit();
std.log.info("Loaded save biome palette with {} biomes.", .{self.biomePalette.size()});
@ -533,18 +532,18 @@ pub const ServerWorld = struct { // MARK: ServerWorld
if(self.wio.hasWorldData()) {
self.seed = try self.wio.loadWorldSeed();
self.generated = true;
try main.assets.loadWorldAssets(try std.fmt.bufPrint(&buf, "saves/{s}/assets/", .{name}), self.blockPalette, self.itemPalette, self.biomePalette);
try main.assets.loadWorldAssets(try std.fmt.allocPrint(arenaAllocator.allocator, "saves/{s}/assets/", .{name}), self.blockPalette, self.itemPalette, self.biomePalette);
} else {
self.seed = main.random.nextInt(u48, &main.seed);
try main.assets.loadWorldAssets(try std.fmt.bufPrint(&buf, "saves/{s}/assets/", .{name}), self.blockPalette, self.itemPalette, self.biomePalette);
try main.assets.loadWorldAssets(try std.fmt.allocPrint(arenaAllocator.allocator, "saves/{s}/assets/", .{name}), self.blockPalette, self.itemPalette, self.biomePalette);
try self.wio.saveWorldData();
}
// Store the block palette now that everything is loaded.
try files.writeZon(try std.fmt.bufPrint(&buf, "saves/{s}/palette.zig.zon", .{name}), self.blockPalette.storeToZon(arenaAllocator));
try files.writeZon(try std.fmt.bufPrint(&buf, "saves/{s}/biome_palette.zig.zon", .{name}), self.biomePalette.storeToZon(arenaAllocator));
try files.writeZon(try std.fmt.bufPrint(&buf, "saves/{s}/item_palette.zig.zon", .{name}), self.itemPalette.storeToZon(arenaAllocator));
try files.writeZon(try std.fmt.allocPrint(arenaAllocator.allocator, "saves/{s}/palette.zig.zon", .{name}), self.blockPalette.storeToZon(arenaAllocator));
try files.writeZon(try std.fmt.allocPrint(arenaAllocator.allocator, "saves/{s}/biome_palette.zig.zon", .{name}), self.biomePalette.storeToZon(arenaAllocator));
try files.writeZon(try std.fmt.allocPrint(arenaAllocator.allocator, "saves/{s}/item_palette.zig.zon", .{name}), self.itemPalette.storeToZon(arenaAllocator));
var gamerules = files.readToZon(arenaAllocator, try std.fmt.bufPrint(&buf, "saves/{s}/gamerules.zig.zon", .{name})) catch ZonElement.initObject(arenaAllocator);
var gamerules = files.readToZon(arenaAllocator, try std.fmt.allocPrint(arenaAllocator.allocator, "saves/{s}/gamerules.zig.zon", .{name})) catch ZonElement.initObject(arenaAllocator);
self.defaultGamemode = std.meta.stringToEnum(main.game.Gamemode, gamerules.get([]const u8, "default_gamemode", "creative")) orelse .creative;
self.allowCheats = gamerules.get(bool, "cheats", true);
@ -821,8 +820,9 @@ pub const ServerWorld = struct { // MARK: ServerWorld
};
}
try self.wio.saveWorldData();
var buf: [32768]u8 = undefined;
const zon = files.readToZon(main.stackAllocator, try std.fmt.bufPrint(&buf, "saves/{s}/items.zig.zon", .{self.name})) catch .null;
const itemsPath = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/{s}/items.zig.zon", .{self.name}) catch unreachable;
defer main.stackAllocator.free(itemsPath);
const zon = files.readToZon(main.stackAllocator, itemsPath) catch .null;
defer zon.deinit(main.stackAllocator);
self.itemDropManager.loadFrom(zon);
}
@ -907,8 +907,9 @@ pub const ServerWorld = struct { // MARK: ServerWorld
const itemDropZon = self.itemDropManager.store(main.stackAllocator);
defer itemDropZon.deinit(main.stackAllocator);
var buf: [32768]u8 = undefined;
try files.writeZon(try std.fmt.bufPrint(&buf, "saves/{s}/items.zig.zon", .{self.name}), itemDropZon);
const itemsPath = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/{s}/items.zig.zon", .{self.name}) catch unreachable;
defer main.stackAllocator.free(itemsPath);
try files.writeZon(itemsPath, itemDropZon);
}
fn isValidSpawnLocation(_: *ServerWorld, wx: i32, wy: i32) bool {