Skip to content

Fix TXT round-trip for long and non-ASCII records#33

Open
bindreams wants to merge 5 commits into
libdns:masterfrom
bindreams:fix/long-txt-roundtrip-v2
Open

Fix TXT round-trip for long and non-ASCII records#33
bindreams wants to merge 5 commits into
libdns:masterfrom
bindreams:fix/long-txt-roundtrip-v2

Conversation

@bindreams

Copy link
Copy Markdown

Fixes #32.

TXT content was encoded with fmt.Sprintf("%q", ...) and decoded by stripping the surrounding quotes. That pairing isn't symmetric and never chunked, so two things broke for TXT values over 255 bytes (DKIM keys, long SPF):

  1. GetRecords returned Text with Cloudflare's zone-file segment separators (" ") still embedded, because CF splits long values into multiple "..." strings and the old code only stripped the outermost quotes.
  2. DeleteRecords silently matched nothing, because the lookup key was the unchunked %q string while CF stored and returned the chunked form.

Cloudflare's TXT content is RFC 1035 zone presentation: quoted character-strings, \DDD escapes, split at 255 octets. This swaps the wrap/unwrap helpers for a real encode/decode (txt.go) and matches TXT for deletion by decoded value instead of by raw presentation. Delete also now honors the RecordDeleter "empty value matches any value" rule for TXT (previously a silent no-op). TXT round-trips byte-for-byte at any length and with any byte content.

While in provider.go I fixed two unrelated pagination bugs in GetRecords: ResultInfo was dereferenced before its own nil check, and the page-count division could divide by zero if per_page came back as 0. Both are guarded now. Happy to split these into a separate PR if you'd prefer.

One thing I left alone on purpose: delete-matching compares name, type, and value but not TTL, which the RecordDeleter contract also mentions. That predates this change and applies to every record type in the driver, so it felt out of scope here.

Testing: codec unit tests (round-trip over every byte value, chunk boundaries, golden cases, error paths) plus live libdnstest integration tests for a DKIM-sized record, quotes and backslashes, raw bytes, SetRecords, and empty-value delete. The workflow now also runs the root module's unit tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Long TXT (>255 bytes, e.g. DKIM) round-trip fails: GetRecords surfaces zone-file segment separators in Text; DeleteRecords silent no-op

1 participant