forked from Wavyzz/dolibarr
Fix: Add an unsecape function to decode javascript escape
encoding. This also fix ecm for cyrillic chars.
This commit is contained in:
@@ -33,13 +33,14 @@ if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1');
|
|||||||
|
|
||||||
$res=@include("../../main.inc.php");
|
$res=@include("../../main.inc.php");
|
||||||
include_once(DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php');
|
include_once(DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php');
|
||||||
|
include_once(DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php');
|
||||||
include_once(DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php');
|
include_once(DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php');
|
||||||
include_once(DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php');
|
include_once(DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php');
|
||||||
include_once(DOL_DOCUMENT_ROOT."/ecm/class/ecmdirectory.class.php");
|
include_once(DOL_DOCUMENT_ROOT."/ecm/class/ecmdirectory.class.php");
|
||||||
|
|
||||||
$openeddir = GETPOST('openeddir');
|
$openeddir = GETPOST('openeddir');
|
||||||
$modulepart= GETPOST('modulepart');
|
$modulepart= GETPOST('modulepart');
|
||||||
$selecteddir = urldecode(GETPOST('dir')); // relative patch. We must keep the urldecode here because para comes from jqueyrFileTree that url encode it.
|
$selecteddir = jsUnEscape(GETPOST('dir')); // relative path. We must decode using same encoding function used by javascript: escape()
|
||||||
if ($selecteddir != '/') $selecteddir = preg_replace('/\/$/','',$selecteddir); // We removed last '/' except if it is '/'
|
if ($selecteddir != '/') $selecteddir = preg_replace('/\/$/','',$selecteddir); // We removed last '/' except if it is '/'
|
||||||
|
|
||||||
$langs->load("ecm");
|
$langs->load("ecm");
|
||||||
@@ -89,7 +90,6 @@ foreach($sqltree as $keycursor => $val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//var_dump($sqltree);
|
|
||||||
|
|
||||||
if( file_exists($fullpathselecteddir) )
|
if( file_exists($fullpathselecteddir) )
|
||||||
{
|
{
|
||||||
@@ -111,6 +111,7 @@ if( file_exists($fullpathselecteddir) )
|
|||||||
|
|
||||||
// Try to find key into $sqltree
|
// Try to find key into $sqltree
|
||||||
$val=array();
|
$val=array();
|
||||||
|
|
||||||
foreach($sqltree as $key => $tmpval)
|
foreach($sqltree as $key => $tmpval)
|
||||||
{
|
{
|
||||||
//print "-- ".$val['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file).'<br>';
|
//print "-- ".$val['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file).'<br>';
|
||||||
|
|||||||
@@ -23,6 +23,17 @@
|
|||||||
* \brief Library for file managing functions
|
* \brief Library for file managing functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a basename working with all page code (default PHP basenamed fails with cyrillic).
|
||||||
|
* We supose dir separator for input is '/'.
|
||||||
|
*
|
||||||
|
* @param string $pathfile String to find basename.
|
||||||
|
* @return string Basename of input
|
||||||
|
*/
|
||||||
|
function dol_basename($pathfile)
|
||||||
|
{
|
||||||
|
return preg_replace('/^.*\/([^\/]+)$/','$1',rtrim($pathfile,'/'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scan a directory and return a list of files/directories.
|
* Scan a directory and return a list of files/directories.
|
||||||
|
|||||||
@@ -24,6 +24,45 @@
|
|||||||
* This file contains all rare functions.
|
* This file contains all rare functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same function than javascript unescape() function but in PHP.
|
||||||
|
*
|
||||||
|
* @param string $sourcetodecode String to decode
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
function jsUnEscape($source)
|
||||||
|
{
|
||||||
|
$decodedStr = "";
|
||||||
|
$pos = 0;
|
||||||
|
$len = strlen ($source);
|
||||||
|
while ($pos < $len) {
|
||||||
|
$charAt = substr ($source, $pos, 1);
|
||||||
|
if ($charAt == '%') {
|
||||||
|
$pos++;
|
||||||
|
$charAt = substr ($source, $pos, 1);
|
||||||
|
if ($charAt == 'u') {
|
||||||
|
// we got a unicode character
|
||||||
|
$pos++;
|
||||||
|
$unicodeHexVal = substr ($source, $pos, 4);
|
||||||
|
$unicode = hexdec ($unicodeHexVal);
|
||||||
|
$entity = "&#". $unicode . ';';
|
||||||
|
$decodedStr .= utf8_encode ($entity);
|
||||||
|
$pos += 4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// we have an escaped ascii character
|
||||||
|
$hexVal = substr ($source, $pos, 2);
|
||||||
|
$decodedStr .= chr (hexdec ($hexVal));
|
||||||
|
$pos += 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$decodedStr .= $charAt;
|
||||||
|
$pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dol_html_entity_decode($decodedStr, ENT_COMPAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return list of modules directories
|
* Return list of modules directories
|
||||||
|
|||||||
@@ -607,8 +607,8 @@ class EcmDirectory // extends CommonObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calcule les proprietes fullpath, fullrelativename, fulllabel d'un repertoire
|
* Define properties fullpath, fullrelativename, fulllabel of a directory of array this->cats and all its childs.
|
||||||
* du tableau this->cats et de toutes ces enfants.
|
* Separator between directories is always '/', whatever is OS.
|
||||||
*
|
*
|
||||||
* @param int $id_categ id_categ entry to update
|
* @param int $id_categ id_categ entry to update
|
||||||
* @param int $protection Deep counter to avoid infinite loop
|
* @param int $protection Deep counter to avoid infinite loop
|
||||||
|
|||||||
@@ -258,6 +258,7 @@ if ($action == 'refreshmanual')
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
dol_syslog("Parent is root");
|
||||||
$fk_parent=0; // Parent is root
|
$fk_parent=0; // Parent is root
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +266,7 @@ if ($action == 'refreshmanual')
|
|||||||
{
|
{
|
||||||
$ecmdirtmp=new EcmDirectory($db);
|
$ecmdirtmp=new EcmDirectory($db);
|
||||||
$ecmdirtmp->ref = 'NOTUSEDYET';
|
$ecmdirtmp->ref = 'NOTUSEDYET';
|
||||||
$ecmdirtmp->label = basename($dirdesc['fullname']);
|
$ecmdirtmp->label = dol_basename($dirdesc['fullname']);
|
||||||
$ecmdirtmp->description = '';
|
$ecmdirtmp->description = '';
|
||||||
$ecmdirtmp->fk_parent = $fk_parent;
|
$ecmdirtmp->fk_parent = $fk_parent;
|
||||||
|
|
||||||
@@ -284,6 +285,10 @@ if ($action == 'refreshmanual')
|
|||||||
//var_dump($sqltree);
|
//var_dump($sqltree);
|
||||||
$adirwascreated=1;
|
$adirwascreated=1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dol_syslog("Failed to create directory ".$ecmdirtmp->label, LOG_ERR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$txt="Parent of ".$dirdesc['fullname']." not found";
|
$txt="Parent of ".$dirdesc['fullname']." not found";
|
||||||
@@ -559,7 +564,7 @@ if (empty($action) || $action == 'file_manager' || preg_match('/refresh/i',$acti
|
|||||||
|
|
||||||
function loadandshowpreview(filedirname,section)
|
function loadandshowpreview(filedirname,section)
|
||||||
{
|
{
|
||||||
//alert('filename='+filename);
|
alert('filename='+filename);
|
||||||
jQuery('#ecmfileview').empty();
|
jQuery('#ecmfileview').empty();
|
||||||
|
|
||||||
url='<?php echo dol_buildpath('/core/ajax/ajaxdirpreview.php',1); ?>?action=preview&module=ecm§ion='+section+'&file='+urlencode(filedirname);
|
url='<?php echo dol_buildpath('/core/ajax/ajaxdirpreview.php',1); ?>?action=preview&module=ecm§ion='+section+'&file='+urlencode(filedirname);
|
||||||
@@ -584,9 +589,11 @@ if (empty($action) || $action == 'file_manager' || preg_match('/refresh/i',$acti
|
|||||||
|
|
||||||
jQuery(document).ready( function() {
|
jQuery(document).ready( function() {
|
||||||
jQuery('#filetree').fileTree({ root: '<?php print dol_escape_js($openeddir); ?>',
|
jQuery('#filetree').fileTree({ root: '<?php print dol_escape_js($openeddir); ?>',
|
||||||
|
// Called if we click on a file (not a dir)
|
||||||
script: '<?php echo DOL_URL_ROOT.'/core/ajax/ajaxdirtree.php?modulepart=ecm&openeddir='.urlencode($openeddir); ?>',
|
script: '<?php echo DOL_URL_ROOT.'/core/ajax/ajaxdirtree.php?modulepart=ecm&openeddir='.urlencode($openeddir); ?>',
|
||||||
folderEvent: 'click',
|
folderEvent: 'click',
|
||||||
multiFolder: false },
|
multiFolder: false },
|
||||||
|
// Called if we click on a file (not a dir)
|
||||||
function(file) {
|
function(file) {
|
||||||
jQuery("#mesg").hide();
|
jQuery("#mesg").hide();
|
||||||
loadandshowpreview(file,0);
|
loadandshowpreview(file,0);
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ class AllTests
|
|||||||
$suite->addTestSuite('ImagesLibTest');
|
$suite->addTestSuite('ImagesLibTest');
|
||||||
require_once dirname(__FILE__).'/FunctionsTest.php';
|
require_once dirname(__FILE__).'/FunctionsTest.php';
|
||||||
$suite->addTestSuite('FunctionsTest');
|
$suite->addTestSuite('FunctionsTest');
|
||||||
|
require_once dirname(__FILE__).'/Functions2Test.php';
|
||||||
|
$suite->addTestSuite('Functions2Test');
|
||||||
|
|
||||||
require_once dirname(__FILE__).'/SecurityTest.php';
|
require_once dirname(__FILE__).'/SecurityTest.php';
|
||||||
$suite->addTestSuite('SecurityTest');
|
$suite->addTestSuite('SecurityTest');
|
||||||
|
|||||||
@@ -114,6 +114,38 @@ class FilesLibTest extends PHPUnit_Framework_TestCase
|
|||||||
print __METHOD__."\n";
|
print __METHOD__."\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testDolBasename
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function testDolBasename()
|
||||||
|
{
|
||||||
|
global $conf,$user,$langs,$db;
|
||||||
|
$conf=$this->savconf;
|
||||||
|
$user=$this->savuser;
|
||||||
|
$langs=$this->savlangs;
|
||||||
|
$db=$this->savdb;
|
||||||
|
|
||||||
|
$result=dol_basename('adir/afile');
|
||||||
|
print __METHOD__." result=".$result."\n";
|
||||||
|
$this->assertEquals('afile',$result);
|
||||||
|
|
||||||
|
$result=dol_basename('adir/afile/');
|
||||||
|
print __METHOD__." result=".$result."\n";
|
||||||
|
$this->assertEquals('afile',$result);
|
||||||
|
|
||||||
|
$result=dol_basename('adir/νεο'); // With cyrillic data. Here basename fails to return correct value
|
||||||
|
print __METHOD__." result=".$result."\n";
|
||||||
|
$this->assertEquals('νεο',$result);
|
||||||
|
|
||||||
|
$result=dol_basename('adir/νεο/'); // With cyrillic data. Here basename fails to return correct value
|
||||||
|
print __METHOD__." result=".$result."\n";
|
||||||
|
$this->assertEquals('νεο',$result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* testDolCountNbOfLine
|
* testDolCountNbOfLine
|
||||||
*
|
*
|
||||||
|
|||||||
134
test/phpunit/Functions2Test.php
Executable file
134
test/phpunit/Functions2Test.php
Executable file
@@ -0,0 +1,134 @@
|
|||||||
|
<?php
|
||||||
|
/* Copyright (C) 2010-2012 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* or see http://www.gnu.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file test/phpunit/FunctionsTest.php
|
||||||
|
* \ingroup test
|
||||||
|
* \brief PHPUnit test
|
||||||
|
* \remarks To run this script as CLI: phpunit filename.php
|
||||||
|
*/
|
||||||
|
|
||||||
|
global $conf,$user,$langs,$db;
|
||||||
|
//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver
|
||||||
|
require_once 'PHPUnit/Autoload.php';
|
||||||
|
require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
|
||||||
|
require_once dirname(__FILE__).'/../../htdocs/core/lib/functions2.lib.php';
|
||||||
|
|
||||||
|
if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1');
|
||||||
|
if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1');
|
||||||
|
if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1');
|
||||||
|
if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');
|
||||||
|
if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1');
|
||||||
|
if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1');
|
||||||
|
if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no menu to show
|
||||||
|
if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php
|
||||||
|
if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1');
|
||||||
|
if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for PHPUnit tests
|
||||||
|
*
|
||||||
|
* @backupGlobals disabled
|
||||||
|
* @backupStaticAttributes enabled
|
||||||
|
* @remarks backupGlobals must be disabled to have db,conf,user and lang not erased.
|
||||||
|
*/
|
||||||
|
class Functions2Test extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
protected $savconf;
|
||||||
|
protected $savuser;
|
||||||
|
protected $savlangs;
|
||||||
|
protected $savdb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* We save global variables into local variables
|
||||||
|
*
|
||||||
|
* @return CoreTest
|
||||||
|
*/
|
||||||
|
function Functions2Test()
|
||||||
|
{
|
||||||
|
//$this->sharedFixture
|
||||||
|
global $conf,$user,$langs,$db;
|
||||||
|
$this->savconf=$conf;
|
||||||
|
$this->savuser=$user;
|
||||||
|
$this->savlangs=$langs;
|
||||||
|
$this->savdb=$db;
|
||||||
|
|
||||||
|
print __METHOD__." db->type=".$db->type." user->id=".$user->id;
|
||||||
|
//print " - db ".$db->db;
|
||||||
|
print "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static methods
|
||||||
|
public static function setUpBeforeClass()
|
||||||
|
{
|
||||||
|
global $conf,$user,$langs,$db;
|
||||||
|
//$db->begin(); // This is to have all actions inside a transaction even if test launched without suite.
|
||||||
|
|
||||||
|
print __METHOD__."\n";
|
||||||
|
}
|
||||||
|
public static function tearDownAfterClass()
|
||||||
|
{
|
||||||
|
global $conf,$user,$langs,$db;
|
||||||
|
//$db->rollback();
|
||||||
|
|
||||||
|
print __METHOD__."\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init phpunit tests
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
global $conf,$user,$langs,$db;
|
||||||
|
$conf=$this->savconf;
|
||||||
|
$user=$this->savuser;
|
||||||
|
$langs=$this->savlangs;
|
||||||
|
$db=$this->savdb;
|
||||||
|
|
||||||
|
print __METHOD__."\n";
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* End phpunit tests
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function tearDown()
|
||||||
|
{
|
||||||
|
print __METHOD__."\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testJsUnEscape
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testJsUnEscape()
|
||||||
|
{
|
||||||
|
$result=jsUnEscape('%u03BD%u03B5%u03BF');
|
||||||
|
print __METHOD__." result=".$result."\n";
|
||||||
|
$this->assertEquals('νεο',$result);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
Reference in New Issue
Block a user