From b4925052dd10f6b407fba5c5f550ebe829356d28 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 2 Aug 2026 21:55:19 +0800 Subject: [PATCH] Fix dns_cyon cleanup failing on FreeBSD _cyon_delete_txt relied on `printf "%b"` to convert a sed-injected literal `\n` into a real newline, but `%b` also processes the `\"` escapes that the JSON response is full of. glibc/bash/dash keep the backslash of such an undefined escape, FreeBSD's printf (sh builtin and /usr/bin/printf alike) drops it -- so `data-hash=\"..\"` became `data-hash=".."`, the extraction regex matched nothing, _dns_entries stayed empty and no TXT record was ever deleted. Drop the newline injection and use _egrep_o, which already yields one match per line, then parse each line with sed. Also feed the read loop a newline-terminated list: `printf "%s"` left the last line unterminated, so `read` returned non-zero at EOF and the loop skipped the final entry on every platform. Verified identical output on FreeBSD 14.3, Linux/bash and Linux/dash. Fixes #7169 --- dnsapi/dns_cyon.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_cyon.sh b/dnsapi/dns_cyon.sh index d4b6b6e8..6677b32f 100644 --- a/dnsapi/dns_cyon.sh +++ b/dnsapi/dns_cyon.sh @@ -285,15 +285,15 @@ _cyon_delete_txt() { list_txt_url="https://my.cyon.ch/domain/dnseditor/list-async" - list_txt_response="$(_get "${list_txt_url}" | sed -e 's/data-hash/\\ndata-hash/g')" + list_txt_response="$(_get "${list_txt_url}")" _debug list_txt_response "${list_txt_response}" if ! _cyon_check_if_2fa_missed "${list_txt_response}"; then return 1; fi # Find and delete all acme challenge entries for the $fulldomain. - _dns_entries="$(printf "%b\n" "${list_txt_response}" | sed -n 's/data-hash=\\"\([^"]*\)\\" data-identifier=\\"\([^"]*\)\\".*/\1 \2/p')" + _dns_entries="$(printf "%s\n" "${list_txt_response}" | _egrep_o 'data-hash=\\"[^"]*\\" data-identifier=\\"[^"]*\\"' | sed 's/data-hash=\\"\([^"]*\)\\" data-identifier=\\"\([^"]*\)\\"/\1 \2/')" - printf "%s" "${_dns_entries}" | while read -r _hash _identifier; do + printf "%s\n" "${_dns_entries}" | while read -r _hash _identifier; do dns_type="$(printf "%s" "$_identifier" | cut -d'|' -f1)" dns_domain="$(printf "%s" "$_identifier" | cut -d'|' -f2)"