lib/wayland/src/protocol/value/validate.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const decode = @import("decode.zig");
2 const protocol = @import("../root.zig");
3
4 pub fn message(
5 metadata: *const protocol.schema.Message,
6 payload: []const u8,
7 descriptors: []const @import("sys").fd.Descriptor,
8 ) decode.Error!void {
9 var decoder = try decode.Decoder.init(metadata, payload, descriptors);
10 var optional = false;
11 for (metadata.signature) |symbol| switch (symbol) {
12 '0'...'9' => {},
13 '?' => optional = true,
14 'i' => {
15 _ = try decoder.signed();
16 optional = false;
17 },
18 'u' => {
19 _ = try decoder.unsigned();
20 optional = false;
21 },
22 'f' => {
23 _ = try decoder.fixed();
24 optional = false;
25 },
26 's' => {
27 if (optional) {
28 _ = try decoder.optionalString();
29 } else {
30 _ = try decoder.string();
31 }
32 optional = false;
33 },
34 'o' => {
35 if (optional) {
36 _ = try decoder.optionalObject();
37 } else {
38 _ = try decoder.object();
39 }
40 optional = false;
41 },
42 'n' => {
43 _ = try decoder.newId();
44 optional = false;
45 },
46 'a' => {
47 _ = try decoder.array();
48 optional = false;
49 },
50 'h' => {
51 _ = try decoder.descriptor();
52 optional = false;
53 },
54 else => unreachable,
55 };
56 if (optional) unreachable;
57 try decoder.finish();
58 }
59
60 test "generic validation follows expanded scanner signatures" {
61 const std = @import("std");
62 const encode = @import("encode.zig");
63 const bind = &protocol.core.wl_registry.requests.bind;
64 var encoder = try encode.Encoder.init(std.testing.allocator, encode.default_capacity);
65 defer encoder.deinit();
66 try encoder.unsigned(4);
67 try encoder.dynamicNewId("wl_output", 3, try .init(9));
68 const encoded = try encoder.finish(bind);
69 try message(bind, encoded.payload, encoded.descriptors);
70
71 try std.testing.expectError(
72 error.IncompletePayload,
73 message(bind, encoded.payload[0 .. encoded.payload.len - 4], encoded.descriptors),
74 );
75 }
76
77 test "generic validation applies nullable wire modifiers" {
78 const metadata: protocol.schema.Message = .{
79 .name = "nullable",
80 .opcode = 0,
81 .since = 1,
82 .deprecated_since = null,
83 .destructor = false,
84 .signature = "?s?o",
85 .descriptor_count = 0,
86 .minimum_payload_size = 8,
87 .arguments = &.{},
88 };
89 try message(&metadata, &(@as([8]u8, @splat(0))), &.{});
90 }