summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2013-10-28 04:27:44 -0700
committerAndreas Gohr <andi@splitbrain.org>2013-10-28 04:27:44 -0700
commit1a3aae1d461842aa814160e5e1b13b1ab9116c8a (patch)
tree7858ec5f9d737a83539c32a24c44b45756dbf757
parent0f91b38c17dcd12ce5b73ad8312851f67244b080 (diff)
parent30eae85545994c10dcacb2d7becceaf569c99f65 (diff)
downloadrpg-1a3aae1d461842aa814160e5e1b13b1ab9116c8a.tar.gz
rpg-1a3aae1d461842aa814160e5e1b13b1ab9116c8a.tar.bz2
Merge pull request #395 from splitbrain/FS#2867
FS#2867, ACL processing may fail with utf-8 characters which include byte 'A0'.
-rw-r--r--_test/tests/inc/auth_loadacl.test.php130
-rw-r--r--_test/tests/inc/auth_nameencode.test.php16
-rw-r--r--inc/auth.php10
-rw-r--r--lib/plugins/acl/admin.php4
4 files changed, 153 insertions, 7 deletions
diff --git a/_test/tests/inc/auth_loadacl.test.php b/_test/tests/inc/auth_loadacl.test.php
new file mode 100644
index 000000000..e8d9f6696
--- /dev/null
+++ b/_test/tests/inc/auth_loadacl.test.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * auth_loadACL carries out the user & group substitutions
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+
+class auth_loadacl_test extends DokuWikiTest {
+
+ function setUp() {
+ global $USERINFO;
+ parent::setUp();
+ $_SERVER['REMOTE_USER'] = 'testuser';
+ $USERINFO['grps'] = array('foo','bar');
+ }
+
+ function tearDown() {
+ parent::tearDown();
+ }
+
+ function auth_loadACL_testwrapper($acls) {
+ global $config_cascade;
+ $acl_file = $config_cascade['acl']['default'];
+
+ $config_cascade['acl']['default'] .= '.test';
+ file_put_contents($config_cascade['acl']['default'],$acls);
+
+ $result = auth_loadACL();
+
+ unlink($config_cascade['acl']['default']);
+ $config_cascade['acl']['default'] = $acl_file;
+
+ return $result;
+ }
+
+ function test_simple() {
+ $acls = <<<ACL
+* @ALL 2
+ACL;
+ $expect = array("*\t@ALL 2");
+ $this->assertEquals($expect, $this->auth_loadACL_testwrapper($acls));
+ }
+
+ function test_user_substitution() {
+ $acls = <<<ACL
+%USER% %USER% 2
+ACL;
+ $expect = array(
+ "testuser\ttestuser 2",
+ );
+ $this->assertEquals($expect, $this->auth_loadACL_testwrapper($acls));
+ }
+
+ function test_group_substitution() {
+ $acls = <<<ACL
+%GROUP% %GROUP% 2
+ACL;
+ $expect = array(
+ "foo\t@foo 2",
+ "bar\t@bar 2",
+ );
+ $this->assertEquals($expect, $this->auth_loadACL_testwrapper($acls));
+ }
+
+ function test_both_substitution() {
+ $acls = <<<ACL
+%GROUP%:%USER% %USER% 2
+%GROUP%:%USER% %GROUP% 2
+ACL;
+ $expect = array(
+ "foo:testuser\ttestuser 2",
+ "bar:testuser\ttestuser 2",
+ "foo:testuser\t@foo 2",
+ "bar:testuser\t@bar 2",
+ );
+ $this->assertEquals($expect, $this->auth_loadACL_testwrapper($acls));
+ }
+
+ // put it all together - read the standard acl provided with the test suite
+ function test_standardtestacls(){
+ $expect = array(
+ "*\t@ALL 8",
+ "private:*\t@ALL 0",
+ "users:*\t@ALL 1",
+ "users:testuser:*\ttestuser 16",
+ "groups:*\t@ALL 1",
+ "groups:foo:*\t@foo 16",
+ "groups:bar:*\t@bar 16",
+ );
+ $this->assertEquals($expect, auth_loadACL());
+ }
+
+ // FS#2867, '\s' in php regular expressions may match non-space characters utf8 strings
+ // this is due to locale setting on the server, which may match bytes '\xA0' and '\x85'
+ // these two bytes are present in valid multi-byte UTF-8 characters.
+ // this test will use one, 'ठ' (DEVANAGARI LETTER TTHA, e0 a4 a0). There are many others.
+ function test_FS2867() {
+ global $USERINFO;
+
+ $old_locale = setlocale(LC_ALL, '0');
+ setlocale(LC_ALL, "English_United States.1252"); // should only succeed on windows systems
+ setlocale(LC_ALL, "en_US.UTF-8"); // should succeed on other systems
+
+ // no point continuing with this test if \s doesn't match A0
+ if (!preg_match('/\s/',"\xa0")) {
+ setlocale(LC_ALL, $old_locale);
+ $this->markTestSkipped('Unable to change locale.');
+ }
+
+ $_SERVER['REMOTE_USER'] = 'utfठ8';
+ $USERINFO['grps'] = array('utfठ16','utfठa');
+
+ $acls = <<<ACL
+%GROUP%:%USER% %USER% 2
+%GROUP%:* %GROUP% 4
+devangariठttha @ALL 2
+ACL;
+ $expect = array(
+ "utfठ16:utfठ8\tutfठ8 2",
+ "utfठa:utfठ8\tutfठ8 2",
+ "utfठ16:*\t@utfठ16 4",
+ "utfठa:*\t@utfठa 4",
+ "devangariठttha\t@ALL 2",
+ );
+ $this->assertEquals($expect, $this->auth_loadACL_testwrapper($acls));
+ setlocale(LC_ALL, $old_locale);
+ }
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/tests/inc/auth_nameencode.test.php b/_test/tests/inc/auth_nameencode.test.php
index 074155486..86db843d6 100644
--- a/_test/tests/inc/auth_nameencode.test.php
+++ b/_test/tests/inc/auth_nameencode.test.php
@@ -54,6 +54,22 @@ class auth_nameencode_test extends DokuWikiTest {
$out = '%40hey%24you';
$this->assertEquals(auth_nameencode($in),$out);
}
+
+ // include a two byte utf8 character which shouldn't be encoded
+ function test_hebrew(){
+ $in = 'nun-נ8';
+ $expect = 'nun%2dנ8';
+
+ $this->assertEquals($expect, auth_nameencode($in));
+ }
+
+ // include a three byte utf8 character which shouldn't be encoded
+ function test_devanagiri(){
+ $in = 'ut-fठ8';
+ $expect = 'ut%2dfठ8';
+
+ $this->assertEquals($expect, auth_nameencode($in));
+ }
}
//Setup VIM: ex: et ts=4 :
diff --git a/inc/auth.php b/inc/auth.php
index 0d42c8673..b793f5d12 100644
--- a/inc/auth.php
+++ b/inc/auth.php
@@ -140,7 +140,7 @@ function auth_loadACL() {
foreach($acl as $line) {
$line = trim($line);
if(empty($line) || ($line{0} == '#')) continue; // skip blank lines & comments
- list($id,$rest) = preg_split('/\s+/',$line,2);
+ list($id,$rest) = preg_split('/[ \t]+/',$line,2);
// substitute user wildcard first (its 1:1)
if(strstr($line, '%USER%')){
@@ -716,11 +716,11 @@ function auth_aclcheck($id, $user, $groups) {
}
//check exact match first
- $matches = preg_grep('/^'.preg_quote($id, '/').'\s+(\S+)\s+/u', $AUTH_ACL);
+ $matches = preg_grep('/^'.preg_quote($id, '/').'[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL);
if(count($matches)) {
foreach($matches as $match) {
$match = preg_replace('/#.*$/', '', $match); //ignore comments
- $acl = preg_split('/\s+/', $match);
+ $acl = preg_split('/[ \t]+/', $match);
if(!$auth->isCaseSensitive() && $acl[1] !== '@ALL') {
$acl[1] = utf8_strtolower($acl[1]);
}
@@ -746,11 +746,11 @@ function auth_aclcheck($id, $user, $groups) {
}
do {
- $matches = preg_grep('/^'.preg_quote($path, '/').'\s+(\S+)\s+/u', $AUTH_ACL);
+ $matches = preg_grep('/^'.preg_quote($path, '/').'[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL);
if(count($matches)) {
foreach($matches as $match) {
$match = preg_replace('/#.*$/', '', $match); //ignore comments
- $acl = preg_split('/\s+/', $match);
+ $acl = preg_split('/[ \t]+/', $match);
if(!$auth->isCaseSensitive() && $acl[1] !== '@ALL') {
$acl[1] = utf8_strtolower($acl[1]);
}
diff --git a/lib/plugins/acl/admin.php b/lib/plugins/acl/admin.php
index 5ab73670d..b24981d91 100644
--- a/lib/plugins/acl/admin.php
+++ b/lib/plugins/acl/admin.php
@@ -554,7 +554,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin {
$line = trim(preg_replace('/#.*$/','',$line)); //ignore comments
if(!$line) continue;
- $acl = preg_split('/\s+/',$line);
+ $acl = preg_split('/[ \t]+/',$line);
//0 is pagename, 1 is user, 2 is acl
$acl[1] = rawurldecode($acl[1]);
@@ -701,7 +701,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin {
$acl_config = file($config_cascade['acl']['default']);
$acl_user = auth_nameencode($acl_user,true);
- $acl_pattern = '^'.preg_quote($acl_scope,'/').'\s+'.$acl_user.'\s+[0-8].*$';
+ $acl_pattern = '^'.preg_quote($acl_scope,'/').'[ \t]+'.$acl_user.'[ \t]+[0-8].*$';
// save all non!-matching
$new_config = preg_grep("/$acl_pattern/", $acl_config, PREG_GREP_INVERT);