Skip to content

Commit db0214a

Browse files
[FEATURE] Allow "EXT:self" syntax for typo3:site-set-settings (#702)
By default only files within a "Documentation/" directory can be read by the "typo3:site-set-settings" directive. However in cases where extensions (Core or third party) provide additional files in their main directory, these should be accessible, to allow reading the ACTUAL file contents, and not requiring a copy to be placed inside Documentation/. With this patch, a new syntax "EXT:self" allows to refer to this base "/project/" directory as a path prefix, instead of "/project/Documentation/". Other file traversal beyond this is forbidden.
1 parent 48ac673 commit db0214a

File tree

9 files changed

+1291
-5
lines changed

9 files changed

+1291
-5
lines changed

packages/typo3-docs-theme/src/Directives/SiteSetSettingsDirective.php

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
namespace T3Docs\Typo3DocsTheme\Directives;
1515

16+
use League\Flysystem\Adapter\Local;
17+
use League\Flysystem\Filesystem;
1618
use phpDocumentor\Guides\RestructuredText\Nodes\ConfvalNode;
1719
use Symfony\Component\Yaml\Yaml;
1820
use phpDocumentor\Guides\Nodes\Inline\PlainTextInlineNode;
@@ -73,16 +75,52 @@ public function loadFileFromDocumentation(BlockContext $blockContext, Directive
7375
{
7476
$parser = $blockContext->getDocumentParserContext()->getParser();
7577
$parserContext = $parser->getParserContext();
76-
77-
$path = $parserContext->absoluteRelativePath($directive->getData());
78-
78+
/** @var Filesystem $origin */
7979
$origin = $parserContext->getOrigin();
80+
/** @var Local $adapter */
81+
$adapter = $origin->getAdapter();
82+
$pathPrefix = (string)$adapter->getPathPrefix();
83+
84+
// The path delivered via the directive like:
85+
// .. typo3:site-set-settings:: EXT:self/Configuration/Sets/FluidStyledContent/settings.definitions.yaml
86+
$setConfigurationFile = $directive->getData();
87+
88+
// By default, the RST files are placed inside a "Documentation" subdirectory.
89+
// When using the docker container, this origin root path is then set to "/project/Documentation".
90+
// No files on the "/project/" directory level can usually be accessed, even though they may belong
91+
// to TYPO3 core/third-party extensions that the Documentation belongs to directory-wise.
92+
// To allow files to be retrieved on the EXTENSION-level, instead of DOCUMENTATION-level,
93+
// a special string "EXT:self" is evaluated here.
94+
// If a path starts with that notation, it will be referenced from the "/project/..." directory level.
95+
// It will not break out of the "/project/" mapping!
96+
if (str_starts_with($setConfigurationFile, 'EXT:self')) {
97+
// This will replace "EXT:self/Configuration/Sets/File.yaml" with "/Configuration/Sets/File.yaml"
98+
// and is then passed to absoluteRelativePath() which will set $path = "/Configuration/Sets/File.yaml",
99+
// but ensure no "../../../" or other path traversal is allowed.
100+
$path = $parserContext->absoluteRelativePath(str_replace('EXT:self', '', $setConfigurationFile));
101+
102+
// Get the current origin Path, usually "/project/Documentation/", and go one level up.
103+
$newOriginPath = dirname($pathPrefix) . '/';
104+
105+
// Temporarily change the path prefix now to "/project/"
106+
$adapter->setPathPrefix($newOriginPath);
107+
} else {
108+
$path = $parserContext->absoluteRelativePath($setConfigurationFile);
109+
}
110+
80111
if (!$origin->has($path)) {
81-
throw new FileLoadingException(sprintf('The directive .. typo3:site-set-settings:: cannot find the source at %s. ', $path));
112+
// Revert temporary change to origin (because it being a singleton)
113+
$adapter->setPathPrefix($pathPrefix);
114+
throw new FileLoadingException(
115+
sprintf('The directive .. typo3:site-set-settings:: cannot find the source at %s. ', $path)
116+
);
82117
}
83118

84119
$contents = $origin->read($path);
85120

121+
// Revert temporary change to origin (because it being a singleton).
122+
$adapter->setPathPrefix($pathPrefix);
123+
86124
if ($contents === false) {
87125
throw new FileLoadingException(sprintf('The .. typo3:site-set-settings:: cannot load file from path %s. ', $path));
88126
}

tests/Integration/tests/roles/role-composer/expected/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ <h1>Document Title<a class="headerlink" href="#document-title" data-bs-toggle="m
1313
data-homepage="https://typo3.org/"
1414
data-documentation=""
1515
data-issues="https://github.com/TYPO3/testing-framework/issues"
16-
data-source="https://github.com/TYPO3/testing-framework/tree/8.2.0"
16+
data-source="https://github.com/TYPO3/testing-framework/tree/8.2.1"
1717
>
1818
typo3/testing-framework
1919
</a> to test projects based on
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
settings:
2+
styles.content.defaultHeaderType:
3+
default: 2
4+
label: 'Default Header type'
5+
type: int
6+
description: 'Enter the number of the header layout to be used by default'
7+
styles.content.shortcut.tables:
8+
default: tt_content
9+
label: 'List of accepted tables'
10+
type: string
11+
description: ''
12+
styles.content.allowTags:
13+
default: 'a, abbr, acronym, address, article, aside, b, bdo, big, blockquote, br, caption, center, cite, code, col, colgroup, dd, del, dfn, dl, div, dt, em, figure, font, footer, header, h1, h2, h3, h4, h5, h6, hr, i, img, ins, kbd, label, li, link, meta, nav, ol, p, pre, q, s, samp, sdfield, section, small, span, strike, strong, style, sub, sup, table, thead, tbody, tfoot, td, th, tr, title, tt, u, ul, var'
14+
label: 'List of allowed HTML tags when rendering RTE content'
15+
type: string
16+
description: ''
17+
styles.content.image.lazyLoading:
18+
default: lazy
19+
label: 'Default settings for browser-native image lazy loading'
20+
type: string
21+
enum:
22+
lazy: 'Lazy'
23+
eager: 'Eager'
24+
auto: 'Auto'
25+
description: 'Can be "lazy" (browsers could choose to load images later), "eager" (load images right away) or "auto" (browser will determine whether the image should be lazy loaded or not)'
26+
styles.content.image.imageDecoding:
27+
default: ''
28+
label: 'Default settings for an image decoding hint to the browser'
29+
type: string
30+
enum:
31+
sync: 'Sync'
32+
async: 'Asynchronous'
33+
auto: 'Auto'
34+
description: 'Can be "sync" (synchronously for atomic presentation with other content), "async" (asynchronously to avoid delaying presentation of other content), "auto" (no preference in decoding mode) or an empty value to omit the usage of the decoding attribute (same as "auto")'
35+
styles.content.textmedia.maxW:
36+
default: 600
37+
label: 'Max Image/Media Width'
38+
type: int
39+
description: 'This indicates that maximum number of pixels (width) a block of media elements inserted as content is allowed to consume'
40+
styles.content.textmedia.maxWInText:
41+
default: 300
42+
label: 'Max Image/Media Width (Text)'
43+
type: int
44+
description: 'Same as above, but this is the maximum width when text is wrapped around an block of media elements. Default is 50% of the normal Max Media Item Width'
45+
styles.content.textmedia.columnSpacing:
46+
default: 10
47+
label: 'Advanced, Column space'
48+
type: int
49+
description: 'Horizontal distance between media elements in a block in content elements of type "Media & Images". If you change this manually in your CSS, you need to adjust this setting accordingly'
50+
styles.content.textmedia.rowSpacing:
51+
default: 10
52+
label: 'Advanced, Row space'
53+
type: int
54+
description: 'Vertical distance after each media elements row in content elements of type ""Text & Media". If you change this manually in your CSS, you need to adjust this setting accordingly'
55+
styles.content.textmedia.textMargin:
56+
default: 10
57+
label: 'Advanced, Margin to text'
58+
type: int
59+
description: 'Horizontal distance between an imageblock and text in content elements of type "Text & Images"'
60+
styles.content.textmedia.borderColor:
61+
default: '#000000'
62+
label: 'Media element border, color'
63+
type: color
64+
description: 'Bordercolor of media elements in content elements when "Border"-option for an element is set'
65+
styles.content.textmedia.borderWidth:
66+
default: 2
67+
label: 'Media element border, thickness'
68+
type: int
69+
description: 'Thickness of border around media elements in content elements when "Border"-option for element is set'
70+
styles.content.textmedia.borderPadding:
71+
default: 0
72+
label: 'Media element border, padding'
73+
type: int
74+
description: 'Padding left and right to the media element, around the border'
75+
styles.content.textmedia.linkWrap.width:
76+
default: 800m
77+
label: 'Click-enlarge Media Width'
78+
type: string
79+
description: 'This specifies the width of the enlarged media element when click-enlarge is enabled'
80+
styles.content.textmedia.linkWrap.height:
81+
default: 600m
82+
label: 'Click-enlarge Media Height'
83+
type: string
84+
description: 'This specifies the height of the enlarged media element when click-enlarge is enabled'
85+
styles.content.textmedia.linkWrap.newWindow:
86+
default: false
87+
label: 'Advanced, New window'
88+
type: bool
89+
description: "If set, every click-enlarged media element will open in it's own popup window and not the current popup window (which may have a wrong size for the media element to fit in)"
90+
styles.content.textmedia.linkWrap.lightboxEnabled:
91+
default: false
92+
label: 'Lightbox click-enlarge rendering'
93+
type: bool
94+
description: 'Whether media elements with click-enlarge checked should be rendered lightbox-compliant'
95+
styles.content.textmedia.linkWrap.lightboxCssClass:
96+
default: lightbox
97+
label: 'Lightbox CSS class'
98+
type: string
99+
description: 'Which CSS class to use for lightbox links (only applicable if lightbox rendering is enabled)'
100+
styles.content.textmedia.linkWrap.lightboxRelAttribute:
101+
default: 'lightbox[{field:uid}]'
102+
label: 'Lightbox rel="" attribute'
103+
type: string
104+
description: 'Which rel="" attribute to use for lightbox links (only applicable if lightbox rendering is enabled)'
105+
styles.content.links.extTarget:
106+
default: _blank
107+
label: 'Target for external links'
108+
type: string
109+
description: ''
110+
styles.content.links.keep:
111+
default: path
112+
label: 'Parts to keep when building links'
113+
type: string
114+
description: 'Comma separated list of the link parts to show when building the link-text: scheme,path,query. Example: "" (empty) => www.example.com, "scheme,path" => http://www.example.com'
115+
styles.templates.templateRootPath:
116+
default: ''
117+
label: 'Path of Fluid Templates for all defined content elements'
118+
type: string
119+
description: ''
120+
styles.templates.partialRootPath:
121+
default: ''
122+
label: 'Path of Fluid Partials for all defined content elements'
123+
type: string
124+
description: ''
125+
styles.templates.layoutRootPath:
126+
default: ''
127+
label: 'Path of Fluid Layouts for all defined content elements'
128+
type: string
129+
description: ''

0 commit comments

Comments
 (0)