Skip to content

Commit 52424aa

Browse files
committed
Fix stale CTAPHID test offsets and drop dead descriptor rewriter
1 parent 4f12926 commit 52424aa

2 files changed

Lines changed: 23 additions & 196 deletions

File tree

pc-hid-runner/src/transport/ctaphid_host.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,9 @@ mod tests {
771771

772772
let frames = take_frame_bytes(&mut host);
773773
assert_eq!(frames.len(), 1);
774-
let assigned = u32::from_be_bytes(frames[0][8..12].try_into().unwrap());
774+
// Init response payload: 8-byte nonce echo followed by 4-byte
775+
// assigned channel id; payload starts at frame offset 7.
776+
let assigned = u32::from_be_bytes(frames[0][15..19].try_into().unwrap());
775777
assert_eq!(assigned, 0x1234_5678);
776778
}
777779

@@ -792,7 +794,7 @@ mod tests {
792794

793795
let frames = take_frame_bytes(&mut host);
794796
assert_eq!(frames.len(), 1);
795-
let assigned = u32::from_be_bytes(frames[0][8..12].try_into().unwrap());
797+
let assigned = u32::from_be_bytes(frames[0][15..19].try_into().unwrap());
796798
assert_eq!(assigned, 0xA1A2_A3A4);
797799

798800
let mut reinit_packet = [0u8; 64];
@@ -806,7 +808,7 @@ mod tests {
806808

807809
let frames = take_frame_bytes(&mut host);
808810
assert_eq!(frames.len(), 1);
809-
let reused = u32::from_be_bytes(frames[0][8..12].try_into().unwrap());
811+
let reused = u32::from_be_bytes(frames[0][15..19].try_into().unwrap());
810812
assert_eq!(reused, assigned);
811813

812814
let mut second_broadcast = [0u8; 64];
@@ -820,7 +822,7 @@ mod tests {
820822

821823
let frames = take_frame_bytes(&mut host);
822824
assert_eq!(frames.len(), 1);
823-
let next_cid = u32::from_be_bytes(frames[0][8..12].try_into().unwrap());
825+
let next_cid = u32::from_be_bytes(frames[0][15..19].try_into().unwrap());
824826
assert_eq!(next_cid, 0xDEAD_BEEF);
825827
}
826828

@@ -840,7 +842,7 @@ mod tests {
840842
let _ = host.poll_dispatch(&mut dispatch, &mut apps);
841843
let frames = take_frame_bytes(&mut host);
842844
assert_eq!(frames.len(), 1);
843-
let first_cid = u32::from_be_bytes(frames[0][8..12].try_into().unwrap());
845+
let first_cid = u32::from_be_bytes(frames[0][15..19].try_into().unwrap());
844846
assert_eq!(first_cid, 0x0102_0304);
845847

846848
let mut second_init = [0u8; 64];
@@ -854,7 +856,7 @@ mod tests {
854856

855857
let frames = take_frame_bytes(&mut host);
856858
assert_eq!(frames.len(), 1);
857-
let second_cid = u32::from_be_bytes(frames[0][8..12].try_into().unwrap());
859+
let second_cid = u32::from_be_bytes(frames[0][15..19].try_into().unwrap());
858860
assert_eq!(second_cid, 0x0BAD_F00D);
859861
assert_ne!(first_cid, second_cid);
860862
}
@@ -877,9 +879,15 @@ mod tests {
877879
assert_eq!(frames.len(), 1);
878880
assert_eq!(frames[0][4] & 0x7f, Command::Init.into_u8());
879881
assert_eq!(frames[0][5..7], [0, 17]);
882+
// Init response payload layout:
883+
// [7..15] nonce echo
884+
// [15..19] assigned channel id
885+
// [19] CTAPHID protocol version (2)
886+
// [20..23] device major/minor/build version
887+
// [23] capability flags
880888
assert_eq!(&frames[0][7..15], &[1, 2, 3, 4, 5, 6, 7, 8]);
881-
// Verify CAPABILITY_CBOR | CAPABILITY_NMSG = 0x0C
882-
assert_eq!(frames[0][16], CAPABILITY_CBOR | CAPABILITY_NMSG);
889+
assert_eq!(frames[0][19], 2);
890+
assert_eq!(frames[0][23], CAPABILITY_CBOR | CAPABILITY_NMSG);
883891
}
884892

885893
#[test]

pc-hid-runner/src/uhid.rs

Lines changed: 7 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -386,68 +386,10 @@ fn event_as_bytes(event: &raw::uhid_event) -> &[u8] {
386386
}
387387
}
388388

389-
fn force_ctaphid_report_descriptor(event: &mut raw::uhid_event) {
390-
// Non-mutating validator: we only log; we never rewrite rd_data/rd_size.
391-
if event.type_ != raw::UHID_EVENT_TYPE_CREATE2 {
392-
return;
393-
}
394-
395-
let size = unsafe {
396-
usize::from(core::ptr::read_unaligned(core::ptr::addr_of!(
397-
event.u.create2.rd_size
398-
)))
399-
};
400-
let expected_len = CTAPHID_REPORT_DESCRIPTOR.len();
401-
402-
if size >= expected_len
403-
&& unsafe {
404-
std::slice::from_raw_parts(
405-
core::ptr::addr_of!(event.u.create2.rd_data) as *const u8,
406-
expected_len,
407-
)
408-
} == CTAPHID_REPORT_DESCRIPTOR
409-
{
410-
return;
411-
}
412-
if size == 0 {
413-
log::warn!(
414-
"create2 descriptor length is zero; expected {} bytes. Not mutating.",
415-
expected_len
416-
);
417-
} else if size > raw::HID_MAX_DESCRIPTOR_SIZE {
418-
log::warn!(
419-
"create2 descriptor length {} exceeds HID max {}; not mutating.",
420-
size,
421-
raw::HID_MAX_DESCRIPTOR_SIZE
422-
);
423-
} else {
424-
log::warn!(
425-
"create2 descriptor does not match reference (size={}, expected={}); not mutating.",
426-
size,
427-
expected_len
428-
);
429-
}
430-
}
431-
432389
fn to_io_error(err: nix::Error) -> io::Error {
433390
io::Error::from(err)
434391
}
435392

436-
fn looks_like_ascii_hex(bytes: &[u8]) -> bool {
437-
let mut saw_digit = false;
438-
for &byte in bytes {
439-
if byte.is_ascii_whitespace() {
440-
continue;
441-
}
442-
if byte.is_ascii_hexdigit() {
443-
saw_digit = true;
444-
continue;
445-
}
446-
return saw_digit;
447-
}
448-
saw_digit
449-
}
450-
451393
mod raw {
452394
pub const UHID_DATA_MAX: usize = 4096;
453395
pub const HID_MAX_DESCRIPTOR_SIZE: usize = 4096;
@@ -748,134 +690,11 @@ mod tests {
748690
assert_eq!(descriptor_bytes, &CTAPHID_REPORT_DESCRIPTOR);
749691
}
750692

751-
#[test]
752-
fn write_event_decodes_ascii_descriptor_bytes() {
753-
use nix::unistd::{close, pipe, read};
754-
755-
let mut event = raw::uhid_event::default();
756-
event.type_ = raw::UHID_EVENT_TYPE_CREATE2;
757-
let ascii_descriptor = b"06 d0 f1 09 01 a1 01 09 20 15 00 26 ff 00 75 08 95 40 81 02 09 21 15 00 26 ff 00 75 08 95 40 91 02 c0";
758-
let descriptor_len = ascii_descriptor.len();
759-
let create2 = unsafe { &mut event.u.create2 };
760-
create2.rd_size = descriptor_len as u16;
761-
create2.rd_data[..descriptor_len].copy_from_slice(ascii_descriptor);
762-
763-
let (read_fd, write_fd) = pipe().expect("pipe");
764-
write_event_blocking(write_fd, &mut event).expect("write_event");
765-
close(write_fd).ok();
766-
767-
let create2 = unsafe { &event.u.create2 };
768-
assert_eq!(create2.rd_size as usize, CTAPHID_REPORT_DESCRIPTOR.len());
769-
assert_eq!(
770-
&create2.rd_data[..CTAPHID_REPORT_DESCRIPTOR.len()],
771-
&CTAPHID_REPORT_DESCRIPTOR
772-
);
773-
774-
let mut buffer = [0u8; raw::UHID_EVENT_SIZE];
775-
let mut offset = 0;
776-
while offset < buffer.len() {
777-
let read_bytes = read(read_fd, &mut buffer[offset..]).expect("read");
778-
if read_bytes == 0 {
779-
break;
780-
}
781-
offset += read_bytes;
782-
}
783-
close(read_fd).ok();
784-
assert_eq!(offset, raw::UHID_EVENT_SIZE);
785-
786-
let data_offset = unsafe {
787-
let base = (&event as *const raw::uhid_event).cast::<u8>();
788-
let data = event.u.create2.rd_data.as_ptr();
789-
data.offset_from(base) as usize
790-
};
791-
let descriptor_bytes = &buffer[data_offset..data_offset + CTAPHID_REPORT_DESCRIPTOR.len()];
792-
assert_eq!(descriptor_bytes, &CTAPHID_REPORT_DESCRIPTOR);
793-
}
794-
795-
#[test]
796-
fn write_event_decodes_ascii_descriptor_with_suffix() {
797-
use nix::unistd::{close, pipe, read};
798-
799-
let mut event = raw::uhid_event::default();
800-
event.type_ = raw::UHID_EVENT_TYPE_CREATE2;
801-
let ascii_descriptor = b"06 d0 f1 09 01 a1 01 09 20 15 00 26 ff 00 75 08 95 40 81 02 09 21 15 00 26 ff 00 75 08 95 40 91 02 c0\n INPUT[INPUT]\n";
802-
let descriptor_len = ascii_descriptor.len();
803-
let create2 = unsafe { &mut event.u.create2 };
804-
create2.rd_size = descriptor_len as u16;
805-
create2.rd_data[..descriptor_len].copy_from_slice(ascii_descriptor);
806-
807-
let (read_fd, write_fd) = pipe().expect("pipe");
808-
write_event_blocking(write_fd, &mut event).expect("write_event");
809-
close(write_fd).ok();
810-
811-
let create2 = unsafe { &event.u.create2 };
812-
assert_eq!(create2.rd_size as usize, CTAPHID_REPORT_DESCRIPTOR.len());
813-
assert_eq!(
814-
&create2.rd_data[..CTAPHID_REPORT_DESCRIPTOR.len()],
815-
&CTAPHID_REPORT_DESCRIPTOR
816-
);
817-
818-
let mut buffer = [0u8; raw::UHID_EVENT_SIZE];
819-
let mut offset = 0;
820-
while offset < buffer.len() {
821-
let read_bytes = read(read_fd, &mut buffer[offset..]).expect("read");
822-
if read_bytes == 0 {
823-
break;
824-
}
825-
offset += read_bytes;
826-
}
827-
close(read_fd).ok();
828-
assert_eq!(offset, raw::UHID_EVENT_SIZE);
829-
830-
let data_offset = unsafe {
831-
let base = (&event as *const raw::uhid_event).cast::<u8>();
832-
let data = event.u.create2.rd_data.as_ptr();
833-
data.offset_from(base) as usize
834-
};
835-
let descriptor_bytes = &buffer[data_offset..data_offset + CTAPHID_REPORT_DESCRIPTOR.len()];
836-
assert_eq!(descriptor_bytes, &CTAPHID_REPORT_DESCRIPTOR);
837-
}
838-
839-
#[test]
840-
fn write_event_overrides_incorrect_binary_descriptor() {
841-
use nix::unistd::{close, pipe, read};
842-
843-
let mut event = raw::uhid_event::default();
844-
event.type_ = raw::UHID_EVENT_TYPE_CREATE2;
845-
let bogus_descriptor = [0xAAu8; CTAPHID_REPORT_DESCRIPTOR.len()];
846-
let create2 = unsafe { &mut event.u.create2 };
847-
create2.rd_size = bogus_descriptor.len() as u16;
848-
create2.rd_data[..bogus_descriptor.len()].copy_from_slice(&bogus_descriptor);
849-
850-
let (read_fd, write_fd) = pipe().expect("pipe");
851-
write_event_blocking(write_fd, &mut event).expect("write_event");
852-
close(write_fd).ok();
853-
854-
let create2 = unsafe { &event.u.create2 };
855-
assert_eq!(create2.rd_size as usize, CTAPHID_REPORT_DESCRIPTOR.len());
856-
assert_eq!(
857-
&create2.rd_data[..CTAPHID_REPORT_DESCRIPTOR.len()],
858-
&CTAPHID_REPORT_DESCRIPTOR
859-
);
860-
861-
let mut buffer = [0u8; raw::UHID_EVENT_SIZE];
862-
let mut offset = 0;
863-
while offset < buffer.len() {
864-
let read_bytes = read(read_fd, &mut buffer[offset..]).expect("read");
865-
if read_bytes == 0 {
866-
break;
867-
}
868-
offset += read_bytes;
869-
}
870-
close(read_fd).ok();
871-
assert_eq!(offset, raw::UHID_EVENT_SIZE);
872-
873-
let data_offset = unsafe {
874-
let base = (&event as *const raw::uhid_event).cast::<u8>();
875-
let data = event.u.create2.rd_data.as_ptr();
876-
data.offset_from(base) as usize
877-
};
878-
let descriptor_bytes = &buffer[data_offset..data_offset + CTAPHID_REPORT_DESCRIPTOR.len()];
879-
assert_eq!(descriptor_bytes, &CTAPHID_REPORT_DESCRIPTOR);
880-
}
693+
// NOTE: previous versions of this file contained tests for an in-place
694+
// descriptor rewriter (`force_ctaphid_report_descriptor`). That helper
695+
// was never wired into the production write path, so the tests asserted
696+
// behaviour the code never performed. They are intentionally removed
697+
// here; `descriptor_bytes_are_copied_verbatim` and
698+
// `write_event_sends_raw_descriptor_bytes` above cover the actual
699+
// serialization contract.
881700
}

0 commit comments

Comments
 (0)