[PR #2948] [MERGED] Handle byte-order mark when reading hosts file #3440

Closed
opened 2026-03-16 11:43:54 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/hickory-dns/hickory-dns/pull/2948
Author: @mat-1
Created: 4/25/2025
Status: Merged
Merged: 4/28/2025
Merged by: @djc

Base: mainHead: main


📝 Commits (3)

  • 7bc70bf handle byte-order mark
  • a967dfe don't unnecessarily clone line when bom is present
  • 12c5fda remove unnecessary reference

📊 Changes

1 file changed (+12 additions, -3 deletions)

View changed files

📝 crates/resolver/src/hosts.rs (+12 -3)

📄 Description

A user for one of my crates was getting this warning from hickory-resolver:

WARN hickory_resolver::hosts: could not parse an IP from hosts file ("\u{feff}")

Upon investigation, we found that their hosts file at C:\Windows\System32\Drivers\etc\hosts began with that codepoint (a byte order mark). We don't know exactly how it showed up, but apparently some text editors insert it when writing files. Additionally, it never caused issues for this user before because most programs strip it when reading files, but Rust doesn't.

You should be able to reproduce their issue on Windows by running the following code:

use std::{fs::read_to_string, path::Path};
use hickory_resolver::Resolver;

#[tokio::main]
async fn main() {
    let system_root =
        std::env::var_os("SystemRoot").expect("Environment variable SystemRoot not found");
    let system_root = Path::new(&system_root);
    let hosts_path = system_root.join("System32\\drivers\\etc\\hosts");
    let hosts = read_to_string(&hosts_path).unwrap();
    println!("{hosts:?}");
    let hosts = format!("\u{FEFF}{hosts}");
    std::fs::write(hosts_path, hosts).unwrap();

    let resolver = Resolver::builder_tokio().unwrap().build();
    let response = resolver.lookup_ip("www.example.com.").await.unwrap();
    println!("{response:?}");
}

This PR solves the problem by updating the logic for reading the hosts file to correctly strip the byte-order mark codepoint. The user has confirmed with me that my fix does resolve the issue.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/hickory-dns/hickory-dns/pull/2948 **Author:** [@mat-1](https://github.com/mat-1) **Created:** 4/25/2025 **Status:** ✅ Merged **Merged:** 4/28/2025 **Merged by:** [@djc](https://github.com/djc) **Base:** `main` ← **Head:** `main` --- ### 📝 Commits (3) - [`7bc70bf`](https://github.com/hickory-dns/hickory-dns/commit/7bc70bf945cf41bb99e725c6536557f9a595d9f9) handle byte-order mark - [`a967dfe`](https://github.com/hickory-dns/hickory-dns/commit/a967dfefe559b421037d7a07602389ec3776a9a2) don't unnecessarily clone line when bom is present - [`12c5fda`](https://github.com/hickory-dns/hickory-dns/commit/12c5fdaa16060783afa1aedda96365377c74de17) remove unnecessary reference ### 📊 Changes **1 file changed** (+12 additions, -3 deletions) <details> <summary>View changed files</summary> 📝 `crates/resolver/src/hosts.rs` (+12 -3) </details> ### 📄 Description A user for one of my crates was getting this warning from hickory-resolver: ```rs WARN hickory_resolver::hosts: could not parse an IP from hosts file ("\u{feff}") ``` Upon investigation, we found that their hosts file at `C:\Windows\System32\Drivers\etc\hosts` began with that codepoint (a byte order mark). We don't know exactly how it showed up, but apparently some text editors insert it when writing files. Additionally, it never caused issues for this user before because most programs strip it when reading files, but Rust doesn't. You should be able to reproduce their issue on Windows by running the following code: ```rs use std::{fs::read_to_string, path::Path}; use hickory_resolver::Resolver; #[tokio::main] async fn main() { let system_root = std::env::var_os("SystemRoot").expect("Environment variable SystemRoot not found"); let system_root = Path::new(&system_root); let hosts_path = system_root.join("System32\\drivers\\etc\\hosts"); let hosts = read_to_string(&hosts_path).unwrap(); println!("{hosts:?}"); let hosts = format!("\u{FEFF}{hosts}"); std::fs::write(hosts_path, hosts).unwrap(); let resolver = Resolver::builder_tokio().unwrap().build(); let response = resolver.lookup_ip("www.example.com.").await.unwrap(); println!("{response:?}"); } ``` This PR solves the problem by updating the logic for reading the hosts file to correctly strip the byte-order mark codepoint. The user has confirmed with me that my fix does resolve the issue. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-03-16 11:43:54 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hickory-dns#3440
No description provided.