You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2026-10-23 21:28:56 +03:00
Verify that page/section links point at an existing section.
Only same-page section links were verified, so a page/section link with a bad section or a missing leading slash would silently render a broken anchor. Require a link section to begin with a slash and, after all pages have been rendered, verify that each page/section link points at a section that exists on the target page. Links to a page that is not part of the build (e.g. a partial build) are skipped. Also fix the news link to the 2.59.0 release notes, which was missing the leading slash and pointed at a broken anchor.
This commit is contained in:
@@ -355,6 +355,9 @@ eval
|
||||
}
|
||||
}
|
||||
|
||||
# Verify page/section links now that all pages have been rendered and their section anchors are known
|
||||
$oManifest->linkVerify();
|
||||
|
||||
# Cache the manifest (mostly useful for testing rendering changes in the code)
|
||||
if (!$bNoCache && !$bCacheOnly)
|
||||
{
|
||||
|
||||
@@ -620,6 +620,38 @@ sub renderOutGet
|
||||
);
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# linkVerify
|
||||
#
|
||||
# Verify that every page/section link points at a section that exists. This must be done after all pages have been rendered since
|
||||
# the section anchors for a page are only known once it has been rendered. Links to a page that was not rendered in this build
|
||||
# (e.g. a partial build with --include/--exclude) are skipped since the section anchors are not available to check.
|
||||
####################################################################################################################################
|
||||
sub linkVerify
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
# Assign function parameters, defaults, and log debug info
|
||||
my ($strOperation) = logDebugParam(__PACKAGE__ . '->linkVerify');
|
||||
|
||||
foreach my $rhLink (@{$self->{rhyLinkVerify} || []})
|
||||
{
|
||||
# Skip if the linked page was not rendered in this build
|
||||
next if (!defined($self->{hPageAnchor}{$rhLink->{page}}));
|
||||
|
||||
# Error if the section does not exist on the page
|
||||
if (!defined($self->{hPageAnchor}{$rhLink->{page}}{substr($rhLink->{section}, 1)}))
|
||||
{
|
||||
confess &log(
|
||||
ERROR,
|
||||
"page '$rhLink->{source}' has a link to page '$rhLink->{page}' section '$rhLink->{section}' that does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
# Return from function and log return values if any
|
||||
return logDebugReturn($strOperation);
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# cacheKey
|
||||
####################################################################################################################################
|
||||
|
||||
@@ -200,6 +200,9 @@ sub new
|
||||
$self->required($strPath);
|
||||
}
|
||||
}
|
||||
|
||||
# Register the section anchor map so cross-page links to this page can be verified
|
||||
$self->{oManifest}->{hPageAnchor}{$self->{strRenderOutKey}} = $self->sectionAnchorMap();
|
||||
}
|
||||
|
||||
if (defined($self->{oDoc}))
|
||||
@@ -588,6 +591,40 @@ sub isRequired
|
||||
defined(${$self->{oSectionRequired}}{$strPath}) ? true : false;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# sectionAnchorMap
|
||||
#
|
||||
# Build the set of section anchors for this page. An anchor is the section id prefixed with the parent anchors, which matches the
|
||||
# anchor generated by the html renderer. A section with anchor set to no-inherit does not include its parent anchors.
|
||||
####################################################################################################################################
|
||||
sub sectionAnchorMap
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $rhAnchor = {};
|
||||
|
||||
foreach my $strPath (keys(%{$self->{oSection}}))
|
||||
{
|
||||
my @stryId;
|
||||
my $oSection = ${$self->{oSection}}{$strPath};
|
||||
|
||||
# Prepend section ids walking up the parents until a section that does not inherit the parent anchor
|
||||
while (defined($oSection))
|
||||
{
|
||||
unshift(@stryId, $oSection->paramGet('id'));
|
||||
|
||||
last if $oSection->paramTest(XML_SECTION_PARAM_ANCHOR, XML_SECTION_PARAM_ANCHOR_VALUE_NOINHERIT);
|
||||
|
||||
my $strParentPath = $oSection->paramGet('path-parent', false);
|
||||
$oSection = defined($strParentPath) ? ${$self->{oSection}}{$strParentPath} : undef;
|
||||
}
|
||||
|
||||
$rhAnchor->{join('/', @stryId)} = true;
|
||||
}
|
||||
|
||||
return $rhAnchor;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# processTag
|
||||
####################################################################################################################################
|
||||
@@ -627,6 +664,12 @@ sub processTag
|
||||
my $strPage = $self->variableReplace($oTag->paramGet('page', false));
|
||||
my $strSection = $oTag->paramGet('section', false);
|
||||
|
||||
# A section link must begin with / since the leading / is stripped to form the anchor
|
||||
if (defined($strSection) && substr($strSection, 0, 1) ne '/')
|
||||
{
|
||||
confess &log(ERROR, "link section '${strSection}' must begin with '/'");
|
||||
}
|
||||
|
||||
# If a page/section link points to the current page then remove the page portion
|
||||
if (defined($strPage) && defined($strSection) && defined($self->{strRenderOutKey}) &&
|
||||
$strPage eq $self->{strRenderOutKey})
|
||||
@@ -637,6 +680,15 @@ sub processTag
|
||||
# If this is a page URL
|
||||
if (defined($strPage))
|
||||
{
|
||||
# Record the page/section link so it can be verified once all pages have been rendered and their section
|
||||
# anchors are known
|
||||
if (defined($strSection))
|
||||
{
|
||||
push(
|
||||
@{$self->{oManifest}->{rhyLinkVerify}},
|
||||
{source => $self->{strRenderOutKey}, page => $strPage, section => $strSection});
|
||||
}
|
||||
|
||||
# If the page wasn't rendered then point at the website
|
||||
if (!defined($self->{oManifest}->renderOutGet($strType, $strPage, true)))
|
||||
{
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<list-item>Exit async archive-push on first error (David Steele)</list-item>
|
||||
</list>
|
||||
|
||||
<p>See the <link page="release" section="2.59.0">2.59.0 Release Notes</link> for additional features and improvements.</p>
|
||||
<p>See the <link page="release" section="/2.59.0">2.59.0 Release Notes</link> for additional features and improvements.</p>
|
||||
</section>
|
||||
|
||||
<section id="note">
|
||||
|
||||
Reference in New Issue
Block a user