#std.json.parseFromSlice returns SyntaxError

1 messages · Page 1 of 1 (latest)

outer stirrup
#

hey guys
i have a buffer with a set size - 32k
i fetch json via http of unknown length into this buffer
i print contents of this buffer and its valid json without any noise after the last closing }
i pasted that json into json validators that dont support jsonc or json5 eg no trailing commas or comments and they confirmed that json is valid
but i do std.json.parseFromSlice with that buffer and i get error: SyntaxError
i dont even know where i should be looking to trace the problem

pub fn getMod(allocator: std.mem.Allocator, slug: []const u8, loader: []const u8, gameVersion: []const u8) !void {
    _ = loader;
    _ = gameVersion;

    const url: [:0]u8 = try std.fmt.allocPrintSentinel(allocator, "https://api.modrinth.com/v2/project/{s}", .{slug}, 0);
    defer allocator.free(url);

    var buffer: [1024 * 32]u8 = undefined;
    const status = try client.fetch(url, &buffer);

    const parsed = try std.json.parseFromSlice(ModrinthProject, allocator, &buffer, .{ .ignore_unknown_fields = true });
    defer parsed.deinit();

    std.debug.print("Status code: {d}\nProject type: {s}\n", .{ status, parsed.value.project_type });
}
pub fn fetch(url: [:0]const u8, buffer: []u8) !i32 {
    var writer = std.Io.Writer.fixed(buffer);
    const response = try client.fetch(url, .{ .writer = &writer });
    return response.status_code;
}

i also tried initializing the response buffer with std.mem.zeroes but it changed nothing.

simple prawn
#

You should pass writer to the fetch function instead, and get the written part with writer.buffered()

outer stirrup
#

let me see if this helps. but i printed contents of a buffer directly just fine

simple prawn
#

That's probably because your terminal won't print some characters

#

(and stops printing at null byte)

outer stirrup
#

yeah i was wondering if libcurl writes as a null terminated string and that was breaking the parser

outer stirrup
outer stirrup
#

maybe std.json could use a parseFromSlizeZ method

simple prawn
#

No the real problem here is that you are passing your whole buffer which has bunch of undefined (unwritten) bytes

#

writer.buffered() gets the part that was written by the client.fetch

outer stirrup
#

when i init with std.mem.zeroes

simple prawn
#

no, undefined is 0xAA on safe modes and whatever on unsafe

#

if you init to zeroes, then you can get slice to the first zero with std.mem.sliceTo but you really shouldn't do that here