Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,26 @@ public function is_url_absolute() {
return WPURL::can_parse( $this->get_raw_url() );
}

/**
* Returns true if the currently matched URL is a fragment-only reference,
* such as `#section` or a bare `#`.
*
* A fragment-only reference points within the document that contains it,
* so it has no origin of its own to rewrite. URL parsers strip leading C0
* control and space characters before resolving a reference, so a value
* like ` #section` counts as one too.
*
* @return bool Whether the currently matched URL is a fragment-only reference.
*/
public function is_fragment_only_reference() {
$raw_url = $this->get_raw_url();
if ( ! is_string( $raw_url ) ) {
return false;
}

return 0 === strpos( ltrim( $raw_url, "\x00..\x20" ), '#' );
}

public function get_inspected_attribute_name() {
if ( '#tag' !== $this->get_token_type() ) {
return false;
Expand Down
22 changes: 22 additions & 0 deletions components/DataLiberation/Tests/BlockMarkupUrlProcessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -467,4 +467,26 @@ public function test_css_urls_with_regular_attributes() {
$expected = '<img src="https://new.com/replaced.png" style="border-image: url(&quot;https://new.com/replaced.png&quot;);">';
$this->assertEquals( $expected, $p->get_updated_html() );
}

/**
*
* @dataProvider provider_test_is_fragment_only_reference
*/
public function test_is_fragment_only_reference( $markup, $expected ) {
$p = new BlockMarkupUrlProcessor( $markup, 'https://example.com' );
$this->assertTrue( $p->next_url(), 'Failed to find the URL in the markup.' );
$this->assertSame( $expected, $p->is_fragment_only_reference() );
}

public static function provider_test_is_fragment_only_reference() {
return array(
'Named fragment' => array( '<a href="#section">Jump</a>', true ),
'Bare hash' => array( '<a href="#">Top</a>', true ),
'Leading space' => array( '<a href=" #section">Jump</a>', true ),
'Leading tab and newline' => array( "<a href=\"\t\n#section\">Jump</a>", true ),
'Fragment in a block attribute' => array( '<!-- wp:button {"url":"#login"} -->', true ),
'Absolute URL with a fragment' => array( '<a href="https://example.com/page#section">Deep link</a>', false ),
'Relative path with a fragment' => array( '<a href="/page#section">Page</a>', false ),
);
}
}
30 changes: 30 additions & 0 deletions components/DataLiberation/Tests/RewriteUrlsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,36 @@ public static function provider_test_wp_rewrite_urls() {
'https://🚀-science.com/science',
'https://science.wordpress.org',
),
'Fragment-only reference in an HTML attribute is left alone' => array(
'<a href="#section">Jump</a>',
'<a href="#section">Jump</a>',
'https://legacy-blog.com',
'https://modern-webstore.org',
),
'Bare hash in an HTML attribute is left alone' => array(
'<a href="#">Placeholder</a>',
'<a href="#">Placeholder</a>',
'https://legacy-blog.com',
'https://modern-webstore.org',
),
'Fragment-only reference with leading whitespace is left alone' => array(
'<a href=" #section">Jump</a>',
'<a href=" #section">Jump</a>',
'https://legacy-blog.com',
'https://modern-webstore.org',
),
'Fragment-only reference in a block attribute is left alone' => array(
'<!-- wp:button {"url":"#login"} -->',
'<!-- wp:button {"url":"#login"} -->',
'https://legacy-blog.com',
'https://modern-webstore.org',
),
'Absolute URL carrying a fragment is still rewritten and keeps its fragment' => array(
'<a href="https://legacy-blog.com/page#section">Deep link</a>',
'<a href="https://modern-webstore.org/page#section">Deep link</a>',
'https://legacy-blog.com',
'https://modern-webstore.org',
),
);
}

Expand Down
13 changes: 12 additions & 1 deletion components/DataLiberation/URL/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,18 @@ function wp_rewrite_urls( $options ) {
while ( $p->next_url() ) {
$token_type = $p->get_token_type();
$raw_url = $p->get_raw_url();
$cache_key = $mapping_cache_key . "\0" . $token_type . "\0" . $raw_url;

/*
* Leave fragment-only references alone. Resolving one against the base
* URL makes it look like a child of the site being imported from, and
* rewriting it then turns an in-page anchor into a link somewhere else
* entirely: `#section` becomes `/#section`, and a bare `#` becomes `/`.
*/
if ( $p->is_fragment_only_reference() ) {
continue;
}

$cache_key = $mapping_cache_key . "\0" . $token_type . "\0" . $raw_url;

$cached = $rewrite_cache->get( $cache_key );
if ( null !== $cached ) {
Expand Down
Loading