M README.md => README.md +2 -2
@@ 41,11 41,11 @@ const x = Bar{
var buf: [12]u8 = undefined;
var fbs = io.fixedBufferStream(&buf);
-try Writer.init().write(x, fbs.outStream());
+try Writer.init().write(x, fbs.writer());
try fbs.seekTo(0);
var r = Reader.init(allocator);
defer r.deinit();
-const y = try r.read(Bar, fbs.inStream());
+const y = try r.read(Bar, fbs.reader());
warn("x: {}\ny: {}\n", .{ x, y });
```
M src/bare.zig => src/bare.zig +6 -3
@@ 185,11 185,14 @@ pub const Reader = struct {
if (comptime !isValidHashMapKeyType(K))
@compileError("unsupported hashmap key type " ++ @typeName(K));
- var i = @intCast(u32, try self.readVarUint(reader));
+ var i = try self.readVarUint(reader);
var map = T.init(&self.arena.allocator);
if (i != 0) {
- try map.ensureCapacity(i);
+ if (std.math.maxInt(T.Size) < i)
+ return ReadError.Overflow;
+
+ try map.ensureCapacity(@intCast(T.Size, i));
while (i != 0) : (i -= 1) {
const key = try self.read(K, reader);
@@ 369,7 372,7 @@ fn isHashMap(comptime T: type) bool {
// `HashMapKeyType` and `HashMapValueType` add further constraints.
const has1 = @hasDecl(T, "iterator") or @hasDecl(T, "items");
const has2 = @hasDecl(T, "putAssumeCapacity") and @hasDecl(T, "ensureCapacity");
- return has1 and has2;
+ return has1 and has2 and @hasDecl(T, "Size");
}
fn HashMapKeyType(comptime T: type) type {
M src/test.zig => src/test.zig +8 -0
@@ 205,6 205,14 @@ test "read map[string]u8" {
expectEqual(map.get("zomg") orelse unreachable, 4);
}
+test "read map overflow" {
+ var r = Reader.init(testing.allocator);
+ defer r.deinit();
+ const T = std.StringHashMap(u8);
+ const map = r.read(T, io.fixedBufferStream("\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x04zomg\x04\x03lol\x02").reader());
+ expectError(error.Overflow, map);
+}
+
test "read map[u8]void" {
try testCompileError(
\\pub fn main() void {