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 }