Skip to content

Commit bcf1ded

Browse files
committed
Merge branch 'main' of github.com:readthedocs/readthedocs.org into diataxis/main
2 parents 2f64539 + 5ab4955 commit bcf1ded

33 files changed

+585
-184
lines changed

.circleci/config.yml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- checkout
1919
- run: git submodule sync
2020
- run: git submodule update --init
21-
- run: pip install --user tox
21+
- run: pip install --user 'tox<5'
2222
- run: tox -e py310
2323
- codecov/upload
2424

@@ -29,7 +29,7 @@ jobs:
2929
- checkout
3030
- run: git submodule sync
3131
- run: git submodule update --init
32-
- run: pip install --user tox
32+
- run: pip install --user 'tox<4'
3333
- run: tox -c tox.embedapi.ini
3434

3535
checks:
@@ -41,18 +41,20 @@ jobs:
4141
- checkout
4242
- run: git submodule sync
4343
- run: git submodule update --init
44-
- run: pip install --user tox
44+
- run: git fetch origin main # needed for comparisson in pre-commit
45+
- run: git branch -f --track main origin/main # needed for comparisson in pre-commit
46+
- run: pip install --user 'tox<5'
47+
- run: tox -e pre-commit
48+
- run: tox -e migrations
49+
- run: tox -e lint
50+
- run: tox -e docs
51+
- run: tox -e docs-dev
4552
- run: scripts/circle/install_node.sh
4653
- run:
4754
name: Add node to the path
4855
command: |
4956
echo 'export PATH=~/.nvm/versions/node/v${NODE_VERSION}/bin:$PATH' >> $BASH_ENV
5057
source $BASH_ENV
51-
- run: tox -e migrations
52-
- run: tox -e pre-commit
53-
- run: tox -e lint
54-
- run: tox -e docs
55-
- run: tox -e docs-dev
5658
- run: tox -e eslint
5759

5860
workflows:

CHANGELOG.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
Version 9.1.0
2+
-------------
3+
4+
**This release contains an important security fix**. See more information `on the GitHub advisory <https://github.com/readthedocs/readthedocs.org/security/advisories/GHSA-368m-86q9-m99w>`_.
5+
6+
:Date: December 08, 2022
7+
8+
* `@benjaoming <https://github.com/benjaoming>`__: Docs: Move "Choosing between our two platforms" to Explanation (Diátaxis) (`#9784 <https://github.com/readthedocs/readthedocs.org/pull/9784>`__)
9+
* `@benjaoming <https://github.com/benjaoming>`__: Abandoned Projects policy: Relax reachability requirement (`#9783 <https://github.com/readthedocs/readthedocs.org/pull/9783>`__)
10+
* `@benjaoming <https://github.com/benjaoming>`__: Docs: Change "downloadable" to "offline" (`#9782 <https://github.com/readthedocs/readthedocs.org/pull/9782>`__)
11+
* `@humitos <https://github.com/humitos>`__: Docs: fix raw directive (`#9778 <https://github.com/readthedocs/readthedocs.org/pull/9778>`__)
12+
* `@github-actions[bot] <https://github.com/github-actions[bot]>`__: Dependencies: all packages updated via pip-tools (`#9775 <https://github.com/readthedocs/readthedocs.org/pull/9775>`__)
13+
* `@humitos <https://github.com/humitos>`__: Settings: define default MailerLite setting (`#9769 <https://github.com/readthedocs/readthedocs.org/pull/9769>`__)
14+
* `@ericholscher <https://github.com/ericholscher>`__: Refactor downloadable docs (`#9768 <https://github.com/readthedocs/readthedocs.org/pull/9768>`__)
15+
* `@humitos <https://github.com/humitos>`__: Docs: fix minor issues (`#9765 <https://github.com/readthedocs/readthedocs.org/pull/9765>`__)
16+
* `@humitos <https://github.com/humitos>`__: Docs: validate Mastodon link (`#9764 <https://github.com/readthedocs/readthedocs.org/pull/9764>`__)
17+
118
Version 9.0.0
219
-------------
320

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070

7171
master_doc = "index"
7272
copyright = "Read the Docs, Inc & contributors"
73-
version = "9.0.0"
73+
version = "9.1.0"
7474
release = version
7575
exclude_patterns = ["_build", "shared"]
7676
default_role = "obj"

docs/user/abandoned-projects.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ Reachability
4141

4242
The user of Read the Docs is solely responsible for being reachable by the core team
4343
for matters concerning projects that the user owns. In every case where
44-
contacting the user is necessary, the core team will try to do so at least
45-
three times, using the following means of contact:
44+
contacting the user is necessary, the core team will try to do so,
45+
using the following means of contact:
4646

4747
* E-mail address on file in the user's profile
4848
* E-mail addresses found in the given project's documentation

docs/user/guides/developers.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ or customize the documentation appearance.
1414
reproducible-builds
1515
embedding-content
1616
conda
17-
poetry
1817
remove-edit-buttons
1918
build-using-too-many-resources
2019
edit-source-links-sphinx

docs/user/guides/poetry.rst

Lines changed: 0 additions & 67 deletions
This file was deleted.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "readthedocs",
3-
"version": "9.0.0",
3+
"version": "9.1.0",
44
"description": "Read the Docs build dependencies",
55
"author": "Read the Docs, Inc <[email protected]>",
66
"scripts": {

readthedocs/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
"""Read the Docs."""
22

33

4-
__version__ = "9.0.0"
4+
__version__ = "9.1.0"

readthedocs/builds/storage.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import structlog
21
from pathlib import Path
32

3+
import structlog
44
from django.conf import settings
55
from django.core.exceptions import SuspiciousFileOperation
66
from django.core.files.storage import FileSystemStorage
77
from storages.utils import get_available_overwrite_name, safe_join
88

9+
from readthedocs.core.utils.filesystem import safe_open
10+
911
log = structlog.get_logger(__name__)
1012

1113

@@ -84,11 +86,20 @@ def copy_directory(self, source, destination):
8486
source = Path(source)
8587
for filepath in source.iterdir():
8688
sub_destination = self.join(destination, filepath.name)
89+
90+
# Don't follow symlinks when uploading to storage.
91+
if filepath.is_symlink():
92+
log.info(
93+
"Skipping symlink upload.",
94+
path_resolved=str(filepath.resolve()),
95+
)
96+
continue
97+
8798
if filepath.is_dir():
8899
# Recursively copy the subdirectory
89100
self.copy_directory(filepath, sub_destination)
90101
elif filepath.is_file():
91-
with filepath.open('rb') as fd:
102+
with safe_open(filepath, "rb") as fd:
92103
self.save(sub_destination, fd)
93104

94105
def sync_directory(self, source, destination):
@@ -114,12 +125,20 @@ def sync_directory(self, source, destination):
114125
copied_dirs = set()
115126
for filepath in source.iterdir():
116127
sub_destination = self.join(destination, filepath.name)
128+
# Don't follow symlinks when uploading to storage.
129+
if filepath.is_symlink():
130+
log.info(
131+
"Skipping symlink upload.",
132+
path_resolved=str(filepath.resolve()),
133+
)
134+
continue
135+
117136
if filepath.is_dir():
118137
# Recursively sync the subdirectory
119138
self.sync_directory(filepath, sub_destination)
120139
copied_dirs.add(filepath.name)
121140
elif filepath.is_file():
122-
with filepath.open('rb') as fd:
141+
with safe_open(filepath, "rb") as fd:
123142
self.save(sub_destination, fd)
124143
copied_files.add(filepath.name)
125144

readthedocs/config/config.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from django.conf import settings
1212

1313
from readthedocs.config.utils import list_to_dict, to_dict
14+
from readthedocs.core.utils.filesystem import safe_open
1415
from readthedocs.projects.constants import GENERIC
1516

1617
from .find import find_one
@@ -1380,7 +1381,11 @@ def load(path, env_config):
13801381

13811382
if not filename:
13821383
raise ConfigFileNotFound(path)
1383-
with open(filename, 'r') as configuration_file:
1384+
1385+
# Allow symlinks, but only the ones that resolve inside the base directory.
1386+
with safe_open(
1387+
filename, "r", allow_symlinks=True, base_path=path
1388+
) as configuration_file:
13841389
try:
13851390
config = parse(configuration_file.read())
13861391
except ParseError as error:

readthedocs/config/tests/test_config.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import pytest
88
from django.conf import settings
9+
from django.test import override_settings
910
from pytest import raises
1011

1112
from readthedocs.config import (
@@ -80,7 +81,8 @@ def test_load_no_config_file(tmpdir, files):
8081
apply_fs(tmpdir, files)
8182
base = str(tmpdir)
8283
with raises(ConfigFileNotFound) as e:
83-
load(base, {})
84+
with override_settings(DOCROOT=tmpdir):
85+
load(base, {})
8486
assert e.value.code == CONFIG_FILE_REQUIRED
8587

8688

@@ -92,13 +94,15 @@ def test_load_empty_config_file(tmpdir):
9294
)
9395
base = str(tmpdir)
9496
with raises(ConfigError):
95-
load(base, {})
97+
with override_settings(DOCROOT=tmpdir):
98+
load(base, {})
9699

97100

98101
def test_minimal_config(tmpdir):
99102
apply_fs(tmpdir, yaml_config_dir)
100103
base = str(tmpdir)
101-
build = load(base, {})
104+
with override_settings(DOCROOT=tmpdir):
105+
build = load(base, {})
102106
assert isinstance(build, BuildConfigV1)
103107

104108

@@ -111,7 +115,8 @@ def test_load_version1(tmpdir):
111115
},
112116
)
113117
base = str(tmpdir)
114-
build = load(base, {})
118+
with override_settings(DOCROOT=tmpdir):
119+
build = load(base, {})
115120
assert isinstance(build, BuildConfigV1)
116121

117122

@@ -124,7 +129,8 @@ def test_load_version2(tmpdir):
124129
},
125130
)
126131
base = str(tmpdir)
127-
build = load(base, {})
132+
with override_settings(DOCROOT=tmpdir):
133+
build = load(base, {})
128134
assert isinstance(build, BuildConfigV2)
129135

130136

@@ -138,7 +144,8 @@ def test_load_unknow_version(tmpdir):
138144
)
139145
base = str(tmpdir)
140146
with raises(ConfigError) as excinfo:
141-
load(base, {})
147+
with override_settings(DOCROOT=tmpdir):
148+
load(base, {})
142149
assert excinfo.value.code == VERSION_INVALID
143150

144151

@@ -159,7 +166,8 @@ def test_load_raise_exception_invalid_syntax(tmpdir):
159166
)
160167
base = str(tmpdir)
161168
with raises(ConfigError) as excinfo:
162-
load(base, {})
169+
with override_settings(DOCROOT=tmpdir):
170+
load(base, {})
163171
assert excinfo.value.code == CONFIG_SYNTAX_INVALID
164172

165173

@@ -176,13 +184,15 @@ def test_yaml_extension(tmpdir):
176184
},
177185
)
178186
base = str(tmpdir)
179-
config = load(base, {})
187+
with override_settings(DOCROOT=tmpdir):
188+
config = load(base, {})
180189
assert isinstance(config, BuildConfigV1)
181190

182191

183192
def test_build_config_has_source_file(tmpdir):
184193
base = str(apply_fs(tmpdir, yaml_config_dir))
185-
build = load(base, {})
194+
with override_settings(DOCROOT=tmpdir):
195+
build = load(base, {})
186196
assert build.source_file == os.path.join(base, 'readthedocs.yml')
187197

188198

@@ -196,7 +206,8 @@ def test_build_config_has_list_with_single_empty_value(tmpdir):
196206
),
197207
},
198208
))
199-
build = load(base, {})
209+
with override_settings(DOCROOT=tmpdir):
210+
build = load(base, {})
200211
assert isinstance(build, BuildConfigV1)
201212
assert build.formats == []
202213

@@ -682,7 +693,8 @@ def test_load_calls_validate(tmpdir):
682693
apply_fs(tmpdir, yaml_config_dir)
683694
base = str(tmpdir)
684695
with patch.object(BuildConfigV1, 'validate') as build_validate:
685-
load(base, {})
696+
with override_settings(DOCROOT=tmpdir):
697+
load(base, {})
686698
assert build_validate.call_count == 1
687699

688700

0 commit comments

Comments
 (0)