diff --git a/emhttp/plugins/dynamix/agents/Discord.xml b/emhttp/plugins/dynamix/agents/Discord.xml index f086531fcc..1fc39b16cd 100644 --- a/emhttp/plugins/dynamix/agents/Discord.xml +++ b/emhttp/plugins/dynamix/agents/Discord.xml @@ -50,6 +50,18 @@ LINK="${LINK:-}" HOSTNAME="${HOSTNAME:-$(hostname)}" TIMESTAMP="${TIMESTAMP:-$(date +%s)}" +# Convert literal \n sequences into real line breaks for reports. +if [[ -n "${DESCRIPTION}" ]]; then + DESCRIPTION=${DESCRIPTION//\\r\\n/$'\n'} + DESCRIPTION=${DESCRIPTION//\\n/$'\n'} + DESCRIPTION=${DESCRIPTION//\\r/$'\n'} +fi +if [[ -n "${CONTENT}" ]]; then + CONTENT=${CONTENT//\\r\\n/$'\n'} + CONTENT=${CONTENT//\\n/$'\n'} + CONTENT=${CONTENT//\\r/$'\n'} +fi + # ensure link has a host if [[ -n "${LINK}" ]] && [[ ${LINK} != http* ]]; then if [[ -r /usr/local/emhttp/state/nginx.ini ]]; then diff --git a/emhttp/plugins/dynamix/agents/tests/discord_newline_test.sh b/emhttp/plugins/dynamix/agents/tests/discord_newline_test.sh new file mode 100644 index 0000000000..3fa4cce347 --- /dev/null +++ b/emhttp/plugins/dynamix/agents/tests/discord_newline_test.sh @@ -0,0 +1,72 @@ +#!/bin/bash +set -euo pipefail + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +agent_xml="${script_dir}/../Discord.xml" + +tmp_dir="$(mktemp -d)" +trap 'rm -rf "$tmp_dir"' EXIT + +stub_dir="${tmp_dir}/bin" +payload="${tmp_dir}/payload.json" +script_path="${tmp_dir}/Discord.sh" + +mkdir -p "$stub_dir" + +cat > "${stub_dir}/curl" <<'EOF' +#!/bin/bash +out="${DISCORD_TEST_OUT:-/tmp/discord_payload.json}" +for ((i=1; i<=$#; i++)); do + if [[ "${!i}" == "--data-binary" ]]; then + j=$((i+1)) + printf '%s' "${!j}" > "$out" + exit 0 + fi +done +exit 0 +EOF +chmod +x "${stub_dir}/curl" + +cat > "${stub_dir}/date" <<'EOF' +#!/bin/bash +if [[ "$*" == *"-d "* ]]; then + printf '%s\n' "1970-01-01T00:00:00.000Z" + exit 0 +fi +exec /bin/date "$@" +EOF +chmod +x "${stub_dir}/date" + +awk ' + index($0, "") { in_block=0; next } + in_block { print } +' "$agent_xml" | sed 's/{0}//' > "$script_path" +chmod +x "$script_path" + +run_case() { + local desc="$1" + local content="$2" + local expected="$3" + + rm -f "$payload" + DISCORD_TEST_OUT="$payload" \ + WEBH_URL="http://example.invalid" \ + DESCRIPTION="$desc" \ + CONTENT="$content" \ + PATH="$stub_dir:$PATH" \ + bash "$script_path" >/dev/null + + actual="$(jq -r '.embeds[0].fields[0].value' "$payload")" + if [[ "$actual" != "$expected" ]]; then + echo "Discord newline test failed." >&2 + printf 'Expected:\n%s\n' "$expected" >&2 + printf 'Actual:\n%s\n' "$actual" >&2 + exit 1 + fi +} + +run_case "Line1\\nLine2" "Line3\\nLine4" $'Line1\nLine2\n\nLine3\nLine4' +run_case "Line1\\nLine2" "" $'Line1\nLine2' + +echo "OK"