Skip to content

Render cypher_raw output as HTML instead of wikitext#1069

Merged
malberts merged 2 commits into
masterfrom
fix/1067-cypher-raw-html
Jul 17, 2026
Merged

Render cypher_raw output as HTML instead of wikitext#1069
malberts merged 2 commits into
masterfrom
fix/1067-cypher-raw-html

Conversation

@JeroenDeDauw

@JeroenDeDauw JeroenDeDauw commented Jul 16, 2026

Copy link
Copy Markdown
Member

Fixes #1067

{{#cypher_raw}} handed its JSON to the parser as wikitext, so any URL in a returned value
got autolinked. The closing quote of the JSON string was swallowed into the link and
percent-encoded, leaving the reader with invalid JSON and <a> tags inside the <pre>.

Returns the output as HTML instead, the way #view and #neowiki_value already do, and the
way {{#sparql_raw}} was fixed in #1051. isHTML is the flag that does the work: it
strip-armours the text so the parser leaves it alone. noparse is already the default for a
parser-function return and is included only to match the shape used elsewhere.

The error path gets the same treatment. Unlike the SPARQL side, no Cypher error message
carries the endpoint URL, since backendUnavailable passes no params; a URL reaches the
message by being echoed back from the offending query.

Returning an array means changing the : string return type to : array on
CypherRawParserFunction::handle() and on the cypher_raw closure in Neo4jPlugin, which
would otherwise fatal with a TypeError.

Testing

The existing unit tests could not catch this: they assert on what handle() returns, while
the corruption happens afterwards, inside the parser. CypherRawParserFunctionParsingTest
parses wikitext through a real Parser and asserts on what a reader ends up with, mirroring
SparqlRawParserFunctionParsingTest. Verified failing before the fix and passing after.

The second commit closes a gap found in review: the unit tests exercised the returned HTML but
never the flags that carry it, so replacing asHtml()'s return with [ $html ] — dropping both
flags and reintroducing the corruption — left all eight of them green. It adds the two armour
tests the sparql_raw sibling already has; they now fail against exactly that mutation.

AI-authored — Claude Code, Opus 4.8 (max); fixing a filed issue at @JeroenDeDauw's direction; not human-reviewed; verified by a parser-level regression test seen failing before the fix and passing after, by the issue's exact query rendered on a live dev wiki before and after, and by mutation-checking the new armour tests; full PHPUnit suite (1749 tests) and make cs green.

JeroenDeDauw and others added 2 commits July 17, 2026 01:42
Fixes #1067

`{{#cypher_raw}}` handed its JSON to the parser as wikitext, so any URL in a returned value
got autolinked. The closing quote of the JSON string was swallowed into the link and
percent-encoded, leaving the reader with invalid JSON and `<a>` tags inside the `<pre>`.

Returns the output as HTML instead, the way `#view` and `#neowiki_value` already do, and the
way `{{#sparql_raw}}` was fixed in #1051. `isHTML` is the flag that does the work: it
strip-armours the text so the parser leaves it alone. `noparse` is already the default for a
parser-function return and is included only to match the shape used elsewhere.

The error path gets the same treatment, as the store's message can itself carry a URL.

Returning an array requires widening the `: string` return types on
`CypherRawParserFunction::handle()` and on the `cypher_raw` closure in `Neo4jPlugin`, which
would otherwise fatal with a `TypeError`.

## Testing

The existing unit tests could not catch this: they assert on what `handle()` returns, while
the corruption happens afterwards, inside the parser. `CypherRawParserFunctionParsingTest`
parses wikitext through a real `Parser` and asserts on what a reader ends up with, mirroring
`SparqlRawParserFunctionParsingTest`. Verified failing before the fix and passing after.

Co-Authored-By: Claude Opus 4.8 (max) <noreply@anthropic.com>
The unit tests exercised the returned HTML but never the flags that carry it: replacing asHtml()'s return with [ $html ], which drops both flags and reintroduces the corruption, left all eight of them green. Only the parser-level test caught it.

Adds the two armour tests the sparql_raw sibling already has, covering the result and the error path.

Also makes the error-path rationale precise: unlike the SPARQL side, no Cypher error message carries the endpoint URL, since backendUnavailable passes no params. A URL reaches the message by being echoed back from the offending query.

Co-Authored-By: Claude Opus 4.8 (max) <noreply@anthropic.com>
@JeroenDeDauw
JeroenDeDauw marked this pull request as ready for review July 17, 2026 13:01
@JeroenDeDauw JeroenDeDauw added the security alert('xss'); label Jul 17, 2026
@malberts malberts assigned malberts and unassigned malberts Jul 17, 2026
@malberts
malberts merged commit 7146574 into master Jul 17, 2026
6 checks passed
@malberts
malberts deleted the fix/1067-cypher-raw-html branch July 17, 2026 17:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security alert('xss');

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cypher_raw corrupts URLs in its output by returning wikitext instead of HTML

2 participants