From bf1cf77bbf4fca5858f464ccaa5f0aa9aa415deb Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> Date: Sat, 14 Feb 2026 22:39:12 -0500 Subject: [PATCH 1/3] fix(content-guards): resolve unbound variable error in markdown validator Simplified array expansion syntax in validate-markdown.sh to prevent "unbound variable" error when running with set -euo pipefail. ROOT CAUSE ---------- Line 111 used complex array expansion syntax ${config_flag[@]+"${config_flag[@]}"} which triggered unbound variable errors with set -u, even though config_flag was properly initialized on line 50. SOLUTION -------- Replaced with simpler "${config_flag[@]}" syntax which works correctly: - Empty array expands to no arguments - Non-empty array expands to its values - No unbound variable error with set -u This was a follow-up fix from PR #36. Co-Authored-By: Claude Sonnet 4.5 --- content-guards/scripts/validate-markdown.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content-guards/scripts/validate-markdown.sh b/content-guards/scripts/validate-markdown.sh index 696d100..46e80b4 100755 --- a/content-guards/scripts/validate-markdown.sh +++ b/content-guards/scripts/validate-markdown.sh @@ -108,7 +108,7 @@ EOF fi fi - if ! markdownlint_output=$(markdownlint-cli2 "${config_flag[@]+"${config_flag[@]}"}" "$file_path" 2>&1); then + if ! markdownlint_output=$(markdownlint-cli2 "${config_flag[@]}" "$file_path" 2>&1); then errors+=("markdownlint-cli2 failed:") errors+=("$markdownlint_output") fi From eb2ce4600ad8f2362c063dd6fadfe58b79fabc88 Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> Date: Sat, 14 Feb 2026 23:07:55 -0500 Subject: [PATCH 2/3] fix(markdown-validator): add jq dependency check and simplify config discovery - Add jq availability check before JSON parsing to fail gracefully when unavailable - Replace 10-file config discovery loop with glob-based compgen check - Keep array expansion fix from PR #39 with safe expansion syntax - Reduce script from 137 to 130 lines while maintaining all functionality Fixes unbound variable crashes and improves robustness when tools are unavailable. Co-Authored-By: Claude Haiku 4.5 --- content-guards/scripts/validate-markdown.sh | 25 ++++++++------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/content-guards/scripts/validate-markdown.sh b/content-guards/scripts/validate-markdown.sh index 46e80b4..dca27e4 100755 --- a/content-guards/scripts/validate-markdown.sh +++ b/content-guards/scripts/validate-markdown.sh @@ -10,6 +10,11 @@ set -euo pipefail +# Fail open if jq is unavailable +if ! command -v jq &>/dev/null; then + exit 0 +fi + # Extract the file path from stdin, which contains the hook input JSON file_path=$(jq -r '.tool_input.file_path // empty') @@ -50,27 +55,15 @@ if command -v markdownlint-cli2 &>/dev/null; then config_flag=() has_project_config=false - # Walk up from the file's directory looking for project-level config + # Check for project-level markdownlint config (walk up from file's directory) search_dir="$(dirname -- "$file_path")" while true; do - if [[ -f "$search_dir/.markdownlint-cli2.yaml" ]] || - [[ -f "$search_dir/.markdownlint-cli2.jsonc" ]] || - [[ -f "$search_dir/.markdownlint-cli2.cjs" ]] || - [[ -f "$search_dir/.markdownlint-cli2.mjs" ]] || - [[ -f "$search_dir/.markdownlint.json" ]] || - [[ -f "$search_dir/.markdownlint.jsonc" ]] || - [[ -f "$search_dir/.markdownlint.yaml" ]] || - [[ -f "$search_dir/.markdownlint.yml" ]] || - [[ -f "$search_dir/.markdownlint.cjs" ]] || - [[ -f "$search_dir/.markdownlint.mjs" ]]; then + if compgen -G "$search_dir/.markdownlint*" > /dev/null 2>&1; then has_project_config=true break fi - parent_dir="$(dirname -- "$search_dir")" - if [[ "$parent_dir" == "$search_dir" ]]; then - break - fi + [[ "$parent_dir" == "$search_dir" ]] && break search_dir="$parent_dir" done @@ -108,7 +101,7 @@ EOF fi fi - if ! markdownlint_output=$(markdownlint-cli2 "${config_flag[@]}" "$file_path" 2>&1); then + if ! markdownlint_output=$(markdownlint-cli2 "${config_flag[@]+"${config_flag[@]}"}" "$file_path" 2>&1); then errors+=("markdownlint-cli2 failed:") errors+=("$markdownlint_output") fi From 0aec01d3a0dc5da93a17ff371df35aa84dba1031 Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> Date: Sat, 14 Feb 2026 23:23:20 -0500 Subject: [PATCH 3/3] fix: use nullglob for safer config detection Address glob injection and false-positive concerns from review: - Use nullglob to safely expand .markdownlint* pattern - Avoids compgen external command and glob-injection risks - Trusts markdownlint-cli2 native discovery for config validation - Maintains simplicity while addressing security concerns Co-Authored-By: Claude Haiku 4.5 --- content-guards/scripts/validate-markdown.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/content-guards/scripts/validate-markdown.sh b/content-guards/scripts/validate-markdown.sh index dca27e4..73dc0ab 100755 --- a/content-guards/scripts/validate-markdown.sh +++ b/content-guards/scripts/validate-markdown.sh @@ -58,7 +58,10 @@ if command -v markdownlint-cli2 &>/dev/null; then # Check for project-level markdownlint config (walk up from file's directory) search_dir="$(dirname -- "$file_path")" while true; do - if compgen -G "$search_dir/.markdownlint*" > /dev/null 2>&1; then + shopt -s nullglob + config_files=("$search_dir"/.markdownlint*) + shopt -u nullglob + if ((${#config_files[@]} > 0)); then has_project_config=true break fi