Fix #1112: download role creates duplicated copies

`:download:` role creates duplicated copies when the document contains
two or more the role for the same file, but in different form.  It
considers two paths are different when one contains relative path like
`path/to/../file.dat`.

Internally, `env.relfn2path()` does not normalize the given path in
relative form.  As a result, download role can't detect the same paths
are given.  This adds `os.path.normpath()` to `env.relfn2path()` to
normalize the path.
This commit is contained in:
Takeshi KOMIYA 2021-01-18 00:00:32 +09:00
parent 596dfba841
commit bc56384fb9
3 changed files with 11 additions and 3 deletions

View File

@ -61,6 +61,8 @@ Bugs fixed
* C, C++: in general fix intersphinx and role lookup types.
* #8683: :confval:`html_last_updated_fmt` does not support UTC offset (%z)
* #8683: :confval:`html_last_updated_fmt` generates wrong time zone for %Z
* #1112: ``download`` role creates duplicated copies when relative path is
specified
Testing
--------

View File

@ -10,6 +10,7 @@
import os
import pickle
import posixpath
import warnings
from collections import defaultdict
from copy import copy
@ -356,9 +357,9 @@ class BuildEnvironment:
docdir = path.dirname(self.doc2path(docname or self.docname,
base=None))
rel_fn = path.join(docdir, filename)
# the path.abspath() might seem redundant, but otherwise artifacts
# such as ".." will remain in the path
return rel_fn, path.abspath(path.join(self.srcdir, rel_fn))
return (posixpath.normpath(rel_fn),
path.normpath(path.join(self.srcdir, rel_fn)))
@property
def found_docs(self) -> Set[str]:

View File

@ -138,6 +138,11 @@ def test_env_relfn2path(app):
assert relfn == '../logo.jpg'
assert absfn == app.srcdir.parent / 'logo.jpg'
# relative path traversal
relfn, absfn = app.env.relfn2path('subdir/../logo.jpg', 'index')
assert relfn == 'logo.jpg'
assert absfn == app.srcdir / 'logo.jpg'
# omit docname (w/ current docname)
app.env.temp_data['docname'] = 'subdir/document'
relfn, absfn = app.env.relfn2path('images/logo.jpg')