Merge branch 'master' into psr2

* master: (22 commits)
  Support "local" subdir when listing the smiley directory
  fix zero ID/NS issue with page_findnearest
  add ID/NS = '0' test against page_findnearest
  fix zero value issue with metadata indexer
  add key/value = '0' test to metadata indexer
  fix zero ID issue with linkwiz and search indexer
  fix zero ID issue with wl() and getID()
  add $ID = '0' test against wl() and getID()
  cookie.js when setValue‘s value parameter is false delete entry
  install.php: respect useacl=0 choice, fixes #2576
  cookie.js add def parameter to getValue()
  cookie.js convert value type to string
  set_doku_pref bugfix, closes #2721
  more definition tests of doku_pref, for #1129
  add tests for get/set_doku_pref #2721
  fix Windows tests for #2702
  use absolute URL in index.php when redirecting to doku.php, fixes #2706
  Adding "recursive_groups" setting for authad-plugin in configuration-manager
  Fix notices when using dw CLI
  Fix issue #2396
  ...
This commit is contained in:
Andreas Gohr 2019-03-30 22:08:54 +01:00
commit abc9c0d217
21 changed files with 237 additions and 67 deletions

View File

@ -20,9 +20,9 @@ error_reporting(DOKU_E_LEVEL);
set_time_limit(0);
ini_set('memory_limit','2048M');
// prepare temporary directories
define('DOKU_INC', dirname(dirname(__FILE__)).'/');
define('TMP_DIR', sys_get_temp_dir().'/dwtests-'.microtime(true));
// prepare temporary directories; str_replace is for WIN
define('DOKU_INC', str_replace('\\', '/', dirname(dirname(__FILE__))) . '/');
define('TMP_DIR', str_replace('\\', '/', sys_get_temp_dir()) . '/dwtests-'.microtime(true));
define('DOKU_CONF', TMP_DIR.'/conf/');
define('DOKU_TMP_DATA', TMP_DIR.'/data/');

View File

@ -0,0 +1,86 @@
<?php
class common_dokupref_test extends DokuWikiTest {
function test_get_default() {
$this->assertEquals('nil', get_doku_pref('foo', 'nil'));
}
function test_set() {
set_doku_pref('foo1', 'bar1');
set_doku_pref('foo2', 'bar2');
$this->assertEquals('bar1', get_doku_pref('foo1', 'nil'));
$this->assertEquals('bar2', get_doku_pref('foo2', 'nil'));
}
function test_set_encode() {
set_doku_pref('foo#1', 'bar#1');
set_doku_pref('foo#2', 'bar2');
$this->assertEquals('bar#1', get_doku_pref('foo#1', 'nil'));
$this->assertEquals('bar2', get_doku_pref('foo#2', 'nil'));
set_doku_pref('foo#2', 'bar#2');
$this->assertEquals('bar#1', get_doku_pref('foo#1', 'nil'));
$this->assertEquals('bar#2', get_doku_pref('foo#2', 'nil'));
}
// mitigate bug in #2721
function test_duplicate_entries() {
$_COOKIE['DOKU_PREFS'] = 'foo1#bar1#foo2#bar1#foo2#bar2';
$this->assertEquals('bar2', get_doku_pref('foo2', 'nil'));
set_doku_pref('foo2', 'new2');
$this->assertEquals('bar1', get_doku_pref('foo1', 'nil'));
$this->assertEquals('new2', get_doku_pref('foo2', 'nil'));
$this->assertEquals('foo1#bar1#foo2#new2', $_COOKIE['DOKU_PREFS'],
'cookie should not have duplicate entries');
}
// This is a definition from #1129
function test_empty() {
set_doku_pref('foo', '');
$this->assertSame('', get_doku_pref('foo', 'nil'));
set_doku_pref('foo', 0);
$this->assertSame('0', get_doku_pref('foo', 'nil'));
set_doku_pref('foo', null);
$this->assertSame('', get_doku_pref('foo', 'nil'));
set_doku_pref('foo', false);
$this->assertSame('nil', get_doku_pref('foo', 'nil'));
}
// #2721
function test_set_empty_string() {
set_doku_pref('foo1', 'bar1');
set_doku_pref('foo2', 'bar1');
set_doku_pref('foo2', '');
$this->assertEquals('bar1', get_doku_pref('foo1', 'nil'));
$this->assertEquals('', get_doku_pref('foo2', 'nil'));
set_doku_pref('foo2', 'bar2');
$this->assertEquals('bar1', get_doku_pref('foo1', 'nil'));
$this->assertEquals('bar2', get_doku_pref('foo2', 'nil'));
$this->assertEquals('foo1#bar1#foo2#bar2', $_COOKIE['DOKU_PREFS'],
'cookie should not have duplicate entries');
}
// #2721
function test_set_delete() {
set_doku_pref('foo1', 'bar1');
set_doku_pref('foo2', 'bar2');
set_doku_pref('foo1', false);
$this->assertEquals('nil', get_doku_pref('foo1', 'nil'));
$this->assertEquals('bar2', get_doku_pref('foo2', 'nil'));
set_doku_pref('foo2', false);
$this->assertEquals('nil', get_doku_pref('foo1', 'nil'));
$this->assertEquals('nil', get_doku_pref('foo2', 'nil'));
}
}
//Setup VIM: ex: et ts=4 :

View File

@ -38,6 +38,15 @@ class common_wl_test extends DokuWikiTest {
$this->assertEquals($expect, wl('some'));
}
function test_wl_id_zero() {
global $conf;
$conf['useslash'] = 0;
$conf['userewrite'] = 0;
$expect = DOKU_BASE . DOKU_SCRIPT . '?id=0';
$this->assertEquals($expect, wl('0'));
}
function test_wl_id_ns() {
global $conf;
$conf['useslash'] = 0;
@ -142,7 +151,7 @@ class common_wl_test extends DokuWikiTest {
$expect = DOKU_BASE . DOKU_SCRIPT . '/some/one?a=b&c=d';
$this->assertEquals($expect, wl('some:one', 'a=b,c=d', false, '&'));
}
function test_wl_empty_rev() {
global $conf;
$conf['useslash'] = 0;

View File

@ -59,4 +59,21 @@ class indexer_indexing_test extends DokuWikiTest {
$query = '1010';
$this->assertEquals(array('notfound', 'testpage'), $indexer->lookupKey('onezero', $query));
}
public function test_numeric_zerostring_meta() {
$indexer = idx_get_indexer();
$indexer->addMetaKeys('zero1', 'zerostring', array('0'));
$indexer->addMetaKeys('zero2', 'zerostring', array('0'));
$indexer->addMetaKeys('0', 'zerostring', array('zero'));
$query = '0';
$result = $indexer->lookupKey('zerostring', $query);
sort($result);
$this->assertEquals(array('zero1', 'zero2'), $result);
$query = 'zero';
$result = $indexer->lookupKey('zerostring', $query);
sort($result);
$this->assertEquals(array('0'), $result);
}
}

View File

@ -38,6 +38,25 @@ class pageutils_findnearest_test extends DokuWikiTest {
$this->assertEquals(false, $sidebar);
}
function testZeroID() {
global $ID;
saveWikiText('sidebar', 'topsidebar-test', '');
saveWikiText('0', 'zero-test', '');
saveWikiText('0:0:0', 'zero-test', '');
$ID = '0:0:0';
$sidebar = page_findnearest('sidebar');
$this->assertEquals('sidebar', $sidebar);
$sidebar = page_findnearest('0');
$this->assertEquals('0:0:0', $sidebar);
$ID = '0';
$sidebar = page_findnearest('0');
$this->assertEquals('0', $sidebar);
}
function testExistingSidebars() {
global $ID;

View File

@ -2,6 +2,21 @@
class init_getID_test extends DokuWikiTest {
/**
* id=0 case
*/
function test_zero_id(){
global $conf;
$conf['basedir'] = '/';
$conf['userewrite'] = 0;
$_SERVER['SCRIPT_FILENAME'] = '/doku.php';
$_SERVER['REQUEST_URI'] = '/doku.php?id=0&do=edit';
$_REQUEST['id'] = '0';
$this->assertSame('0', getID('id'));
}
/**
* fetch media files with basedir and urlrewrite=2
*

View File

@ -414,7 +414,7 @@ class Ajax {
foreach($data as $item) {
$even *= -1; //zebra
if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id']) $item['id'] .= ':';
if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id'] !== '') $item['id'] .= ':';
$link = wl($item['id']);
echo '<div class="' . (($even > 0) ? 'even' : 'odd') . ' type_' . $item['type'] . '">';

View File

@ -32,7 +32,7 @@ class Edit extends AbstractItem {
}
}
} else {
if(!actionOK($this->type)) throw new \RuntimeException("action disabled: source");
if(!actionOK("source")) throw new \RuntimeException("action disabled: source");
$params['rev'] = $REV;
$this->type = 'source';
$this->accesskey = 'v';

View File

@ -190,7 +190,7 @@ class TaskRunner
global $ID;
print 'runIndexer(): started' . NL;
if (!$ID) {
if ((string) $ID === '') {
return false;
}

View File

@ -510,7 +510,7 @@ function wl($id = '', $urlParameters = '', $absolute = false, $separator = '&amp
} elseif($conf['userewrite']) {
$xlink .= $id;
if($urlParameters) $xlink .= '?'.$urlParameters;
} elseif($id) {
} elseif($id !== '') {
$xlink .= DOKU_SCRIPT.'?id='.$id;
if($urlParameters) $xlink .= $separator.$urlParameters;
} else {
@ -2033,7 +2033,10 @@ function get_doku_pref($pref, $default) {
if(isset($_COOKIE['DOKU_PREFS']) && strpos($_COOKIE['DOKU_PREFS'], $enc_pref) !== false) {
$parts = explode('#', $_COOKIE['DOKU_PREFS']);
$cnt = count($parts);
for($i = 0; $i < $cnt; $i += 2) {
// due to #2721 there might be duplicate entries,
// so we read from the end
for($i = $cnt-2; $i >= 0; $i -= 2) {
if($parts[$i] == $enc_pref) {
return urldecode($parts[$i + 1]);
}
@ -2055,30 +2058,39 @@ function set_doku_pref($pref, $val) {
$orig = get_doku_pref($pref, false);
$cookieVal = '';
if($orig && ($orig != $val)) {
if($orig !== false && ($orig !== $val)) {
$parts = explode('#', $_COOKIE['DOKU_PREFS']);
$cnt = count($parts);
// urlencode $pref for the comparison
$enc_pref = rawurlencode($pref);
for($i = 0; $i < $cnt; $i += 2) {
if($parts[$i] == $enc_pref) {
if ($val !== false) {
$parts[$i + 1] = rawurlencode($val);
$seen = false;
for ($i = 0; $i < $cnt; $i += 2) {
if ($parts[$i] == $enc_pref) {
if (!$seen){
if ($val !== false) {
$parts[$i + 1] = rawurlencode($val);
} else {
unset($parts[$i]);
unset($parts[$i + 1]);
}
$seen = true;
} else {
// no break because we want to remove duplicate entries
unset($parts[$i]);
unset($parts[$i + 1]);
}
break;
}
}
$cookieVal = implode('#', $parts);
} else if (!$orig && $val !== false) {
$cookieVal = ($_COOKIE['DOKU_PREFS'] ? $_COOKIE['DOKU_PREFS'].'#' : '').
rawurlencode($pref).'#'.rawurlencode($val);
} else if ($orig === false && $val !== false) {
$cookieVal = ($_COOKIE['DOKU_PREFS'] ? $_COOKIE['DOKU_PREFS'] . '#' : '') .
rawurlencode($pref) . '#' . rawurlencode($val);
}
if (!empty($cookieVal)) {
$cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
$cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
if(defined('DOKU_UNITTEST')) {
$_COOKIE['DOKU_PREFS'] = $cookieVal;
}else{
setcookie('DOKU_PREFS', $cookieVal, time()+365*24*3600, $cookieDir, '', ($conf['securecookie'] && is_ssl()));
}
}

View File

@ -293,7 +293,7 @@ class Doku_Indexer {
if (!is_array($values)) $values = array($values);
$val_idx = $this->getIndexKey($metaname.'_p', '', $pid);
if ($val_idx != '') {
if ($val_idx !== '') {
$val_idx = explode(':', $val_idx);
// -1 means remove, 0 keep, 1 add
$val_idx = array_combine($val_idx, array_fill(0, count($val_idx), -1));
@ -1284,7 +1284,7 @@ class Doku_Indexer {
list($key, $cnt) = explode('*', $tuple);
if (!$cnt) continue;
$key = $keys[$key];
if (!$key) continue;
if ($key === false || is_null($key)) continue;
$result[$key] = $cnt;
}
return $result;

View File

@ -108,11 +108,11 @@ if(!defined('DOKU_LF')) define ('DOKU_LF',"\n");
if(!defined('DOKU_TAB')) define ('DOKU_TAB',"\t");
// define cookie and session id, append server port when securecookie is configured FS#1664
if(!defined('DOKU_COOKIE')) define(
'DOKU_COOKIE',
'DW' . md5(DOKU_REL . (($conf['securecookie']) ? $_SERVER['SERVER_PORT'] : ''))
);
if (!defined('DOKU_COOKIE')) {
$serverPort = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : '';
define('DOKU_COOKIE', 'DW' . md5(DOKU_REL . (($conf['securecookie']) ? $serverPort : '')));
unset($serverPort);
}
// define main script
if(!defined('DOKU_SCRIPT')) define('DOKU_SCRIPT','doku.php');
@ -143,7 +143,8 @@ if(!defined('DOKU_TPLINC')) {
@ini_set('pcre.backtrack_limit', '20971520');
// enable gzip compression if supported
$conf['gzip_output'] &= (strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false);
$httpAcceptEncoding = isset($_SERVER['HTTP_ACCEPT_ENCODING']) ? $_SERVER['HTTP_ACCEPT_ENCODING'] : '';
$conf['gzip_output'] &= (strpos($httpAcceptEncoding, 'gzip') !== false);
global $ACT;
if ($conf['gzip_output'] &&
!defined('DOKU_DISABLE_GZIP_OUTPUT') &&

View File

@ -92,9 +92,8 @@ function getID($param='id',$clean=true){
send_redirect(wl($id, $urlParameters, true, '&'));
}
}
if($clean) $id = cleanID($id);
if(empty($id) && $param=='id') $id = $conf['start'];
if($id === '' && $param=='id') $id = $conf['start'];
return $id;
}
@ -762,7 +761,7 @@ function utf8_decodeFN($file){
* @return false|string the full page id of the found page, false if any
*/
function page_findnearest($page, $useacl = true){
if (!$page) return false;
if ((string) $page === '') return false;
global $ID;
$ns = $ID;
@ -772,7 +771,7 @@ function page_findnearest($page, $useacl = true){
if(page_exists($pageid) && (!$useacl || auth_quickaclcheck($pageid) >= AUTH_READ)){
return $pageid;
}
} while($ns);
} while($ns !== false);
return false;
}

View File

@ -14,8 +14,10 @@
* @author Andreas Gohr <andi@splitbrain.org>
*/
if(php_sapi_name() != 'cli-server') {
header("Location: doku.php");
exit;
if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__).'/');
require_once(DOKU_INC.'inc/init.php');
send_redirect(DOKU_URL.'doku.php');
}
# ROUTER starts below

View File

@ -320,6 +320,9 @@ function check_data(&$d){
$error[] = sprintf($lang['i_badval'],$lang['email']);
$ok = false;
}
}else{
// Since default = 1, browser won't send acl=0 when user untick acl
$d['acl'] = '0';
}
}
$d = array_merge($form_default, $d);

View File

@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<title>filetype icons</title>
<title>Filetype icons</title>
<style type="text/css">
body {
@ -11,7 +11,7 @@
.box {
width: 200px;
float:left;
float: left;
padding: 0.5em;
margin: 0;
}
@ -28,40 +28,32 @@
</head>
<body>
<div class="white box">
<?php
$fi_list = ''; $fi_list32 = '';
foreach (glob('*.png') as $img) {
echo '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
$fi_list .= '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
}
?>
foreach (glob('32x32/*.png') as $img) {
$fi_list32 .= '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
}
echo '<div class="white box">
'.$fi_list.'
</div>
<div class="black box">
<?php
foreach (glob('*.png') as $img) {
echo '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
}
?>
'.$fi_list.'
</div>
<br style="clear: left" />
<div class="white box">
<?php
foreach (glob('32x32/*.png') as $img) {
echo '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
}
?>
'.$fi_list32.'
</div>
<div class="black box">
<?php
foreach (glob('32x32/*.png') as $img) {
echo '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
}
?>
'.$fi_list32;
?>
</div>
</body>
</html>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<title>smileys</title>
<title>Smileys</title>
<style type="text/css">
body {
@ -11,7 +11,7 @@
.box {
width: 200px;
float:left;
float: left;
padding: 0.5em;
margin: 0;
}
@ -28,19 +28,24 @@
</head>
<body>
<div class="white box">
<?php
$smi_list = '';
foreach (glob('*.gif') as $img) {
echo '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
$smi_list .= '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
}
?>
if(is_dir('local')) {
$smi_list .= '<hr />';
foreach (glob('local/*.gif') as $img) {
$smi_list .= '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
}
}
echo '<div class="white box">
'.$smi_list.'
</div>
<div class="black box">
<?php
foreach (glob('*.gif') as $img) {
echo '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
}
'.$smi_list;
?>
</div>

View File

@ -15,3 +15,4 @@ $conf['expirywarn'] = 0;
$conf['additional'] = '';
$conf['update_name'] = 0;
$conf['update_mail'] = 0;
$conf['recursive_groups'] = 0;

View File

@ -15,3 +15,4 @@ $meta['expirywarn'] = array('numeric', '_min'=>0,'_caution' => 'danger')
$meta['additional'] = array('string','_caution' => 'danger');
$meta['update_name'] = array('onoff','_caution' => 'danger');
$meta['update_mail'] = array('onoff','_caution' => 'danger');
$meta['recursive_groups'] = array('onoff','_caution' => 'danger');

View File

@ -15,3 +15,4 @@ $lang['expirywarn'] = 'Days in advance to warn user about expiring passw
$lang['additional'] = 'A comma separated list of additional AD attributes to fetch from user data. Used by some plugins.';
$lang['update_name'] = 'Allow users to update their AD display name?';
$lang['update_mail'] = 'Allow users to update their email address?';
$lang['recursive_groups'] = 'Resolve nested groups to their respective members (slower).';

View File

@ -22,7 +22,13 @@ var DokuCookie = {
var text = [],
_this = this;
this.init();
this.data[key] = val;
if (val === false){
delete this.data[key];
}else{
val = val + "";
this.data[key] = val;
}
//save the whole data array
jQuery.each(_this.data, function (key, val) {
@ -37,10 +43,11 @@ var DokuCookie = {
* Get a Value from the Cookie
*
* @author Andreas Gohr <andi@splitbrain.org>
* @param def default value if key does not exist; if not set, returns undefined by default
*/
getValue: function(key){
getValue: function(key, def){
this.init();
return this.data[key];
return this.data.hasOwnProperty(key) ? this.data[key] : def;
},
/**