| ... | ... | @@ -593,9 +593,9 @@ var ipc_metadata_len: u16 = 0; |
| 593 | 593 | |
| 594 | 594 | const SavedMetadata = struct { |
| 595 | 595 | ipc_fd: u16, |
| 596 | | main_index: u16, |
| 597 | | start_index: u16, |
| 598 | | nodes_len: u16, |
| 596 | main_index: u8, |
| 597 | start_index: u8, |
| 598 | nodes_len: u8, |
| 599 | 599 | |
| 600 | 600 | fn getIpcFd(metadata: SavedMetadata) posix.fd_t { |
| 601 | 601 | return if (builtin.os.tag == .windows) |
| ... | ... | @@ -677,11 +677,13 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff |
| 677 | 677 | }; |
| 678 | 678 | }; |
| 679 | 679 | |
| 680 | const nodes_len: u8 = @intCast(@min(parents.len - 1, serialized_buffer.storage.len - serialized_len)); |
| 681 | |
| 680 | 682 | // Remember in case the pipe is empty on next update. |
| 681 | 683 | ipc_metadata[ipc_metadata_len] = .{ |
| 682 | 684 | .ipc_fd = SavedMetadata.setIpcFd(fd), |
| 683 | 685 | .start_index = @intCast(serialized_len), |
| 684 | | .nodes_len = @intCast(parents.len), |
| 686 | .nodes_len = nodes_len, |
| 685 | 687 | .main_index = @intCast(main_index), |
| 686 | 688 | }; |
| 687 | 689 | ipc_metadata_len += 1; |
| ... | ... | @@ -690,24 +692,26 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff |
| 690 | 692 | copyRoot(main_storage, &storage[0]); |
| 691 | 693 | |
| 692 | 694 | // Copy the rest of the tree to the end. |
| 693 | | @memcpy(serialized_buffer.storage[serialized_len..][0 .. storage.len - 1], storage[1..]); |
| 695 | @memcpy(serialized_buffer.storage[serialized_len..][0..nodes_len], storage[1..][0..nodes_len]); |
| 694 | 696 | |
| 695 | 697 | // Patch up parent pointers taking into account how the subtree is mounted. |
| 696 | | serialized_buffer.parents[serialized_len] = .none; |
| 697 | | |
| 698 | | for (serialized_buffer.parents[serialized_len..][0 .. parents.len - 1], parents[1..]) |*dest, p| { |
| 698 | for (serialized_buffer.parents[serialized_len..][0..nodes_len], parents[1..][0..nodes_len]) |*dest, p| { |
| 699 | 699 | dest.* = switch (p) { |
| 700 | 700 | // Fix bad data so the rest of the code does not see `unused`. |
| 701 | 701 | .none, .unused => .none, |
| 702 | 702 | // Root node is being mounted here. |
| 703 | 703 | @as(Node.Parent, @enumFromInt(0)) => @enumFromInt(main_index), |
| 704 | 704 | // Other nodes mounted at the end. |
| 705 | | // TODO check for bad data pointing outside the expected range |
| 706 | | _ => |off| @enumFromInt(serialized_len + @intFromEnum(off) - 1), |
| 705 | // Don't trust child data; if the data is outside the expected range, ignore the data. |
| 706 | // This also handles the case when data was truncated. |
| 707 | _ => |off| if (@intFromEnum(off) > nodes_len) |
| 708 | .none |
| 709 | else |
| 710 | @enumFromInt(serialized_len + @intFromEnum(off) - 1), |
| 707 | 711 | }; |
| 708 | 712 | } |
| 709 | 713 | |
| 710 | | serialized_len += storage.len - 1; |
| 714 | serialized_len += nodes_len; |
| 711 | 715 | } |
| 712 | 716 | |
| 713 | 717 | // Save a copy in case any pipes are empty on the next update. |
| ... | ... | @@ -753,7 +757,7 @@ fn useSavedIpcData( |
| 753 | 757 | }; |
| 754 | 758 | |
| 755 | 759 | const start_index = saved_metadata.start_index; |
| 756 | | const nodes_len = saved_metadata.nodes_len; |
| 760 | const nodes_len = @min(saved_metadata.nodes_len, serialized_buffer.storage.len - start_serialized_len); |
| 757 | 761 | const old_main_index = saved_metadata.main_index; |
| 758 | 762 | |
| 759 | 763 | ipc_metadata[ipc_metadata_len] = .{ |
| ... | ... | @@ -764,8 +768,8 @@ fn useSavedIpcData( |
| 764 | 768 | }; |
| 765 | 769 | ipc_metadata_len += 1; |
| 766 | 770 | |
| 767 | | const parents = parents_copy[start_index..][0 .. nodes_len - 1]; |
| 768 | | const storage = storage_copy[start_index..][0 .. nodes_len - 1]; |
| 771 | const parents = parents_copy[start_index..][0..nodes_len]; |
| 772 | const storage = storage_copy[start_index..][0..nodes_len]; |
| 769 | 773 | |
| 770 | 774 | copyRoot(main_storage, &storage_copy[old_main_index]); |
| 771 | 775 | |
| ... | ... | @@ -774,10 +778,15 @@ fn useSavedIpcData( |
| 774 | 778 | for (serialized_buffer.parents[start_serialized_len..][0..parents.len], parents) |*dest, p| { |
| 775 | 779 | dest.* = switch (p) { |
| 776 | 780 | .none, .unused => .none, |
| 777 | | _ => |prev| @enumFromInt(if (@intFromEnum(prev) == old_main_index) |
| 778 | | main_index |
| 779 | | else |
| 780 | | @intFromEnum(prev) - start_index + start_serialized_len), |
| 781 | _ => |prev| d: { |
| 782 | if (@intFromEnum(prev) == old_main_index) { |
| 783 | break :d @enumFromInt(main_index); |
| 784 | } else if (@intFromEnum(prev) > nodes_len) { |
| 785 | break :d .none; |
| 786 | } else { |
| 787 | break :d @enumFromInt(@intFromEnum(prev) - start_index + start_serialized_len); |
| 788 | } |
| 789 | }, |
| 781 | 790 | }; |
| 782 | 791 | } |
| 783 | 792 | |