summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Brown <ptbrown@whoopdedo.org>2015-07-16 12:35:56 -0400
committerPatrick Brown <ptbrown@whoopdedo.org>2015-07-16 12:35:56 -0400
commit17e17ae257649aef67c693d01e8992ece86eabd2 (patch)
tree8b5012cd488eefb7ca2c98f508b52ef2f429d5b6
parentccee93d9d1aa20ccc91f9277983d7fa2ee34f7f9 (diff)
downloadrpg-17e17ae257649aef67c693d01e8992ece86eabd2.tar.gz
rpg-17e17ae257649aef67c693d01e8992ece86eabd2.tar.bz2
Encode unsafe characters in interwiki links. closes #1220
-rw-r--r--_test/tests/inc/parser/renderer_resolveinterwiki.test.php16
-rw-r--r--inc/parser/renderer.php12
2 files changed, 18 insertions, 10 deletions
diff --git a/_test/tests/inc/parser/renderer_resolveinterwiki.test.php b/_test/tests/inc/parser/renderer_resolveinterwiki.test.php
index 9cc3443eb..8379bc065 100644
--- a/_test/tests/inc/parser/renderer_resolveinterwiki.test.php
+++ b/_test/tests/inc/parser/renderer_resolveinterwiki.test.php
@@ -17,18 +17,18 @@ class Test_resolveInterwiki extends DokuWikiTest {
$tests = array(
// shortcut, reference and expected
- array('wp', 'foo [\\]^`{|}~@+#%?/#txt', 'https://en.wikipedia.org/wiki/foo %7E%5B%5C%5D%5E%60%7B%7C%7D%7E@+%23%25%3F/#txt'),
- array('amazon', 'foo [\\]^`{|}~@+#%?/#txt', 'https://www.amazon.com/exec/obidos/ASIN/foo%20%7E%5B%5C%5D%5E%60%7B%7C%7D%7E%40%2B%23%25%3F%2F/splitbrain-20/#txt'),
- array('doku', 'foo [\\]^`{|}~@+#%?/#txt', 'https://www.dokuwiki.org/foo%20%7E%5B%5C%5D%5E%60%7B%7C%7D%7E%40%2B%23%25%3F%2F#txt'),
+ array('wp', 'foo [\\]^`{|}~@+#%?/#txt', 'https://en.wikipedia.org/wiki/foo %5B%5C%5D%5E%60%7B%7C%7D~@+%23%25?/#txt'),
+ array('amazon', 'foo [\\]^`{|}~@+#%?/#txt', 'https://www.amazon.com/exec/obidos/ASIN/foo%20%5B%5C%5D%5E%60%7B%7C%7D~%40%2B%23%25%3F%2F/splitbrain-20/#txt'),
+ array('doku', 'foo [\\]^`{|}~@+#%?/#txt', 'https://www.dokuwiki.org/foo%20%5B%5C%5D%5E%60%7B%7C%7D~%40%2B%23%25%3F%2F#txt'),
array('coral', 'http://example.com:83/path/naar/?query=foo%20%40%2B%25%3F%2F', 'http://example.com.83.nyud.net:8090/path/naar/?query=foo%20%40%2B%25%3F%2F'),
array('scheme', 'ftp://foo @+%/#txt', 'ftp://example.com#txt'),
//relative url
- array('withslash', 'foo [\\]^`{|}~@+#%?/#txt', '/testfoo%20%7E%5B%5C%5D%5E%60%7B%7C%7D%7E%40%2B%23%25%3F%2F#txt'),
- array('skype', 'foo [\\]^`{|}~@+#%?/#txt', 'skype:foo %7E%5B%5C%5D%5E%60%7B%7C%7D%7E@+%23%25?/#txt'),
+ array('withslash', 'foo [\\]^`{|}~@+#%?/#txt', '/testfoo%20%5B%5C%5D%5E%60%7B%7C%7D~%40%2B%23%25%3F%2F#txt'),
+ array('skype', 'foo [\\]^`{|}~@+#%?/#txt', 'skype:foo %5B%5C%5D%5E%60%7B%7C%7D~@+%23%25?/#txt'),
//dokuwiki id's
- array('onlytext', 'foo [\\]^`{|}~@+#%?/#txt', DOKU_BASE.'doku.php?id=onlytextfoo#txt'),
- array('user', 'foo [\\]^`{|}~@+#%?/#txt', DOKU_BASE.'doku.php?id=user:foo#txt'),
- array('withquery', 'foo [\\]^`{|}~@+#%?/#txt', DOKU_BASE.'doku.php?id=anyns:foo&amp;do=edit#txt')
+ array('onlytext', 'foo [\\]^`{|}~@+#%/#txt', DOKU_BASE.'doku.php?id=onlytextfoo#txt'),
+ array('user', 'foo [\\]^`{|}~@+#%/#txt', DOKU_BASE.'doku.php?id=user:foo#txt'),
+ array('withquery', 'foo [\\]^`{|}~@+#%/#txt', DOKU_BASE.'doku.php?id=anyns:foo&amp;do=edit#txt')
);
foreach($tests as $test) {
diff --git a/inc/parser/renderer.php b/inc/parser/renderer.php
index d5cc68367..d7a3faef8 100644
--- a/inc/parser/renderer.php
+++ b/inc/parser/renderer.php
@@ -811,13 +811,21 @@ class Doku_Renderer extends DokuWiki_Plugin {
}
//split into hash and url part
- @list($reference, $hash) = explode('#', $reference, 2);
+ $hash = strrchr($reference, '#');
+ if($hash) {
+ $reference = substr($reference, 0, -strlen($hash));
+ $hash = substr($hash, 1);
+ }
//replace placeholder
if(preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#', $url)) {
//use placeholders
$url = str_replace('{URL}', rawurlencode($reference), $url);
- $url = str_replace('{NAME}', $reference, $url);
+ //wiki names will be cleaned next, otherwise urlencode unsafe chars
+ $url = str_replace('{NAME}', ($url{0} === ':') ? $reference :
+ preg_replace_callback('/[[\\\\\]^`{|}#%]/', function($match) {
+ return rawurlencode($match[0]);
+ }, $reference), $url);
$parsed = parse_url($reference);
if(!$parsed['port']) $parsed['port'] = 80;
$url = str_replace('{SCHEME}', $parsed['scheme'], $url);