libnet/internal/resolvconf: Parse: improve error message

When attempting to read a (malformed) resolv.conf with a very long line,
a obscure error would be produced that didn't provide much context to
identify the problem;

    Handler for POST /v1.51/containers/mariadb11/start returned error: bufio.Scanner: token too long

This patch adds some additional error-handling to detect this situation,
and includes the filename of the resolv.conf to help the user locating
the file that failed to be parsed.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2026-01-06 14:06:23 +01:00
parent e3f60d72f4
commit 07e2a782c7
2 changed files with 21 additions and 1 deletions

View File

@@ -18,6 +18,7 @@ import (
"bufio"
"bytes"
"context"
"fmt"
"io"
"io/fs"
"net/netip"
@@ -115,7 +116,15 @@ func Parse(reader io.Reader, path string) (ResolvConf, error) {
rc.processLine(scanner.Text())
}
if err := scanner.Err(); err != nil {
return ResolvConf{}, systemError{err}
src := rc.md.SourcePath
if errors.Is(err, bufio.ErrTooLong) {
return ResolvConf{}, systemError{
fmt.Errorf("failed to parse resolv.conf from %s: line too long (exceeds %d)", src, bufio.MaxScanTokenSize),
}
}
return ResolvConf{}, systemError{
fmt.Errorf("failed to parse resolv.conf from %s: %w", src, err),
}
}
if _, ok := rc.Option("ndots"); ok {
rc.md.NDotsFrom = "host"

View File

@@ -1,6 +1,7 @@
package resolvconf
import (
"bufio"
"bytes"
"io/fs"
"net/netip"
@@ -553,6 +554,16 @@ unrecognised thing
assert.Check(t, golden.String(string(content), t.Name()+".golden"))
}
// TestRCParseErrors tests that attempting to read a resolv.conf with a
// very long line produces a useful error.
// see https://github.com/moby/moby/issues/51679#issuecomment-3714403300
func TestRCParseErrors(t *testing.T) {
input := strings.Repeat("a", bufio.MaxScanTokenSize+1) + "\n"
_, err := Parse(bytes.NewBufferString(input), "/etc/resolv.conf")
assert.Error(t, err, `failed to parse resolv.conf from /etc/resolv.conf: line too long (exceeds 65536)`)
}
func BenchmarkGenerate(b *testing.B) {
rc := &ResolvConf{
nameServers: []netip.Addr{