@@ -110,19 +110,76 @@ runs:
110110      if : ${{ !cancelled() }} 
111111      shell : bash 
112112      run : | 
113-         set -e  # Exit immediately if any command fails 
114-         sha_input='${{ inputs.sha }}' 
115-         if [[ ! "$sha_input" =~ ^[0-9a-f]{40}$ ]]; then 
116-           # check if value is non-sha valid 
117-           output=$(git rev-parse --verify $sha_input) 
118-           if [[ -n "$output" ]]; then 
119-             printf "::debug:: %s\n" "Valid branch name or sha provided: ${output}" ; 
113+         set -euo pipefail 
114+ 
115+         raw_input='${{ inputs.sha }}' 
116+ 
117+         # Reject NUL or newline immediately 
118+         if printf '%s' "$raw_input" | grep -q $'[\\x00\\n\\r]'; then 
119+           printf "::error title='Invalid':: %s\n" "Error: input contains disallowed control characters" >&2 
120+           exit 1 
121+         fi 
122+ 
123+         # Strip one level of surrounding quotes and trim whitespace 
124+         normalize() { 
125+           local s="$1" 
126+           s="${s#"${s%%[![:space:]]*}"}" 
127+           s="${s%"${s##*[![:space:]]}"}" 
128+           if [[ (${s:0:1} == "'" && ${s: -1} == "'") || (${s:0:1} == '"' && ${s: -1} == '"') ]]; then 
129+             s="${s:1:-1}" 
130+           fi 
131+           printf '%s' "$s" 
132+         } 
133+         input="$(normalize "$raw_input")" 
134+ 
135+         # Reject inputs starting with '-' (options) 
136+         if [[ "${input:0:1}" == "-" ]]; then 
137+           printf "::error title='Invalid':: %s\n" "Error: input may not start with '-'" >&2 
138+           exit 1 
139+         fi 
140+ 
141+         # Reject any characters that enable ref modifiers or ambiguity 
142+         if [[ "$input" =~ [[:space:]~^\{\}:@\*\?$$$$] ]]; then 
143+           printf "::error title='Invalid':: %s\n" "Error: input contains disallowed characters" >&2 
144+           exit 1 
145+         fi 
146+ 
147+         # If it's a 40-char SHA, accept directly 
148+         if [[ "$input" =~ ^[0-9a-f]{40}$ ]]; then 
149+           resolved_sha="$input" 
150+         else 
151+           # Try explicit namespaces in order: full refs, refs/heads/, refs/tags/, then bare branch/tag 
152+           resolved_sha="" 
153+           # 1) If input is a full ref path starting with refs/, resolve only that 
154+           if [[ "$input" == refs/* ]]; then 
155+             if git rev-parse --verify "$input" >/dev/null 2>&1; then 
156+               resolved_sha="$(git rev-parse --verify "$input")" 
157+             else 
158+               printf "::error title='Invalid':: %s\n" "Error: ref not found: $input" >&2 
159+               exit 1 
160+             fi 
120161          else 
121-             printf "::error title='Invalid':: %s\n" "Error: Invalid SHA format" >&2 ; 
122-             exit 1 ; 
162+             # 2) Try refs/heads/<input> 
163+             if git rev-parse --verify "refs/heads/$input" >/dev/null 2>&1; then 
164+               resolved_sha="$(git rev-parse --verify "refs/heads/$input")" 
165+             # 3) Try refs/tags/<input> 
166+             elif git rev-parse --verify "refs/tags/$input" >/dev/null 2>&1; then 
167+               resolved_sha="$(git rev-parse --verify "refs/tags/$input")" 
168+             else 
169+               printf "::error title='Invalid':: %s\n" "Error: no matching branch or tag found for: $input" >&2 
170+               exit 1 
171+             fi 
123172          fi 
124-         fi ; 
125-         printf "sha=%s\n" $(git rev-parse --verify "$output") >> "$GITHUB_OUTPUT" ; 
173+         fi 
174+ 
175+         # Ensure final resolved value is a full 40-char commit SHA 
176+         if [[ ! "$resolved_sha" =~ ^[0-9a-f]{40}$ ]]; then 
177+           printf "::error title='Invalid':: %s\n" "Error: resolved value is not a full commit SHA" >&2 
178+           exit 1 
179+         fi 
180+ 
181+         printf "sha=%s\n" "$resolved_sha" >> "$GITHUB_OUTPUT" 
182+ 
126183id : output_uuid 
127184      if : ${{ !cancelled() && (inputs.check-id == '') }} 
128185      shell : bash 
@@ -167,21 +224,19 @@ runs:
167224      run : | 
168225        printf "%s\n" "::group::validate-name" 
169226        name_input='${{ inputs.name }}' 
170-         sanitized_input_name=$(echo "$name_input" | tr -cd '[:alnum:] _') 
171-         printf "::debug:: %s\n" "Will use name $sanitized_input_name" ; 
227+         printf "::debug:: %s\n" "Will use name $name_input" ; 
172228        printf "%s\n" "::endgroup::" 
173229        printf "%s\n" "::group::validate-title" 
174230        title_input='${{ inputs.name }}' 
175-         sanitized_input_title=$(echo "$title_input" | tr -cd '[:alnum:] _') 
176-         printf "::debug:: %s\n" "Will use name $sanitized_input_title" ; 
177-         sanitized_input_title_field=$(printf "%s%s" 'output[title]=' "$sanitized_input_title_field" ;) 
231+         printf "::debug:: %s\n" "Will use name $title_input" ; 
232+         sanitized_input_title_field=$(printf "%s%s" 'output[title]=' "$title_input" ;) 
178233        printf "%s\n" "::endgroup::" 
179234        printf "%s\n" "::group::create-new-check" 
180235        # GitHub CLI api 
181236        # https://cli.github.com/manual/gh_api 
182237        CHECK_ID=$(gh api --method POST -H "Accept: application/vnd.github+json" \ 
183238        /repos/reactive-firewall-org/multicast/check-runs \ 
184-         -f "name=$sanitized_input_name " -f "head_sha=${{ steps.output_sha.outputs.sha }}" \ 
239+         -f "name=$name_input " -f "head_sha=${{ steps.output_sha.outputs.sha }}" \ 
185240        -f 'status=${{ inputs.status }}' -f "external_id=${{ steps.output_uuid.outputs.uuid }}" \ 
186241        -f "started_at=${{ steps.output_date.outputs.check_date }}Z" \ 
187242        -f "details_url=${{ steps.output_check_details_url.outputs.details_url }}" \ 
@@ -198,21 +253,19 @@ runs:
198253      run : | 
199254        printf "%s\n" "::group::validate-name" 
200255        name_input='${{ inputs.name }}' 
201-         sanitized_input_name=$(echo "$name_input" | tr -cd '[:alnum:] _') 
202-         printf "::debug:: %s\n" "Will use name $sanitized_input_name" ; 
256+         printf "::debug:: %s\n" "Will use name $name_input" ; 
203257        printf "%s\n" "::endgroup::" 
204258        printf "%s\n" "::group::validate-title" 
205259        title_input='${{ inputs.name }}' 
206-         sanitized_input_title=$(echo "$title_input" | tr -cd '[:alnum:] _') 
207-         printf "::debug:: %s\n" "Will use name $sanitized_input_title" ; 
208-         sanitized_input_title_field=$(printf "%s%s" 'output[title]=' "$sanitized_input_title_field" ;) 
260+         printf "::debug:: %s\n" "Will use name $title_input" ; 
261+         sanitized_input_title_field=$(printf "%s%s" 'output[title]=' "$title_input" ;) 
209262        printf "%s\n" "::endgroup::" 
210263        printf "%s\n" "::group::update-new-check" 
211264        # GitHub CLI api 
212265        # https://cli.github.com/manual/gh_api 
213266        CHECK_ID=$(gh api --method POST -H "Accept: application/vnd.github+json" \ 
214267        /repos/reactive-firewall-org/multicast/check-runs \ 
215-         -f "name=$sanitized_input_name " -f "head_sha=${{ steps.output_sha.outputs.sha }}" \ 
268+         -f "name=$input_name " -f "head_sha=${{ steps.output_sha.outputs.sha }}" \ 
216269        -f "status=in_progress" -f "external_id=${{ steps.output_uuid.outputs.uuid }}" \ 
217270        -f "started_at=${{ steps.output_date.outputs.check_date }}Z" \ 
218271        -f "details_url=${{ steps.output_check_details_url.outputs.details_url }}" \ 
@@ -253,21 +306,19 @@ runs:
253306      run : | 
254307        printf "%s\n" "::group::validate-name" 
255308        name_input='${{ inputs.name }}' 
256-         sanitized_input_name=$(echo "$name_input" | tr -cd '[:alnum:] _') 
257-         printf "::debug:: %s\n" "Will use name $sanitized_input_name" ; 
309+         printf "::debug:: %s\n" "Will use name $name_input" ; 
258310        printf "%s\n" "::endgroup::" 
259311        printf "%s\n" "::group::validate-title" 
260312        title_input='${{ inputs.name }}' 
261-         sanitized_input_title=$(echo "$title_input" | tr -cd '[:alnum:] _') 
262-         printf "::debug:: %s\n" "Will use name $sanitized_input_title" ; 
263-         sanitized_input_title_field=$(printf "%s%s" 'output[title]=' "$sanitized_input_title_field" ;) 
313+         printf "::debug:: %s\n" "Will use name $title_input" ; 
314+         sanitized_input_title_field=$(printf "%s%s" 'output[title]=' "$title_input" ;) 
264315        printf "%s\n" "::endgroup::" 
265316        printf "%s\n" "::group::update-check" 
266317        # GitHub CLI api 
267318        # https://cli.github.com/manual/gh_api 
268319        gh api --method PATCH -H "Accept: application/vnd.github+json" \ 
269320        /repos/reactive-firewall-org/multicast/check-runs/${{ steps.output_check_id.outputs.check_id }} \ 
270-         -f "name=$sanitized_input_name " -f "head_sha=${{ steps.output_sha.outputs.sha }}" \ 
321+         -f "name=$input_name " -f "head_sha=${{ steps.output_sha.outputs.sha }}" \ 
271322        -f "status=${{ inputs.status }}" \ 
272323        -f "details_url=${{ steps.output_check_details_url.outputs.details_url }}" \ 
273324        -f "$sanitized_input_title_field" \ 
@@ -282,21 +333,19 @@ runs:
282333      run : | 
283334        printf "%s\n" "::group::validate-name" 
284335        name_input='${{ inputs.name }}' 
285-         sanitized_input_name=$(echo "$name_input" | tr -cd '[:alnum:] _') 
286-         printf "::debug:: %s\n" "Will use name $sanitized_input_name" ; 
336+         printf "::debug:: %s\n" "Will use name $name_input" ; 
287337        printf "%s\n" "::endgroup::" 
288338        printf "%s\n" "::group::validate-title" 
289339        title_input='${{ inputs.name }}' 
290-         sanitized_input_title=$(echo "$title_input" | tr -cd '[:alnum:] _') 
291-         printf "::debug:: %s\n" "Will use name $sanitized_input_title" ; 
292-         sanitized_input_title_field=$(printf "%s%s" 'output[title]=' "$sanitized_input_title_field" ;) 
340+         printf "::debug:: %s\n" "Will use name $title_input" ; 
341+         sanitized_input_title_field=$(printf "%s%s" 'output[title]=' "$title_input" ;) 
293342        printf "%s\n" "::endgroup::" 
294343        printf "%s\n" "::group::complete-check" 
295344        # GitHub CLI api 
296345        # https://cli.github.com/manual/gh_api 
297346        gh api --method PATCH -H "Accept: application/vnd.github+json" \ 
298347        /repos/reactive-firewall-org/multicast/check-runs/${{ steps.output_check_id.outputs.check_id }} \ 
299-         -f "name=$sanitized_input_name " -f "head_sha=${{ steps.output_sha.outputs.sha }}" \ 
348+         -f "name=$input_name " -f "head_sha=${{ steps.output_sha.outputs.sha }}" \ 
300349        -f "status=completed" -f "conclusion=${{ inputs.conclusion }}" \ 
301350        -f "completed_at=${{ steps.output_date.outputs.check_date }}Z" \ 
302351        -f "details_url=${{ steps.output_check_details_url.outputs.details_url }}" \ 
0 commit comments