php-mustache icon indicating copy to clipboard operation
php-mustache copied to clipboard

Lambda to return text instead of parsable template syntax

Open Krinkle opened this issue 6 months ago • 6 comments

I spent a good amount of time today figuring out why a certain code path works fine during development with https://github.com/bobthecow/mustache.php, but crashes in a container for production, where we use php-mustache.

The repro reduces down to the following:

$templateContent = '
<section>
	{{#lines}}
	<code>{{{html}}}</code>
	{{/lines}}
</section>
';

$text = trim( <<<TEXT
yle={{ // eslint-disable-line react/prop-types\n    padding: \"1em\",\n    \"color\": \"#aaa\"\n  }}> <i>Could not r
TEXT );
$html = static function () use ( $text ) {
	return $text;
};
$data = [
	'lines' => [
		[
			'html' => $html,
		],
	],
];
$partials = [];

if ( class_exists( Mustache::class ) ) {
	// Prefer native php-mustache (PECL) when available
	$mustache = new Mustache();
	return $mustache->render( $templateContent, $data, $partials );
} else {
	// Fallback to composer bobthecow/mustache.php for local dev server
	$mustache = new Mustache_Engine( [
		'entity_flags' => ENT_QUOTES,
		'partials' => $partials,
	] );
	return $mustache->render( $templateContent, $data );
}
Fatal error: Uncaught MustacheException: Reached bottom of stack
in /Users/krinkle/Development/labs-codesearch/frontend/index.php:53
Stack trace:
#0 /Users/krinkle/Development/labs-codesearch/frontend/index.php(53): Mustache->render('\n<section>\n\t{{#...', Array, Array) 

Background

The above was reduced down from https://github.com/wikimedia/labs-codesearch . The live example works at the moment, because it's rendering the results client-side in JavaScript. I'm working on moving this to the backend. In doing so, 99% of search queries rendered without issue and render identically in pixel-perfect manner. But for one rare query, with very large and numerous results, it would crash. I mistakenly attributed this to result size given that all shorter results worked fined, but it turned out the larger result size happen to contain the above unusual text to display, which is rather Mustache-like.

The function in question normally performs a regular expression, and highlights portions that match your search query and then HTML-escapes it. https://gerrit.wikimedia.org/g/labs/codesearch/+/refs/changes/48/1056248/5/frontend/src/Model.php#394

When doing this eagerly, and setting the string in the Mustache data, it all works fine. But when doing the computation and string allocations lazily, it started failing for this one unusual input.

I failed to understand that this error related to something in with "my" template stack, because I had already ruled out all partials or and any unbalanced sections in "my" code. But it turns out there was some Mustache-like syntax in one of the results.

Question: Is there a way to disable parsing/interpretation of the lambda return value as anything other than a data value to be displayed as {{x}} or {{{x}}} accordingly? This would be great for interoperability.

Krinkle avatar Aug 08 '24 22:08 Krinkle