Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dns/src/record/others.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static TYPES: &[(&str, u16)] = &[
("DHCID", 49),
("DLV", 32769),
("DNAME", 39),
("DNSKEEYE", 48),
("DNSKEY", 48),
("DS", 43),
("HIP", 55),
("IPSECKEY", 45),
Expand Down
26 changes: 26 additions & 0 deletions dns/src/record/txt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ impl Wire for TXT {
if next_length < 255 {
break;
}
else if total_length >= stated_length {
// If we've read a chunk with length 255 and we've now consumed
// all the stated bytes, stop here. Don't try to read another
// length byte as we've reached the end of the record.
trace!("Got length 255 and reached stated_length, stopping");
break;
}
else {
trace!("Got length 255, so looping");
}
Expand Down Expand Up @@ -228,4 +235,23 @@ mod test {
assert_eq!(TXT::read(23, &mut Cursor::new(buf)),
Err(WireError::IO));
}

#[test]
fn exact_256_byte_boundary() {
// This reproduces the bug: a TXT record where the character string data
// ends at exactly the stated_length boundary with a 255-byte chunk.
// Before the fix, the code would try to read another length byte after
// the 255-byte chunk, causing an IO error or length mismatch.
let mut buf = vec![0xFF]; // length byte = 255
buf.extend(vec![0x41; 255]); // 255 'A's

// The stated_length is 256 (the exact size of the buffer)
// With the special handling for length=255 (continuation), this creates
// a message with 255 A's (no additional chunk needed)
let result = TXT::read(256, &mut Cursor::new(&buf));
assert!(result.is_ok(), "Should parse successfully at boundary");
let txt = result.unwrap();
assert_eq!(txt.messages.len(), 1);
assert_eq!(txt.messages[0].len(), 255);
}
}