From 1b4788f46967ce0a2de36492668294f30fefcd8d Mon Sep 17 00:00:00 2001 From: Simon Hartcher Date: Tue, 8 Apr 2025 12:49:59 +1000 Subject: [PATCH] fix: undefined behaviour in parseJsonData --- src/aws.zig | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/aws.zig b/src/aws.zig index e776ce3..d0db16e 100644 --- a/src/aws.zig +++ b/src/aws.zig @@ -688,7 +688,6 @@ pub fn Request(comptime request_action: anytype) type { fn ParsedJsonData(comptime T: type) type { return struct { - raw_response_parsed: bool, parsed_response_ptr: *T, allocator: std.mem.Allocator, @@ -697,8 +696,7 @@ pub fn Request(comptime request_action: anytype) type { pub fn deinit(self: MySelf) void { // This feels like it should result in a use after free, but it // seems to be working? - if (self.raw_response_parsed) - self.allocator.destroy(self.parsed_response_ptr); + self.allocator.destroy(self.parsed_response_ptr); } }; } @@ -713,11 +711,13 @@ pub fn Request(comptime request_action: anytype) type { std.mem.eql(u8, key, action.action_name ++ "Response") or std.mem.eql(u8, key, action.action_name ++ "Result") or isOtherNormalResponse(response_types.NormalResponse, key); - var raw_response_parsed = false; var stream = json.TokenStream.init(data); const parsed_response_ptr = blk: { - if (!response_types.isRawPossible or found_normal_json_response) - break :blk &(json.parse(response_types.NormalResponse, &stream, parser_options) catch |e| { + const ptr = try options.client.allocator.create(response_types.NormalResponse); + errdefer options.client.allocator.destroy(ptr); + + if (!response_types.isRawPossible or found_normal_json_response) { + ptr.* = (json.parse(response_types.NormalResponse, &stream, parser_options) catch |e| { log.err( \\Call successful, but unexpected response from service. \\This could be the result of a bug or a stale set of code generated @@ -733,10 +733,10 @@ pub fn Request(comptime request_action: anytype) type { return e; }); + break :blk ptr; + } + log.debug("Appears server has provided a raw response", .{}); - raw_response_parsed = true; - const ptr = try options.client.allocator.create(response_types.NormalResponse); - errdefer options.client.allocator.destroy(ptr); @field(ptr.*, std.meta.fields(action.Response)[0].name) = json.parse(response_types.RawResponse, &stream, parser_options) catch |e| { log.err( @@ -756,8 +756,7 @@ pub fn Request(comptime request_action: anytype) type { break :blk ptr; }; return ParsedJsonData(response_types.NormalResponse){ - .raw_response_parsed = raw_response_parsed, - .parsed_response_ptr = @constCast(parsed_response_ptr), //TODO: why doesn't changing const->var above fix this? + .parsed_response_ptr = parsed_response_ptr, .allocator = options.client.allocator, }; }