Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimization Detective's XPath expressions in HTML can be erroneously interpreted as JS/CSS comments #1947

Open
westonruter opened this issue Mar 19, 2025 · 5 comments
Assignees
Labels
Needs Discussion Anything that needs a discussion/agreement [Plugin] Optimization Detective Issues for the Optimization Detective plugin [Type] Bug An existing feature is broken

Comments

@westonruter
Copy link
Member

westonruter commented Mar 19, 2025

Bug Description

I just discovered that certain plugins (example) may implement HTML compression that collapses whitespace and removes JS/CSS comments by means of regular expressions. For example (do not do this):

$buffer = preg_replace( '@\/\*(.*?)\*\/@s', ' ', $buffer );

This is dangerous and will often result in corrupted HTML markup.

This has the effect of turning this:

<p>This is an XPath: <code>/HTML/BODY/*[1][self::DIV]</code></p>

<p>This is a Script:</p>

<pre class="wp-block-code"><code>&lt;script>
/* example script */
&lt;/script></code></pre>

Into:

<p>This is an XPath: <code>/HTML/BODY &lt;/script&gt;</code></pre>

This is because the regular expression starts matching the supposed comment start in the first paragraph which mentions /HTML/BODY/* and then it terminates the "comment" in the code sample in the third block.

This will break pages that contain data-od-xpath attributes which Optimization Detective adds when detection is needed.

Granted, such regular expression logic will invariably cause many more problems than this, but we might want to consider hardening the data-od-xpath attribute to prevent this from happening, namely by doing something like base64-encoding it in the attribute via base64_encode() in PHP. It could then be converted back to the non-encoded form in JavaScript via atob().

Just something to consider.

@westonruter westonruter added [Plugin] Optimization Detective Issues for the Optimization Detective plugin [Type] Bug An existing feature is broken Needs Discussion Anything that needs a discussion/agreement labels Mar 19, 2025
@github-project-automation github-project-automation bot moved this to Not Started/Backlog 📆 in WP Performance 2025 Mar 19, 2025
@nani-samireddy
Copy link
Contributor

Hi, I'm a bit new to the performance plugin but I would like to work on this.

@sarthak-19
Copy link
Contributor

Hi, @nani-samireddy welcome to WP-Performance community, feel free to reach out if stuck while solving this issue. 😄

@nani-samireddy
Copy link
Contributor

nani-samireddy commented Mar 20, 2025

Thank you @sarthak-19

I have spent few hours on this and here are my findings:

Here are setting the xpath attribute in the PHP. So we can change the following

if ( $tracked_in_url_metrics && $needs_detection ) {
$processor->set_meta_attribute( 'xpath', $processor->get_xpath() );
}

To

if ( $tracked_in_url_metrics && $needs_detection ) {
	$processor->set_meta_attribute( 'xpath', base64_encode( $processor->get_xpath() ) );
}

And in the Javascript we are retrieving here:

const breadcrumbedElementsMap = new Map(
[ ...breadcrumbedElements ].map(
/**
* @param {HTMLElement} element
* @return {[HTMLElement, string]} Tuple of element and its XPath.
*/
( element ) => [ element, element.dataset.odXpath ]
)
);

To

const breadcrumbedElementsMap = new Map(
	[ ...breadcrumbedElements ].map(
		/**
		 * @param {HTMLElement} element
		 * @return {[HTMLElement, string]} Tuple of element and its XPath.
		 */
		( element ) => [ element, atob( element.dataset.odXpath ) ]
	)
);

I tested this on release/3.4.1 and it is working fine.

But as I'm new to performance plugins cloud anyone help me to resolve this error on trunk

Image

Because of this error I tested this on release/3.4.1 😅

also please let me know your thoughts on the above solution.

cc: @westonruter

@westonruter
Copy link
Member Author

@nani-samireddy Hello! Welcome. And your research looks correct.

FYI: The latest release is release/2025-03-17 but testing on trunk is good here.

Nevertheless, I'm not sure yet whether we should implement this change. It's something I opened to discuss. Given it addresses a specific compatibility problem observed in another plugin, I'm wanting to find out if there are more examples of this where we should go ahead and implement this workaround.

In regards to the error you're seeing, this is expected when using wp-env, because it still doesn't support loopback requests. Nevertheless, the plugin specifically excludes this from blocking pages from being optimized by checking if it is a local env:

array(
'test' => ! od_is_rest_api_unavailable() || ( wp_get_environment_type() === 'local' && ! function_exists( 'tests_add_filter' ) ),
'reason' => __( 'Page is not optimized because the REST API for storing URL Metrics is not available.', 'optimization-detective' ),
),

@nani-samireddy
Copy link
Contributor

@westonruter Thank you for the warm welcome. As you mentioned, let's wait for more insights and other opinions on this and move forward accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Discussion Anything that needs a discussion/agreement [Plugin] Optimization Detective Issues for the Optimization Detective plugin [Type] Bug An existing feature is broken
Projects
Status: Not Started/Backlog 📆
Development

No branches or pull requests

3 participants