1use alloc::string::String;
8use alloc::vec::Vec;
9
10use crate::errors::ParseError;
11use crate::protocol::{request_name, ErrorKind};
12use crate::utils::RawFdContainer;
13use crate::BufWithFds;
14
15#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct X11Error {
18 pub error_kind: ErrorKind,
20 pub error_code: u8,
22 pub sequence: u16,
24 pub bad_value: u32,
26 pub minor_opcode: u16,
28 pub major_opcode: u8,
30 pub extension_name: Option<String>,
32 pub request_name: Option<&'static str>,
34}
35
36impl X11Error {
37 pub fn try_parse(
39 data: &[u8],
40 ext_info_provider: &dyn ExtInfoProvider,
41 ) -> Result<Self, ParseError> {
42 let (response_type, remaining) = u8::try_parse(data)?;
43 let (error_code, remaining) = u8::try_parse(remaining)?;
44 let (sequence, remaining) = u16::try_parse(remaining)?;
45 let (bad_value, remaining) = u32::try_parse(remaining)?;
46 let (minor_opcode, remaining) = u16::try_parse(remaining)?;
47 let (major_opcode, _) = u8::try_parse(remaining)?;
48 if response_type != 0 {
49 Err(ParseError::InvalidValue)
50 } else {
51 let error_kind = ErrorKind::from_wire_error_code(error_code, ext_info_provider);
52 let (extension_name, request_name) =
53 request_name(ext_info_provider, major_opcode, minor_opcode);
54 Ok(X11Error {
55 error_kind,
56 error_code,
57 sequence,
58 bad_value,
59 minor_opcode,
60 major_opcode,
61 extension_name,
62 request_name,
63 })
64 }
65 }
66}
67
68#[cfg(test)]
69mod tryparse_x11error_test {
70 use super::{ErrorKind, ExtInfoProvider, ParseError, X11Error};
71 use crate::x11_utils::ExtensionInformation;
72
73 struct Provider;
74
75 impl ExtInfoProvider for Provider {
76 fn get_from_major_opcode(&self, major_opcode: u8) -> Option<(&str, ExtensionInformation)> {
77 assert_eq!(major_opcode, 10);
78 None
79 }
80 fn get_from_event_code(&self, _event_code: u8) -> Option<(&str, ExtensionInformation)> {
81 unimplemented!()
82 }
83 fn get_from_error_code(&self, _error_code: u8) -> Option<(&str, ExtensionInformation)> {
84 unimplemented!()
85 }
86 }
87
88 #[test]
89 fn try_parse_error() {
90 let input = [
91 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
92 0, 0, 0,
93 ];
94 let error = X11Error::try_parse(&input, &Provider);
95 let expected = X11Error {
96 error_kind: ErrorKind::Request,
97 error_code: 1,
98 sequence: u16::from_ne_bytes([2, 3]),
99 bad_value: u32::from_ne_bytes([4, 5, 6, 7]),
100 minor_opcode: u16::from_ne_bytes([8, 9]),
101 major_opcode: 10,
102 extension_name: None,
103 request_name: Some("UnmapWindow"),
104 };
105 assert_eq!(error, Ok(expected));
106 }
107
108 #[test]
109 fn reject_invalid_response_type() {
110 let result = X11Error::try_parse(&[1; 32], &Provider);
111 assert_eq!(Err(ParseError::InvalidValue), result);
112 }
113}
114
115impl From<&X11Error> for [u8; 32] {
116 fn from(input: &X11Error) -> Self {
117 let sequence_bytes = input.sequence.serialize();
118 let bad_value_bytes = input.bad_value.serialize();
119 let minor_opcode_bytes = input.minor_opcode.serialize();
120 [
121 0,
122 input.error_code,
123 sequence_bytes[0],
124 sequence_bytes[1],
125 bad_value_bytes[0],
126 bad_value_bytes[1],
127 bad_value_bytes[2],
128 bad_value_bytes[3],
129 minor_opcode_bytes[0],
130 minor_opcode_bytes[1],
131 input.major_opcode,
132 0,
133 0,
134 0,
135 0,
136 0,
137 0,
138 0,
139 0,
140 0,
141 0,
142 0,
143 0,
144 0,
145 0,
146 0,
147 0,
148 0,
149 0,
150 0,
151 0,
152 0,
153 ]
154 }
155}
156impl From<X11Error> for [u8; 32] {
157 fn from(input: X11Error) -> Self {
158 Self::from(&input)
159 }
160}
161
162#[cfg(test)]
163mod serialise_x11error_test {
164 use super::{ErrorKind, X11Error};
165
166 #[test]
167 fn test_serialise() {
168 let error = X11Error {
169 error_kind: ErrorKind::Request,
170 error_code: 1,
171 sequence: u16::from_ne_bytes([2, 3]),
172 bad_value: u32::from_ne_bytes([4, 5, 6, 7]),
173 minor_opcode: u16::from_ne_bytes([8, 9]),
174 major_opcode: 10,
175 extension_name: None,
176 request_name: None,
177 };
178 let expected = [
179 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
180 0, 0, 0,
181 ];
182 assert_eq!(expected, <[u8; 32]>::from(error));
183 }
184}
185
186#[derive(Debug, Copy, Clone, PartialEq, Eq)]
188pub struct ExtensionInformation {
189 pub major_opcode: u8,
191 pub first_event: u8,
193 pub first_error: u8,
195}
196
197pub trait ExtInfoProvider {
199 fn get_from_major_opcode(&self, major_opcode: u8) -> Option<(&str, ExtensionInformation)>;
202
203 fn get_from_event_code(&self, event_code: u8) -> Option<(&str, ExtensionInformation)>;
206
207 fn get_from_error_code(&self, error_code: u8) -> Option<(&str, ExtensionInformation)>;
210}
211
212pub trait TryParse: Sized {
214 fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError>;
219}
220
221pub trait TryParseFd: Sized {
223 fn try_parse_fd<'a>(
233 value: &'a [u8],
234 fds: &mut Vec<RawFdContainer>,
235 ) -> Result<(Self, &'a [u8]), ParseError>;
236}
237
238impl<T: TryParse> TryParseFd for T {
239 fn try_parse_fd<'a>(
240 value: &'a [u8],
241 _: &mut Vec<RawFdContainer>,
242 ) -> Result<(Self, &'a [u8]), ParseError> {
243 T::try_parse(value)
244 }
245}
246
247#[derive(Debug, Clone, Copy)]
249pub struct RequestHeader {
250 pub major_opcode: u8,
252 pub minor_opcode: u8,
255 pub remaining_length: u32,
260}
261
262pub trait Request {
264 const EXTENSION_NAME: Option<&'static str>;
266
267 fn serialize(self, extension_opcode: u8) -> BufWithFds<Vec<u8>>;
272}
273
274pub type ReplyParsingFunction =
276 for<'a> fn(
277 &'a [u8],
278 &mut Vec<RawFdContainer>,
279 ) -> Result<(crate::protocol::Reply, &'a [u8]), ParseError>;
280
281pub trait VoidRequest: Request {}
283
284pub trait ReplyRequest: Request {
286 type Reply: Into<crate::protocol::Reply> + TryParse;
288}
289
290pub trait ReplyFDsRequest: Request {
292 type Reply: Into<crate::protocol::Reply> + TryParseFd;
294}
295
296pub trait Serialize {
298 type Bytes;
305
306 fn serialize(&self) -> Self::Bytes;
308
309 fn serialize_into(&self, bytes: &mut Vec<u8>);
314}
315
316macro_rules! implement_try_parse {
319 ($t:ty) => {
320 impl TryParse for $t {
321 fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> {
322 let len = core::mem::size_of::<$t>();
323 let bytes = value
324 .get(..len)
325 .ok_or(ParseError::InsufficientData)?
326 .try_into() .unwrap();
328 Ok((<$t>::from_ne_bytes(bytes), &value[len..]))
329 }
330 }
331 };
332}
333
334macro_rules! implement_serialize {
335 ($t:ty: $size:expr) => {
336 impl Serialize for $t {
337 type Bytes = [u8; $size];
338 fn serialize(&self) -> Self::Bytes {
339 self.to_ne_bytes()
340 }
341 fn serialize_into(&self, bytes: &mut Vec<u8>) {
342 bytes.extend_from_slice(&self.to_ne_bytes());
343 }
344 }
345 };
346}
347
348macro_rules! forward_float {
349 ($from:ty: $to:ty) => {
350 impl TryParse for $from {
351 fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> {
352 let (data, remaining) = <$to>::try_parse(value)?;
353 Ok((<$from>::from_bits(data), remaining))
354 }
355 }
356 impl Serialize for $from {
357 type Bytes = <$to as Serialize>::Bytes;
358 fn serialize(&self) -> Self::Bytes {
359 self.to_bits().serialize()
360 }
361 fn serialize_into(&self, bytes: &mut Vec<u8>) {
362 self.to_bits().serialize_into(bytes);
363 }
364 }
365 };
366}
367
368implement_try_parse!(u8);
369implement_try_parse!(i8);
370implement_try_parse!(u16);
371implement_try_parse!(i16);
372implement_try_parse!(u32);
373implement_try_parse!(i32);
374implement_try_parse!(u64);
375implement_try_parse!(i64);
376
377implement_serialize!(u8: 1);
378implement_serialize!(i8: 1);
379implement_serialize!(u16: 2);
380implement_serialize!(i16: 2);
381implement_serialize!(u32: 4);
382implement_serialize!(i32: 4);
383implement_serialize!(u64: 8);
384implement_serialize!(i64: 8);
385
386forward_float!(f32: u32);
387forward_float!(f64: u64);
388
389#[cfg(test)]
390mod float_tests {
391 use super::{Serialize, TryParse};
392
393 fn test_round_trip<F>(value: F)
394 where
395 F: TryParse + Serialize + PartialEq + core::fmt::Debug + Copy,
396 <F as Serialize>::Bytes: AsRef<[u8]>,
397 {
398 let empty = &[][..];
399
400 assert_eq!(Ok((value, empty)), F::try_parse(value.serialize().as_ref()));
402
403 let mut output = alloc::vec::Vec::new();
405 value.serialize_into(&mut output);
406 assert_eq!(Ok((value, empty)), F::try_parse(&output));
407 }
408
409 #[test]
410 fn test_f32_round_trips() {
411 for &f in &[0f32, 1., std::f32::consts::PI, 42., 1337., 1e7] {
412 test_round_trip(f);
413 test_round_trip(-f);
414 }
415 }
416
417 #[test]
418 fn test_f64_round_trips() {
419 for &f in &[0f64, 1., std::f64::consts::PI, 42., 1337., 1e7] {
420 test_round_trip(f);
421 test_round_trip(-f);
422 }
423 }
424
425 #[test]
426 fn test_parse_known_value() {
427 let bytes = 0x42280000u32.to_ne_bytes();
428 let value = f32::try_parse(&bytes);
429 let empty = &[][..];
430 assert_eq!(Ok((42., empty)), value);
431 }
432
433 #[test]
434 fn test_serialize_known_value() {
435 assert_eq!(0x42280000u32.to_ne_bytes(), 42f32.serialize());
436 }
437}
438
439impl TryParse for bool {
440 fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> {
441 let (data, remaining) = u8::try_parse(value)?;
442 Ok((data != 0, remaining))
443 }
444}
445
446impl Serialize for bool {
447 type Bytes = [u8; 1];
448 fn serialize(&self) -> Self::Bytes {
449 [u8::from(*self)]
450 }
451 fn serialize_into(&self, bytes: &mut Vec<u8>) {
452 bytes.push(u8::from(*self));
453 }
454}
455
456macro_rules! tuple_try_parse {
459 ($($name:ident)*) => {
460 impl<$($name,)*> TryParse for ($($name,)*)
461 where $($name: TryParse,)*
462 {
463 #[allow(non_snake_case)]
464 fn try_parse(remaining: &[u8]) -> Result<(($($name,)*), &[u8]), ParseError> {
465 $(let ($name, remaining) = $name::try_parse(remaining)?;)*
466 Ok((($($name,)*), remaining))
467 }
468 }
469 }
470}
471
472macro_rules! tuple_serialize {
473 ($($name:ident:$idx:tt)*) => {
474 impl<$($name,)*> Serialize for ($($name,)*)
475 where $($name: Serialize,)*
476 {
477 type Bytes = Vec<u8>;
478 fn serialize(&self) -> Self::Bytes {
479 let mut result = Vec::new();
480 self.serialize_into(&mut result);
481 result
482 }
483 fn serialize_into(&self, bytes: &mut Vec<u8>) {
484 $(self.$idx.serialize_into(bytes);)*
485 }
486 }
487 }
488}
489
490macro_rules! tuple_impls {
491 ($($name:ident:$idx:tt)*) => {
492 tuple_try_parse!($($name)*);
493 tuple_serialize!($($name:$idx)*);
494 }
495}
496
497impl Serialize for () {
499 type Bytes = [u8; 0];
500 fn serialize(&self) -> Self::Bytes {
501 []
502 }
503 fn serialize_into(&self, _bytes: &mut Vec<u8>) {}
504}
505
506impl<T: Serialize> Serialize for (T,) {
507 type Bytes = T::Bytes;
508 fn serialize(&self) -> Self::Bytes {
509 self.0.serialize()
510 }
511 fn serialize_into(&self, bytes: &mut Vec<u8>) {
512 self.0.serialize_into(bytes)
513 }
514}
515
516tuple_try_parse!();
517tuple_try_parse!(A);
518tuple_impls!(A:0 B:1);
519tuple_impls!(A:0 B:1 C:2);
520tuple_impls!(A:0 B:1 C:2 D:3);
521tuple_impls!(A:0 B:1 C:2 D:3 E:4);
522tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5);
523tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6);
524tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7);
525tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8);
526tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9);
527tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10);
528tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10 L:11);
529tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10 L:11 M:12);
530tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10 L:11 M:12 N:13);
531tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10 L:11 M:12 N:13 O:14);
532
533pub(crate) fn parse_list<T>(data: &[u8], list_length: usize) -> Result<(Vec<T>, &[u8]), ParseError>
538where
539 T: TryParse,
540{
541 let mut remaining = data;
542 let mut result = Vec::with_capacity(list_length);
543 for _ in 0..list_length {
544 let (entry, new_remaining) = T::try_parse(remaining)?;
545 result.push(entry);
546 remaining = new_remaining;
547 }
548 Ok((result, remaining))
549}
550
551#[inline]
553pub(crate) fn parse_u8_list(data: &[u8], list_length: usize) -> Result<(&[u8], &[u8]), ParseError> {
554 if data.len() < list_length {
555 Err(ParseError::InsufficientData)
556 } else {
557 Ok(data.split_at(list_length))
558 }
559}
560
561#[inline]
563pub(crate) fn parse_u8_array_ref<const N: usize>(
564 data: &[u8],
565) -> Result<(&[u8; N], &[u8]), ParseError> {
566 let (slice, remaining) = parse_u8_list(data, N)?;
567 let slice = slice
568 .try_into()
569 .expect("Cannot fail since slice has expected length");
570 Ok((slice, remaining))
571}
572
573#[inline]
575pub(crate) fn parse_u8_array<const N: usize>(data: &[u8]) -> Result<([u8; N], &[u8]), ParseError> {
576 let (array, remaining) = parse_u8_array_ref(data)?;
577 Ok((*array, remaining))
578}
579
580impl<T: Serialize> Serialize for [T] {
581 type Bytes = Vec<u8>;
582 fn serialize(&self) -> Self::Bytes {
583 let mut result = Vec::new();
584 self.serialize_into(&mut result);
585 result
586 }
587 fn serialize_into(&self, bytes: &mut Vec<u8>) {
588 for item in self {
589 item.serialize_into(bytes);
590 }
591 }
592}
593
594macro_rules! bitmask_binop {
597 ($t:ty, $u:ty) => {
598 impl core::ops::BitOr for $t {
599 type Output = $t;
600 fn bitor(self, other: Self) -> Self::Output {
601 Self::from(<$u>::from(self) | <$u>::from(other))
602 }
603 }
604 impl core::ops::BitOr<$u> for $t {
605 type Output = $t;
606 fn bitor(self, other: $u) -> Self::Output {
607 self | Self::from(other)
608 }
609 }
610 impl core::ops::BitOr<$t> for $u {
611 type Output = $t;
612 fn bitor(self, other: $t) -> Self::Output {
613 <$t>::from(self) | other
614 }
615 }
616 impl core::ops::BitOrAssign for $t {
617 fn bitor_assign(&mut self, other: $t) {
618 *self = *self | Self::from(other)
619 }
620 }
621 impl core::ops::BitOrAssign<$t> for $u {
622 fn bitor_assign(&mut self, other: $t) {
623 *self |= Self::from(other)
624 }
625 }
626 impl core::ops::BitOrAssign<$u> for $t {
627 fn bitor_assign(&mut self, other: $u) {
628 self.0 |= other
629 }
630 }
631 impl core::ops::BitAnd for $t {
632 type Output = $t;
633 fn bitand(self, other: Self) -> Self::Output {
634 Self::from(<$u>::from(self) & <$u>::from(other))
635 }
636 }
637 impl core::ops::BitAnd<$u> for $t {
638 type Output = $t;
639 fn bitand(self, other: $u) -> Self::Output {
640 self & Self::from(other)
641 }
642 }
643 impl core::ops::BitAnd<$t> for $u {
644 type Output = $t;
645 fn bitand(self, other: $t) -> Self::Output {
646 <$t>::from(self) & other
647 }
648 }
649 impl core::ops::BitAndAssign for $t {
650 fn bitand_assign(&mut self, other: $t) {
651 self.0 &= other
652 }
653 }
654 impl core::ops::BitAndAssign<$t> for $u {
655 fn bitand_assign(&mut self, other: $t) {
656 *self &= Self::from(other)
657 }
658 }
659 impl core::ops::BitAndAssign<$u> for $t {
660 fn bitand_assign(&mut self, other: $u) {
661 self.0 &= other
662 }
663 }
664 impl $t {
665 pub fn contains(self, flag: impl Into<$u>) -> bool {
669 let flag = flag.into();
670 (<$u>::from(self) & flag) == flag
671 }
672
673 pub fn intersects(self, flag: impl Into<$u>) -> bool {
677 let flag = flag.into();
678 (<$u>::from(self) & flag) != 0
679 }
680
681 pub fn remove(self, flags: impl Into<$u>) -> Self {
686 Self::from(self.bits() & !flags.into())
687 }
688
689 pub fn bits(self) -> $u {
691 self.0
692 }
693 }
694 };
695}
696
697macro_rules! impl_debug_if_no_extra_traits {
698 ($type:ty, $name:literal) => {
699 #[cfg(not(feature = "extra-traits"))]
700 impl core::fmt::Debug for $type {
701 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
702 f.debug_struct($name).finish_non_exhaustive()
703 }
704 }
705 };
706}
707
708pub(crate) trait TryIntoUSize: TryInto<usize> {
712 fn try_to_usize(self) -> Result<usize, ParseError> {
714 self.try_into().or(Err(ParseError::ConversionFailed))
715 }
716}
717
718impl TryIntoUSize for u8 {}
719impl TryIntoUSize for u16 {}
720impl TryIntoUSize for u32 {}
721impl TryIntoUSize for u64 {}
722impl TryIntoUSize for i8 {}
723impl TryIntoUSize for i16 {}
724impl TryIntoUSize for i32 {}
725impl TryIntoUSize for i64 {}
726
727#[derive(Debug, Clone, Copy, PartialEq, Eq)]
729pub enum BigRequests {
730 Enabled,
732 NotEnabled,
734}
735
736pub fn parse_request_header(
738 input: &[u8],
739 big_requests_enabled: BigRequests,
740) -> Result<(RequestHeader, &[u8]), ParseError> {
741 let (major_opcode, remaining) = u8::try_parse(input)?;
742 let (minor_opcode, remaining) = u8::try_parse(remaining)?;
743 let (length, remaining) = u16::try_parse(remaining)?;
744 let (remaining_length, finally_remaining) = if length == 0 {
745 if big_requests_enabled == BigRequests::NotEnabled {
746 return Err(ParseError::InvalidValue);
747 }
748
749 let (length, remaining) = u32::try_parse(remaining)?;
750 if length < 2 {
751 return Err(ParseError::InvalidValue);
752 }
753 (length - 2, remaining)
755 } else {
756 (u32::from(length) - 1, remaining)
758 };
759 Ok((
760 RequestHeader {
761 major_opcode,
762 minor_opcode,
763 remaining_length,
764 },
765 finally_remaining,
766 ))
767}