core/modules/rest/src/Plugin/views/display/RestExport.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/core/modules/rest/src/Plugin/views/display/RestExport.php b/core/modules/rest/src/Plugin/views/display/RestExport.php index eefdf39..e3a587c 100644 --- a/core/modules/rest/src/Plugin/views/display/RestExport.php +++ b/core/modules/rest/src/Plugin/views/display/RestExport.php @@ -312,7 +312,7 @@ public function execute() { public function render() { $build = array(); $build['#markup'] = $this->renderer->executeInRenderContext(new RenderContext(), function() { - return ViewsRenderPipelineSafeString::create($this->view->style_plugin->render()); + return $this->view->style_plugin->render(); }); $this->view->element['#content_type'] = $this->getMimeType(); @@ -324,6 +324,19 @@ public function render() { $build['#markup'] = SafeMarkup::checkPlain($build['#markup']); $build['#suffix'] = ''; } + elseif ($this->view->getRequest()->getFormat($this->view->element['#content_type']) !== 'html') { + // This display plugin is primarily for returning non-HTML formats. + // However, we still invoke the renderer to collect cacheability metadata. + // Because the renderer is designed for HTML rendering, it filters + // #markup for XSS unless it is already known to be safe, but that filter + // only works for HTML. Therefore, we mark the contents as safe to bypass + // the filter. So long as we are returning this in a non-HTML response + // (checked above), this is safe, because an XSS attack only works when + // executed by an HTML agent. + // @todo Decide how to support non-HTML in the render API in + // https://www.drupal.org/node/2501313. + $build['#markup'] = ViewsRenderPipelineSafeString::create($build['#markup']); + } parent::applyDisplayCachablityMetadata($build);