mirror of
https://github.com/sbrl/Pepperminty-Wiki.git
synced 2024-11-22 04:23:01 +00:00
Update parser engine to handle comments as untrusted
This commit is contained in:
parent
d1c161f26a
commit
3dcb8b5b1e
5 changed files with 26 additions and 8 deletions
15
Changelog.md
15
Changelog.md
|
@ -1,6 +1,21 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
This file holds the changelog for Pepperminty Wiki. This is the master list of things that have changed (second only to the commit history!) - though the information for any particular release can also be found in the description of it's page for every release made on GitHub too.
|
This file holds the changelog for Pepperminty Wiki. This is the master list of things that have changed (second only to the commit history!) - though the information for any particular release can also be found in the description of it's page for every release made on GitHub too.
|
||||||
|
|
||||||
|
|
||||||
|
## v0.19-dev
|
||||||
|
> The update that changed the world! Turn everything upside-down.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- [Module API] Added new extra data system. See `parser-parsedown` and `page-edit` for an example.
|
||||||
|
- Extra data is packed into a zip archive, which is packed into `index.php` via [`__halt_compiler();`](https://devdocs.io/php/function.halt-compiler)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Core sharding: split `core.php` into multiple files
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- [Module API] Not often I have a removed section! Remove remote file system.
|
||||||
|
|
||||||
|
|
||||||
## v0.18
|
## v0.18
|
||||||
|
|
||||||
_(No changes have been made since the last beta release.)_
|
_(No changes have been made since the last beta release.)_
|
||||||
|
|
|
@ -34,10 +34,11 @@ function add_parser($name, $parser_code, $hash_generator) {
|
||||||
* The specified parser may (though it's unlikely) render it to other things.
|
* The specified parser may (though it's unlikely) render it to other things.
|
||||||
* @package core
|
* @package core
|
||||||
* @param string $source The source to render.
|
* @param string $source The source to render.
|
||||||
* @param string $use_cache Whether to use the on-disk cache. Has no effect if parser caching is disabled in peppermint.json, or the source string is too small.
|
* @param bool $use_cache Whether to use the on-disk cache. Has no effect if parser caching is disabled in peppermint.json, or the source string is too small.
|
||||||
|
* @param bool $untrusted Whether the source string is 'untrusted' - i.e. a user comment. Untrusted source disallows HTML and protects against XSS attacks.
|
||||||
* @return string The source rendered to HTML.
|
* @return string The source rendered to HTML.
|
||||||
*/
|
*/
|
||||||
function parse_page_source($source, $use_cache = true) {
|
function parse_page_source($source, $untrusted = false, $use_cache = true) {
|
||||||
global $settings, $paths, $parsers, $version;
|
global $settings, $paths, $parsers, $version;
|
||||||
$start_time = microtime(true);
|
$start_time = microtime(true);
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ function parse_page_source($source, $use_cache = true) {
|
||||||
$result .= "\n<!-- cache: hit, id: $cache_id, took: " . round((microtime(true) - $start_time)*1000, 5) . "ms -->\n";
|
$result .= "\n<!-- cache: hit, id: $cache_id, took: " . round((microtime(true) - $start_time)*1000, 5) . "ms -->\n";
|
||||||
}
|
}
|
||||||
if($result == null) {
|
if($result == null) {
|
||||||
$result = $parsers[$settings->parser]["parser"]($source);
|
$result = $parsers[$settings->parser]["parser"]($source, $untrusted);
|
||||||
// If we should use the cache and we failed to write to it, warn the admin.
|
// If we should use the cache and we failed to write to it, warn the admin.
|
||||||
// It's not terribible if we can't write to the cache directory (so we shouldn't stop dead & refuse service), but it's still of concern.
|
// It's not terribible if we can't write to the cache directory (so we shouldn't stop dead & refuse service), but it's still of concern.
|
||||||
if($use_cache && !file_put_contents($cache_file, $result))
|
if($use_cache && !file_put_contents($cache_file, $result))
|
||||||
|
|
|
@ -461,7 +461,7 @@ function render_comments($comments_data, $depth = 0)
|
||||||
$result .= "\t<div class='comment' id='comment-$comment->id' data-comment-id='$comment->id'>\n";
|
$result .= "\t<div class='comment' id='comment-$comment->id' data-comment-id='$comment->id'>\n";
|
||||||
$result .= "\t<p class='comment-header'><span class='name'>" . page_renderer::render_username($comment->username ?? "<em>Unknown</em>") . "</span> said:</p>";
|
$result .= "\t<p class='comment-header'><span class='name'>" . page_renderer::render_username($comment->username ?? "<em>Unknown</em>") . "</span> said:</p>";
|
||||||
$result .= "\t<div class='comment-body'>\n";
|
$result .= "\t<div class='comment-body'>\n";
|
||||||
$result .= "\t\t" . parse_page_source($comment->message);
|
$result .= "\t\t" . parse_page_source($comment->message, true);
|
||||||
$result .= "\t</div>\n";
|
$result .= "\t</div>\n";
|
||||||
$result .= "\t<div class='reply-box-container'></div>\n";
|
$result .= "\t<div class='reply-box-container'></div>\n";
|
||||||
$result .= "\t<p class='comment-footer'>";
|
$result .= "\t<p class='comment-footer'>";
|
||||||
|
|
|
@ -18,8 +18,9 @@ register_module([
|
||||||
|
|
||||||
$parser = new PeppermintParsedown();
|
$parser = new PeppermintParsedown();
|
||||||
$parser->setInternalLinkBase("?page=%s");
|
$parser->setInternalLinkBase("?page=%s");
|
||||||
add_parser("parsedown", function($source) use ($parser) {
|
add_parser("parsedown", function($source, $untrusted) use ($parser) {
|
||||||
global $settings;
|
global $settings;
|
||||||
|
$parser->setsafeMode($untrusted || $settings->all_untrusted);
|
||||||
$parser->setMarkupEscaped($settings->clean_raw_html);
|
$parser->setMarkupEscaped($settings->clean_raw_html);
|
||||||
$result = $parser->text($source);
|
$result = $parser->text($source);
|
||||||
|
|
||||||
|
@ -429,8 +430,8 @@ class PeppermintParsedown extends ParsedownExtra
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles parsing out templates - recursively - and the parameter stack associated with it.
|
* Handles parsing out templates - recursively - and the parameter stack associated with it.
|
||||||
* @param [type] $source [description]
|
* @param string $source The source string to process.
|
||||||
* @return [type] [description]
|
* @return array The parsed result
|
||||||
*/
|
*/
|
||||||
protected function templateHandler($source)
|
protected function templateHandler($source)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
"parser_cache_min_size": { "type": "number", "description": "The minimum size a source string must be (in bytes) before it's considered eligible for caching.", "default": 1024 },
|
"parser_cache_min_size": { "type": "number", "description": "The minimum size a source string must be (in bytes) before it's considered eligible for caching.", "default": 1024 },
|
||||||
"interwiki_index_location": { "type": "text", "description": "The location to find the interwiki wiki definition file, which contains a list of wikis along with their names, prefixes, and root urls. May be a URL, or simply a file path - as it's passed to file_get_contents(). If left blank, interwiki link parsing is disabled.", "default": null },
|
"interwiki_index_location": { "type": "text", "description": "The location to find the interwiki wiki definition file, which contains a list of wikis along with their names, prefixes, and root urls. May be a URL, or simply a file path - as it's passed to file_get_contents(). If left blank, interwiki link parsing is disabled.", "default": null },
|
||||||
"clean_raw_html": { "type": "checkbox", "description": "Whether page sources should be cleaned of HTML before rendering. It is STRONGLY recommended that you keep this option turned on.", "default": true },
|
"clean_raw_html": { "type": "checkbox", "description": "Whether page sources should be cleaned of HTML before rendering. It is STRONGLY recommended that you keep this option turned on.", "default": true },
|
||||||
|
"all_untrusted": { "type": "checkbox", "description": "Whether to treat both page sources and comment text as untrusted input. Untrusted input has additional restrictions to protect against XSS attacks etc. Turn on if your wiki allows anonymous edits.", "default": false},
|
||||||
"enable_math_rendering": { "type": "checkbox", "description": "Whether to enable client side rendering of mathematical expressions with MathJax (https://www.mathjax.org/). Math expressions should be enclosed inside of dollar signs ($). Turn off if you don't use it.", "default": true},
|
"enable_math_rendering": { "type": "checkbox", "description": "Whether to enable client side rendering of mathematical expressions with MathJax (https://www.mathjax.org/). Math expressions should be enclosed inside of dollar signs ($). Turn off if you don't use it.", "default": true},
|
||||||
"users": { "type": "usertable", "description": "An array of usernames and passwords - passwords should be hashed with password_hash() (the hash action can help here)", "default": {
|
"users": { "type": "usertable", "description": "An array of usernames and passwords - passwords should be hashed with password_hash() (the hash action can help here)", "default": {
|
||||||
"admin": {
|
"admin": {
|
||||||
|
|
Loading…
Reference in a new issue