fix : release.yaml#4
Conversation
| echo "No version field found to update in pyproject.toml" >&2 | ||
| exit 1 | ||
| fi | ||
| sed -i "s/^version\s*=\s*\"[^\"]*\"/version = \"${VERSION}\"/" pyproject.toml |
There was a problem hiding this comment.
🔴 Unescaped VERSION in sed replacement allows sed metacharacters to corrupt the version string
The sed replacement string "${VERSION}" is interpolated directly without escaping sed-special characters. The version validation regex on line 37 (^[0-9]+\.[0-9]+\.[0-9]+(.*)?$) is very permissive — the (.*) allows characters like & and / after the third semver component. If VERSION contains &, sed interprets it as the entire matched text, silently producing a corrupted version (e.g., v1.2.3&bad → version = "1.2.3version = "0.2.0b4"bad"). If VERSION contains /, the sed command fails outright. The old Python code using re.subn was not susceptible to this because Python's regex replacement doesn't treat & or / as special.
Reproduction showing corruption with &
VERSION='1.2.3&bad'
echo 'version = "0.2.0b4"' | sed "s/^version\s*=\s*\"[^\"]*\"/version = \"${VERSION}\"/"
# Output: version = "1.2.3version = "0.2.0b4"bad"Prompt for agents
In .github/workflows/release.yml line 45, the VERSION variable is interpolated directly into the sed replacement string, which means sed metacharacters (& / \) in VERSION will cause corruption or failure. Two approaches to fix:
1. Escape the VERSION for sed before using it:
ESCAPED_VERSION=$(printf '%s\n' "$VERSION" | sed 's/[&/\\]/\\&/g')
sed -i "s/^version\s*=\s*\"[^\"]*\"/version = \"${ESCAPED_VERSION}\"/" pyproject.toml
2. Or tighten the version validation regex on line 37 to only allow safe characters (digits, dots, hyphens, alphanumerics):
Change: ^[0-9]+\.[0-9]+\.[0-9]+(.*)?$
To: ^[0-9]+\.[0-9]+\.[0-9]+([a-zA-Z0-9._-]*)?$
Option 2 is preferred as it also serves as better input validation. Alternatively, revert to the Python-based approach which handles these characters safely.
Was this helpful? React with 👍 or 👎 to provide feedback.
| sed -i "s/^version\s*=\s*\"[^\"]*\"/version = \"${VERSION}\"/" pyproject.toml | ||
| echo "pyproject.toml version updated to ${VERSION}" | ||
| grep '^version' pyproject.toml |
There was a problem hiding this comment.
🟡 No verification that sed actually performed the substitution — silent failure possible
The old Python code explicitly verified the substitution count (if n == 0: sys.exit(1)), ensuring the version was actually updated. The new code only checks that a line matching '^version\s*=' exists (line 41) before running sed (line 45), but doesn't verify sed actually performed a replacement. The grep pattern is looser than the sed pattern — for example, if the version line used single quotes (version = '0.2.0'), grep would match but sed (which requires double quotes) would silently leave the file unchanged. The build would then proceed and publish the package with the old version to PyPI. The grep '^version' on line 47 prints the line for logging but doesn't validate correctness.
| sed -i "s/^version\s*=\s*\"[^\"]*\"/version = \"${VERSION}\"/" pyproject.toml | |
| echo "pyproject.toml version updated to ${VERSION}" | |
| grep '^version' pyproject.toml | |
| sed -i "s/^version\s*=\s*\"[^\"]*\"/version = \"${VERSION}\"/" pyproject.toml | |
| echo "pyproject.toml version updated to ${VERSION}" | |
| if ! grep -q "^version\s*=\s*\"${VERSION}\"" pyproject.toml; then | |
| echo "Error: version substitution failed — pyproject.toml does not contain version \"${VERSION}\"" >&2 | |
| exit 1 | |
| fi | |
| grep '^version' pyproject.toml |
Was this helpful? React with 👍 or 👎 to provide feedback.
Uh oh!
There was an error while loading. Please reload this page.