-
-
Notifications
You must be signed in to change notification settings - Fork 73
Open
Description
A double free occurs when trying to add an entry with a duplicate key.
Error is shown by following test:
test "double_free" {
const source =
\\ name: test
\\ jobs:
\\ name:
\\ steps: []
\\ name:
\\ steps: []
;
const gpa = std.testing.allocator;
var yaml_parser: yaml.Yaml = .{ .source = source };
defer yaml_parser.deinit(gpa);
try yaml_parser.load(gpa);
}
Error is:
$ zig build test
test
└─ run test failure
[gpa] (err): Double free detected. Allocation:
/usr/lib/zig/std/mem/Allocator.zig:436:40: 0x1083e8e in dupe__anon_5587 (std.zig)
const new_buf = try allocator.alloc(T, m.len);
^
/home/lepton/projects/zig-yaml/src/Yaml.zig:496:45: 0x10595c7 in fromNode (lib.zig)
const key = try gpa.dupe(u8, tree.rawString(entry.data.key, entry.data.key));
^
/home/lepton/projects/zig-yaml/src/Yaml.zig:447:38: 0x1058423 in fromNode (lib.zig)
return Value.fromNode(gpa, tree, inner);
^
/home/lepton/projects/zig-yaml/src/Yaml.zig:52:41: 0x1050577 in load (lib.zig)
const value = try Value.fromNode(gpa, self.tree.?, node);
^
/home/lepton/projects/demo/src/main.zig:33:25: 0x1050b80 in test.double_free (main.zig)
try yaml_parser.load(gpa);
^
/usr/lib/zig/compiler/test_runner.zig:130:29: 0x11d507e in mainServer (test_runner.zig)
test_fn.func() catch |err| switch (err) {
^
/usr/lib/zig/compiler/test_runner.zig:64:26: 0x11d6336 in main (test_runner.zig)
return mainServer() catch @panic("internal test runner failure");
^
/usr/lib/zig/std/start.zig:618:22: 0x11d011d in posixCallMainAndExit (std.zig)
root.main();
^
/usr/lib/zig/std/start.zig:232:5: 0x11cf9b1 in _start (std.zig)
asm volatile (switch (native_arch) {
^
First free:
/home/lepton/projects/zig-yaml/src/Yaml.zig:497:38: 0x1059e10 in fromNode (lib.zig)
errdefer gpa.free(key);
^
/home/lepton/projects/zig-yaml/src/Yaml.zig:447:38: 0x1058423 in fromNode (lib.zig)
return Value.fromNode(gpa, tree, inner);
^
/home/lepton/projects/zig-yaml/src/Yaml.zig:52:41: 0x1050577 in load (lib.zig)
const value = try Value.fromNode(gpa, self.tree.?, node);
^
/home/lepton/projects/demo/src/main.zig:33:25: 0x1050b80 in test.double_free (main.zig)
try yaml_parser.load(gpa);
^
/usr/lib/zig/compiler/test_runner.zig:130:29: 0x11d507e in mainServer (test_runner.zig)
test_fn.func() catch |err| switch (err) {
^
/usr/lib/zig/compiler/test_runner.zig:64:26: 0x11d6336 in main (test_runner.zig)
return mainServer() catch @panic("internal test runner failure");
^
/usr/lib/zig/std/start.zig:618:22: 0x11d011d in posixCallMainAndExit (std.zig)
root.main();
^
/usr/lib/zig/std/start.zig:232:5: 0x11cf9b1 in _start (std.zig)
asm volatile (switch (native_arch) {
^
Second free:
/home/lepton/projects/zig-yaml/src/Yaml.zig:484:33: 0x105a024 in fromNode (lib.zig)
gpa.free(key);
^
/home/lepton/projects/zig-yaml/src/Yaml.zig:447:38: 0x1058423 in fromNode (lib.zig)
return Value.fromNode(gpa, tree, inner);
^
/home/lepton/projects/zig-yaml/src/Yaml.zig:52:41: 0x1050577 in load (lib.zig)
const value = try Value.fromNode(gpa, self.tree.?, node);
^
/home/lepton/projects/demo/src/main.zig:33:25: 0x1050b80 in test.double_free (main.zig)
try yaml_parser.load(gpa);
^
/usr/lib/zig/compiler/test_runner.zig:130:29: 0x11d507e in mainServer (test_runner.zig)
test_fn.func() catch |err| switch (err) {
^
/usr/lib/zig/compiler/test_runner.zig:64:26: 0x11d6336 in main (test_runner.zig)
return mainServer() catch @panic("internal test runner failure");
^
/usr/lib/zig/std/start.zig:618:22: 0x11d011d in posixCallMainAndExit (std.zig)
root.main();
^
/usr/lib/zig/std/start.zig:232:5: 0x11cf9b1 in _start (std.zig)
asm volatile (switch (native_arch) {
^
thread 338456 panic: switch on corrupt value
/home/lepton/projects/zig-yaml/src/Yaml.zig:500:45: 0x1059cda in fromNode (lib.zig)
if (gop.found_existing) return error.DuplicateMapKey;
^
/home/lepton/projects/zig-yaml/src/Yaml.zig:324:17: 0x10853a6 in deinit (lib.zig)
switch (self.*) {
^
/home/lepton/projects/zig-yaml/src/Yaml.zig:485:37: 0x105a04b in fromNode (lib.zig)
value.deinit(gpa);
^
/home/lepton/projects/zig-yaml/src/Yaml.zig:447:38: 0x1058423 in fromNode (lib.zig)
return Value.fromNode(gpa, tree, inner);
^
/home/lepton/projects/zig-yaml/src/Yaml.zig:52:41: 0x1050577 in load (lib.zig)
const value = try Value.fromNode(gpa, self.tree.?, node);
^
/home/lepton/projects/demo/src/main.zig:33:25: 0x1050b80 in test.double_free (main.zig)
try yaml_parser.load(gpa);
^
/usr/lib/zig/compiler/test_runner.zig:130:29: 0x11d507e in mainServer (test_runner.zig)
test_fn.func() catch |err| switch (err) {
^
/usr/lib/zig/compiler/test_runner.zig:64:26: 0x11d6336 in main (test_runner.zig)
return mainServer() catch @panic("internal test runner failure");
^
/usr/lib/zig/std/start.zig:618:22: 0x11d011d in posixCallMainAndExit (std.zig)
root.main();
^
/usr/lib/zig/std/start.zig:232:5: 0x11cf9b1 in _start (std.zig)
asm volatile (switch (native_arch) {
^
???:?:?: 0x0 in ??? (???)
error: while executing test 'main.test.double_free', the following command terminated with signal 6 (expected exited with code 0):
./.zig-cache/o/e0aaec5b41d88640ff6352b7dc4cb6db/test --cache-dir=./.zig-cache --seed=0xfdf10dcd --listen=-
Build Summary: 1/3 steps succeeded; 1 failed; 1/1 tests passed
test transitive failure
└─ run test failure
error: the following build command failed with exit code 1:
.zig-cache/o/ac9a1f8922d4d3a8fcae40d86754c5f2/build /usr/bin/zig /usr/lib/zig /home/lepton/projects/demo .zig-cache /home/lepton/.cache/zig --seed 0xfdf10dcd -Zd315e20251cfeeba test
It appears to happen because the following errdefer frees the key:
Line 497 in a6c2cd8
| errdefer gpa.free(key); |
Then, when freeing the whole map, it tries to free the already freed key.
It also tries to free the entry value, but there is no value because it returned the DuplicateMapKey error, thus panics.
Lines 482 to 488 in a6c2cd8
| errdefer { | |
| for (out_map.keys(), out_map.values()) |key, *value| { | |
| gpa.free(key); | |
| value.deinit(gpa); | |
| } | |
| out_map.deinit(gpa); | |
| } |
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels