Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fix: path traversal prevention auto-failure on windows#1016

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
codejedi365 merged 13 commits intomasterfromfix/windows-path-traversal-prevention
Sep 1, 2024
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
13 commits
Select commitHold shift + click to select a range
a2e4af4
test(cli-version): ensure test path criteria is os-agnostic
codejedi365Aug 31, 2024
897493d
test: ensure compatibility with windows when evaluating results
codejedi365Aug 31, 2024
4599b33
test: adjust style & improve precision of assertions
codejedi365Aug 31, 2024
33cb454
test(gitea): ensure netrc testing works on windows
codejedi365Sep 1, 2024
7e29138
test(github): ensure netrc testing works on windows
codejedi365Sep 1, 2024
643bfbd
test(conf): ensure netrc generation fixture is windows compatible
codejedi365Sep 1, 2024
502602c
style(tests): swap to dynamic references to ensure easy refactor
codejedi365Sep 1, 2024
4498989
refactor(version-cmd): use all capital windows variables (x86) -> X86
codejedi365Sep 1, 2024
13fd1c9
docs(configuration): update `build_command` env table for windows to …
codejedi365Sep 1, 2024
aebfc8e
ci(main,pr): add automated testing on windows in parallel with linux
codejedi365Aug 31, 2024
d81f272
ci(pr): change to annotate only for test report upload on prs
codejedi365Sep 1, 2024
8edddfa
ci(gha-pr): restrict windows executions to python@3.8
codejedi365Aug 31, 2024
7e0b850
fix(config): fix path traversal detection for windows compatibility (…
codejedi365Sep 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions.github/workflows/main.yml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,11 +10,12 @@ on:

jobs:
test:
name: Python ${{ matrix.python-version }} tests
runs-on:ubuntu-latest
name: Python ${{ matrix.python-version }}on ${{ matrix.os }}tests
runs-on:${{ matrix.os }}
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
os: [ubuntu-latest, windows-latest]

steps:
- uses: actions/checkout@v4
Expand All@@ -39,8 +40,9 @@ jobs:
python -m pip install .[test]
python -m pip install pytest-github-actions-annotate-failures

- name: pytest
id: tests
- name: pytest on Linux
id: tests-linux
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
python -m pytest \
-vv \
Expand All@@ -51,9 +53,33 @@ jobs:
--cov-fail-under=80 \
--junit-xml=tests/reports/pytest-results.xml

- name: Report | Upload Test Results
- name: pytest on windows
id: tests-win
if: ${{ matrix.os == 'windows-latest' }}
# env:
# Required for GitPython to work on Windows because of getpass.getuser()
# USERNAME: "runneradmin"
# Because GHA is currently broken on Windows to pass these varables, we do it manually
run: |
$env:USERNAME = "runneradmin"
python -m pytest `
-vv `
-nauto `
`--cov=semantic_release `
`--cov-context=test `
`--cov-report=term-missing `
`--cov-fail-under=80 `
`--junit-xml=tests/reports/pytest-results.xml

- name: Report | Upload Linux Test Results
uses: mikepenz/action-junit-report@v4.3.1
if: ${{ always() && steps.tests-linux.outcome != 'skipped' }}
with:
report_paths: ./tests/reports/*.xml

- name: Report | Upload Windows Test Results
uses: mikepenz/action-junit-report@v4.3.1
if: ${{ always() && steps.tests.outcome != 'skipped' }}
if: ${{ always() && steps.tests-win.outcome != 'skipped' }}
with:
report_paths: ./tests/reports/*.xml

Expand Down
78 changes: 73 additions & 5 deletions.github/workflows/pr.yml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,12 +5,19 @@ on:
pull_request:

jobs:
test:
name: Python ${{ matrix.python-version }} tests
runs-on:ubuntu-latest
test-linux:
name: Python ${{ matrix.python-version }}on ${{ matrix.os }}tests
runs-on:${{ matrix.os }}
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
os:
- ubuntu-latest

steps:
- uses: actions/checkout@v4
Expand All@@ -36,7 +43,7 @@ jobs:
python -m pip install .[test]
python -m pip install pytest-github-actions-annotate-failures

- name:pytest
- name:Test
id: tests
run: |
python -m pytest \
Expand All@@ -53,6 +60,67 @@ jobs:
if: ${{ always() && steps.tests.outcome != 'skipped' }}
with:
report_paths: ./tests/reports/*.xml
annotate_only: true


test-windows:
name: Python ${{ matrix.python-version }} on ${{ matrix.os }} tests
runs-on: ${{ matrix.os }}
strategy:
# Since the current test suite takes 10-15 minutes to complete on windows, we are
# only going to run it on the oldest version of python we support. The older version
# will be the most likely area to fail as newer minor versions maintain compatibility.
matrix:
python-version: [3.8]
os: [windows-latest]

steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-

- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install .[test]
python -m pip install pytest-github-actions-annotate-failures

- name: Test
id: tests
# env:
# Required for GitPython to work on Windows because of getpass.getuser()
# USERNAME: "runneradmin"
# Because GHA is currently broken on Windows to pass these varables, we do it manually
run: |
$env:USERNAME = "runneradmin"
python -m pytest `
-vv `
-nauto `
`--cov=semantic_release `
`--cov-context=test `
`--cov-report=term-missing `
`--cov-fail-under=80 `
`--junit-xml=tests/reports/pytest-results.xml

- name: Report | Upload Test Results
uses: mikepenz/action-junit-report@v4.3.1
if: ${{ always() && steps.tests.outcome != 'skipped' }}
with:
report_paths: ./tests/reports/*.xml
annotate_only: true

lint:
runs-on: ubuntu-latest
Expand Down
4 changes: 2 additions & 2 deletionsdocs/configuration.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -216,13 +216,13 @@ ALLUSERSAPPDATA Pass-through ``ALLUSERAPPDATA`` if exists in process e
ALLUSERSPROFILE Pass-through ``ALLUSERSPPPROFILE`` if exists in process env, unset otherwise
APPDATA Pass-through ``APPDATA`` if exists in process env, unset otherwise
COMMONPROGRAMFILES Pass-through ``COMMONPROGRAMFILES`` if exists in process env, unset otherwise
COMMONPROGRAMFILES(x86) Pass-through ``COMMONPROGRAMFILES(x86)`` if exists in process env, unset otherwise
COMMONPROGRAMFILES(X86) Pass-through ``COMMONPROGRAMFILES(X86)`` if exists in process env, unset otherwise
DEFAULTUSERPROFILE Pass-through ``DEFAULTUSERPROFILE`` if exists in process env, unset otherwise
HOMEPATH Pass-through ``HOMEPATH`` if exists in process env, unset otherwise
PATHEXT Pass-through ``PATHEXT`` if exists in process env, unset otherwise
PROFILESFOLDER Pass-through ``PROFILESFOLDER`` if exists in process env, unset otherwise
PROGRAMFILES Pass-through ``PROGRAMFILES`` if exists in process env, unset otherwise
PROGRAMFILES(x86) Pass-through ``PROGRAMFILES(x86)`` if exists in process env, unset otherwise
PROGRAMFILES(X86) Pass-through ``PROGRAMFILES(X86)`` if exists in process env, unset otherwise
SYSTEM Pass-through ``SYSTEM`` if exists in process env, unset otherwise
SYSTEM16 Pass-through ``SYSTEM16`` if exists in process env, unset otherwise
SYSTEM32 Pass-through ``SYSTEM32`` if exists in process env, unset otherwise
Expand Down
4 changes: 2 additions & 2 deletionssemantic_release/cli/commands/version.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -189,13 +189,13 @@ def get_windows_env() -> Mapping[str, str | None]:
"ALLUSERSPROFILE",
"APPDATA",
"COMMONPROGRAMFILES",
"COMMONPROGRAMFILES(x86)",
"COMMONPROGRAMFILES(X86)",
"DEFAULTUSERPROFILE",
"HOMEPATH",
"PATHEXT",
"PROFILESFOLDER",
"PROGRAMFILES",
"PROGRAMFILES(x86)",
"PROGRAMFILES(X86)",
"SYSTEM",
"SYSTEM16",
"SYSTEM32",
Expand Down
14 changes: 12 additions & 2 deletionssemantic_release/cli/config.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -568,15 +568,25 @@ def from_raw_config( # noqa: C901
)

# changelog_file
changelog_file = Path(raw.changelog.changelog_file).expanduser().resolve()
# Must use absolute after resolve because windows does not resolve if the path does not exist
# which means it returns a relative path. So we force absolute to ensure path is complete
# for the next check of path matching
changelog_file = (
Path(raw.changelog.changelog_file).expanduser().resolve().absolute()
)

# Prevent path traversal attacks
if raw.repo_dir not in changelog_file.parents:
raise InvalidConfiguration(
"Changelog file destination must be inside of the repository directory."
)

template_dir = Path(raw.changelog.template_dir).expanduser().resolve()
# Must use absolute after resolve because windows does not resolve if the path does not exist
# which means it returns a relative path. So we force absolute to ensure path is complete
# for the next check of path matching
template_dir = (
Path(raw.changelog.template_dir).expanduser().resolve().absolute()
)

# Prevent path traversal attacks
if raw.repo_dir not in template_dir.parents:
Expand Down
64 changes: 50 additions & 14 deletionstests/command_line/test_changelog.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,6 +3,7 @@
import filecmp
import os
import shutil
import sys
from typing import TYPE_CHECKING
from unittest import mock

Expand All@@ -11,6 +12,7 @@
from pytest_lazy_fixtures.lazy_fixture import lf as lazy_fixture
from requests import Session

import semantic_release.hvcs.github
from semantic_release.cli.commands.main import main

from tests.const import (
Expand DownExpand Up@@ -226,17 +228,7 @@ def test_changelog_release_tag_not_in_history(
repo_with_single_branch_and_prereleases_angular_commits.__name__
)
@pytest.mark.parametrize("args", [("--post-to-release-tag", "v0.1.0")])
def test_changelog_post_to_release(
args: list[str],
monkeypatch: pytest.MonkeyPatch,
tmp_path_factory: pytest.TempPathFactory,
example_project_dir: ExProjectDir,
cli_runner: CliRunner,
):
tempdir = tmp_path_factory.mktemp("test_changelog")
remove_dir_tree(tempdir.resolve(), force=True)
shutil.copytree(src=str(example_project_dir.resolve()), dst=tempdir)

def test_changelog_post_to_release(args: list[str], cli_runner: CliRunner):
# Set up a requests HTTP session so we can catch the HTTP calls and ensure they're
# made

Expand All@@ -256,19 +248,63 @@ def test_changelog_post_to_release(
repo_name=EXAMPLE_REPO_NAME,
)

clean_os_environment = dict(
filter(
lambda k_v: k_v[1] is not None,
{
"CI": "true",
"PATH": os.getenv("PATH"),
"HOME": os.getenv("HOME"),
"VIRTUAL_ENV": os.getenv("VIRTUAL_ENV", "./.venv"),
**(
{}
if sys.platform != "win32"
else {
# Windows Required variables
"ALLUSERSAPPDATA": os.getenv("ALLUSERSAPPDATA"),
"ALLUSERSPROFILE": os.getenv("ALLUSERSPROFILE"),
"APPDATA": os.getenv("APPDATA"),
"COMMONPROGRAMFILES": os.getenv("COMMONPROGRAMFILES"),
"COMMONPROGRAMFILES(X86)": os.getenv("COMMONPROGRAMFILES(X86)"),
"DEFAULTUSERPROFILE": os.getenv("DEFAULTUSERPROFILE"),
"HOMEPATH": os.getenv("HOMEPATH"),
"PATHEXT": os.getenv("PATHEXT"),
"PROFILESFOLDER": os.getenv("PROFILESFOLDER"),
"PROGRAMFILES": os.getenv("PROGRAMFILES"),
"PROGRAMFILES(X86)": os.getenv("PROGRAMFILES(X86)"),
"SYSTEM": os.getenv("SYSTEM"),
"SYSTEM16": os.getenv("SYSTEM16"),
"SYSTEM32": os.getenv("SYSTEM32"),
"SYSTEMDRIVE": os.getenv("SYSTEMDRIVE"),
"SYSTEMROOT": os.getenv("SYSTEMROOT"),
"TEMP": os.getenv("TEMP"),
"TMP": os.getenv("TMP"),
"USERPROFILE": os.getenv("USERPROFILE"),
"USERSID": os.getenv("USERSID"),
"USERNAME": os.getenv("USERNAME"),
"WINDIR": os.getenv("WINDIR"),
}
),
}.items(),
)
)

# Patch out env vars that affect changelog URLs but only get set in e.g.
# Github actions
with mock.patch(
"semantic_release.hvcs.github.build_requests_session",
# Patching the specific module's reference to the build_requests_session function
f"{semantic_release.hvcs.github.__name__}.{semantic_release.hvcs.github.build_requests_session.__name__}",
return_value=session,
) as mocker, mock.patch.dict("os.environ", {}, clear=True):
) as build_requests_session_mock, mock.patch.dict(
os.environ, clean_os_environment, clear=True
):
# Act
cli_cmd = [MAIN_PROG_NAME, CHANGELOG_SUBCMD, *args]
result = cli_runner.invoke(main, cli_cmd[1:])

# Evaluate
assert_successful_exit_code(result, cli_cmd)
assertmocker.called
assertbuild_requests_session_mock.called
assert mock_adapter.called
assert mock_adapter.last_request is not None
assert expected_request_url == mock_adapter.last_request.url
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp