refactor: tighten name_to_wire per review feedback

- Replace hand-rolled per-byte lowercase loop with stdlib
  [u8]::make_ascii_lowercase(). Shorter and idiomatic.
- Tighten the .expect() message to state the actual invariant
  (parseable DNS name) instead of vague "well-formed" language.
- Replace the doc comment's "see #55" with the real invariant —
  issue numbers rot, and by merge time #55 is closed anyway. The
  comment now explains WHY the lowercase pass has to happen
  post-escape-resolution (\065 → 'A' → 'a') instead of during
  write_qname.
- Drop the redundant `\065` test comment (the one-liner version
  is enough with the assertion showing the transform).

No behavior change; 160 tests still pass, clippy + fmt clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Razvan Dimescu
2026-04-10 00:22:08 +03:00
parent 938317f1d4
commit a8138847f2

View File

@@ -724,14 +724,16 @@ pub fn verify_ds(ds: &DnsRecord, dnskey: &DnsRecord, owner: &str) -> bool {
/// Encode a DNS name in canonical wire form per RFC 4034 §6.2: /// Encode a DNS name in canonical wire form per RFC 4034 §6.2:
/// uncompressed, with all ASCII letters lowercased. /// uncompressed, with all ASCII letters lowercased.
/// ///
/// Delegates label parsing and RFC 1035 §5.1 escape handling to /// Label parsing and RFC 1035 §5.1 escape handling live in
/// `BytePacketBuffer::write_qname`, then post-processes the emitted bytes /// `BytePacketBuffer::write_qname`; this function then walks the emitted
/// to lowercase label bodies (length bytes stay untouched). This keeps /// wire bytes once to lowercase label bodies (length bytes stay untouched).
/// the escape logic in exactly one place — see #55. /// Lowercasing has to happen post-escape-resolution because a decimal
/// escape like `\065` yields `'A'`, which canonical form must convert
/// to `'a'`.
pub fn name_to_wire(name: &str) -> Vec<u8> { pub fn name_to_wire(name: &str) -> Vec<u8> {
let mut buf = BytePacketBuffer::new(); let mut buf = BytePacketBuffer::new();
buf.write_qname(name) buf.write_qname(name)
.expect("DNSSEC canonical form: name must be a well-formed DNS name"); .expect("name_to_wire: input must parse as a valid DNS name");
let mut wire = buf.filled().to_vec(); let mut wire = buf.filled().to_vec();
let mut i = 0; let mut i = 0;
@@ -742,9 +744,7 @@ pub fn name_to_wire(name: &str) -> Vec<u8> {
} }
i += 1; i += 1;
let end = i + label_len; let end = i + label_len;
for b in &mut wire[i..end] { wire[i..end].make_ascii_lowercase();
*b = b.to_ascii_lowercase();
}
i = end; i = end;
} }
@@ -1499,7 +1499,7 @@ mod tests {
#[test] #[test]
fn name_to_wire_decimal_escape_is_lowercased() { fn name_to_wire_decimal_escape_is_lowercased() {
// `\065` is the byte 0x41 ('A'), which canonical form must lowercase to 'a'. // \065 = 'A', must become 'a' in canonical form.
let wire = name_to_wire("\\065bc.com"); let wire = name_to_wire("\\065bc.com");
assert_eq!(wire, vec![3, b'a', b'b', b'c', 3, b'c', b'o', b'm', 0]); assert_eq!(wire, vec![3, b'a', b'b', b'c', 3, b'c', b'o', b'm', 0]);
} }