Skip to content

Commit e12e9e4

Browse files
committed
fix: safely replace description placeholder in janitor run
Before this commit a (single-)quote or the pipe symbol in the description would make the janitor fail to replace the description placeholder as those made the sed statement malformed. A first fix is to store the value of the description in a variable and pass that to the sed statement. This eliminates the problems of quotes and variable expansion due to $ signs. The variable had to be passed as a real variable instead of using githubs variable replacement as with that the shell would still see the quotes and parse them. The second thing to fix is to escape any occurences of the pipe symbol in the description as that is what the sed command uses as its delimiter. The escaping has to be done by adding a literal \ to the description so during the sed command the | will stay in place. While doing this it became clear that also the \ has to be escaped as it would otherwise vanish after the sed run. Thus this is done prior to escaping the pipe symbol in order to not also mess with the introduced \ in that command. To verify it is working the test step gained a new variable that is injected if the it is no new repo. With this at least it is checked that the description can contain the special characters. One thing to note though is that setting the test variable and extracting the actual description need to look alike so we can be sure the actual retrieval will not fail.
1 parent 1015c6b commit e12e9e4

1 file changed

Lines changed: 29 additions & 2 deletions

File tree

.github/workflows/template-janitor.yml

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,43 @@ jobs:
5757
env:
5858
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5959

60+
- name: Export description to variable
61+
# This is basically needed as we have to have the value in an env variable to further process it in a safe manner.
62+
# Also we can inject a mock-string for testing if the project is still the template.
63+
if: fromJson(steps.get_repo_meta.outputs.data).is_template == false
64+
run: |
65+
# description can contain characters that mess with the sed command, so store it in a variable first.
66+
# The content of the description will be copied as-is by the action which makes it nearly impossible to "just" use it.
67+
# But by storing it in a variable with a heredoc the sed command will accept quotes and single quotes without a problem.
68+
# The heredoc delimiter is deliberately verbose and complex to reduce the likeliness someone accidentally puts it in their
69+
# description.
70+
echo NEW_DESCRIPTION="$(cat <<'do;not(include}this[in%the$description'
71+
${{ fromJson(steps.get_repo_meta.outputs.data).description }}
72+
do;not(include}this[in%the$description
73+
)" >> $GITHUB_ENV
74+
6075
- name: Use testing variables if still a template
6176
if: fromJson(steps.get_repo_meta.outputs.data).is_template == true
6277
run: |
6378
# This name is unsafe because it is not a valid C++ identifier
6479
echo "NEW_PROJECT=my-unsafe.project" >> $GITHUB_ENV
80+
# This name is unsafe as the sed command later uses surrounding quotes and the pipe symbol. The other characters are generally harmful too.
81+
NEW_DESCRIPTION=$(cat <<'EOF'
82+
Unsafe because of "quotes" and unbalanced "quotes ('Also' 'unbalanced single). The sed uses | and used to have /. Variable expansion might be bad $GITHUB_ENV as well. Also \ should stay.
83+
EOF
84+
)
85+
echo NEW_DESCRIPTION="$NEW_DESCRIPTION" >> $GITHUB_ENV
6586
6687
- name: Add safe replacement variable versions
6788
run: |
6889
# hyphens and dots in c++ identifiers are forbidden. Use underscores instead.
6990
NEW_SAFE_PROJECT=$(echo ${{ env.NEW_PROJECT }} | sed "s/-/_/g" | sed "s/\./_/g" )
70-
echo "NEW_SAFE_PROJECT=$NEW_SAFE_PROJECT" >> $GITHUB_ENV
91+
echo "NEW_SAFE_PROJECT=$NEW_SAFE_PROJECT" >> $GITHUB_ENV
92+
# The sed command uses the pipe as the delimiter so escape that to make it safe.
93+
# Also as we would remove any literal \ we have to escape those aswell and that has to
94+
# be done first as it would mess with the escape for the | otherwise.
95+
NEW_SAFE_DESCRIPTION="$(echo "$NEW_DESCRIPTION" | sed 's/\\/\\\\/g' | sed 's/|/\\|/g' )"
96+
echo "NEW_SAFE_DESCRIPTION=$NEW_SAFE_DESCRIPTION" >> $GITHUB_ENV
7197
7298
# Rename all cpp_starter_project occurences to current repository and remove this workflow
7399
- name: Insert new org and project
@@ -81,7 +107,8 @@ jobs:
81107
# fill in placeholders of readme and move it into place
82108
sed -i "s/%%myorg%%/${{ env.NEW_ORG }}/g" ${{ env.TEMPLATES_PATH }}/README.md
83109
sed -i "s/%%myproject%%/${{ env.NEW_PROJECT }}/g" ${{ env.TEMPLATES_PATH }}/README.md
84-
sed -i "s|%%description%%|${{ fromJson(steps.get_repo_meta.outputs.data).description }}|g" ${{ env.TEMPLATES_PATH }}/README.md
110+
# Use the variable from the env directly as githubs expansion would break the sed command.
111+
sed -i "s|%%description%%|$NEW_SAFE_DESCRIPTION|g" ${{ env.TEMPLATES_PATH }}/README.md
85112
mv include/myproject include/${{ env.NEW_SAFE_PROJECT }}
86113
cp ${{ env.TEMPLATES_PATH }}/README.md README.md
87114

0 commit comments

Comments
 (0)