diff --git a/src/check_formalities.sh b/src/check_formalities.sh index 4b2878a..6160a1a 100755 --- a/src/check_formalities.sh +++ b/src/check_formalities.sh @@ -188,15 +188,22 @@ output_skip() { output_split_fail() { split_fail "$1" "$2" "${INDENT_TERM}" [ -f "$GITHUB_OUTPUT" ] || return + local part1 part2 + part1="$(escape_latex "${2:0:$1}")" + part2="$(escape_latex "${2:$1}")" printf "${INDENT_MD}\$\\\textsf{%s\\color{red}{%s}}\$\n" \ - "${2:0:$1}" "${2:$1}" >> "$GITHUB_OUTPUT" + "$part1" "$part2" >> "$GITHUB_OUTPUT" } output_split_fail_ex() { split_fail_ex "$1" "$2" "$3" "${INDENT_TERM}" [ -f "$GITHUB_OUTPUT" ] || return + local part1 part2 part3 + part1="$(escape_latex "${3:0:$1}")" + part2="$(escape_latex "${3:$1:$(($2 - $1))}")" + part3="$(escape_latex "${3:$2}")" printf "${INDENT_MD}\$\\\textsf{%s\\color{yellow}{%s}\\color{red}{%s}}\$\n" \ - "${3:0:$1}" "${3:$1:$(($2 - $1))}" "${3:$2}" >> "$GITHUB_OUTPUT" + "$part1" "$part2" "$part3" >> "$GITHUB_OUTPUT" } # shellcheck disable=SC2329 diff --git a/src/helpers.sh b/src/helpers.sh index 3e2cb54..fa72f9e 100644 --- a/src/helpers.sh +++ b/src/helpers.sh @@ -58,3 +58,44 @@ status_fail() { status_skip() { status 39 skip "$1" } + +# Escapes special characters in the given text to be safe for inclusion in LaTeX +# output. +escape_latex() { + local text="$1" + + # Placeholders for characters that need special handling + local bs='LATEXESCAPEBACKSLASH' + local crt='LATEXESCAPECARET' + local rcb='LATEXESCAPERCB' + local tld='LATEXESCAPETILDE' + + # Replacement strings (stored in variables to avoid bash parsing issues with + # } in replacement strings) + local r_bs='\textbackslash{}' + local r_crt='\textasciicircum{}' + local r_rcb='\}' + local r_tld='\textasciitilde{}' + + # First, replace characters that need placeholders + text="${text//\\/$bs}" + text="${text//^/$crt}" + text="${text//\}/$rcb}" + text="${text//\~/$tld}" + + # Escape simple characters + text="${text//_/\\_}" + text="${text//\$/\\$}" + text="${text//&/\\&}" + text="${text//%/\\%}" + text="${text//#/\\#}" + text="${text//\{/\\{}" + + # Replace placeholders with actual LaTeX commands + text="${text//$bs/$r_bs}" + text="${text//$crt/$r_crt}" + text="${text//$rcb/$r_rcb}" + text="${text//$tld/$r_tld}" + + echo "$text" +} diff --git a/src/test.sh b/src/test.sh index e97ac5b..fb872fe 100755 --- a/src/test.sh +++ b/src/test.sh @@ -454,6 +454,18 @@ define \ Signed-off-by: Good Author EOF +define \ + -test 'LaTeX special chars' \ + -expected '0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 3' \ + -author 'Good Author' \ + -email 'good.author@example.com' \ + -subject 'package: stress test latex escaping' \ + -body <<-'EOF' + This line is intentionally made very long to trigger the body length check warning or error so we can test escaping of _ & % $ # { } \ ^ ~ + + Signed-off-by: Good Author + EOF + cleanup() { if [ -d "$REPO_DIR" ]; then [ -z "$PARALLEL_WORKER" ] && echo "Cleaning up temporary directory '$REPO_DIR'"