From 643309dc6ad280ad8fee15cceaaccc97f557aa9c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Jan 2021 15:50:19 +0100 Subject: [PATCH 1/6] Update doc --- ChangeLog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index aff7be3c35e..7282e2e3423 100644 --- a/ChangeLog +++ b/ChangeLog @@ -238,7 +238,7 @@ Following changes may create regressions for some external modules, but were nec * All properties ->titre have been renamed into ->title * Property $paiementid in API 'api_supplier_invoices.php' has been renamed into into $payment_mode_id * Property 'num_paiement' has been renamed 'num_payment' everywhere for better code consistency. -* The deprecated subsitution key __SIGNATURE__ has been removed. Use __USER_SIGNATURE__ if you used the old syntax in your email templates. +* The deprecated subsitution key __SIGNATURE__ has been removed. Replace it with __USER_SIGNATURE__ if you used the old syntax in your email templates. * The hidden option HOLIDAY_MORE_PUBLIC_HOLIDAYS has been removed. Use instead the dictionary table if you need to define custom days of holiday. * If you build a class that implement CommonObject to use the incoterm properties or methods (->fk_incoterm, ->label_incoterm, ->location_incoterm), you must now also include declaration of the Trait 'CommonIncoterm' in your class. All incoterm functions were moved into this Trait. @@ -251,6 +251,7 @@ Following changes may create regressions for some external modules, but were nec * Context for hook showSocinfoOnPrint has been moved from "showsocinfoonprint" to "main" * Library htdocs/includes/phpoffice/phpexcel as been removed (replaced with htdocs/includes/phpoffice/PhpSpreadsheet) * Databse transaction in your triggers must be correctly balanced (one close for one open). If not, an error will be returned by the trigger, even if trigger did return error code. +* Dolibarr v13 is still compatible with any PHP version between 5.6.0 and 7.4.*; Unit tests are OK with PHP 8.0 but some warnings or troubles may appears with PHP 8.0. ***** ChangeLog for 12.0.4 compared to 12.0.3 ***** From 56d13c96f4483257f0538f041557908d78419e2b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Jan 2021 15:51:14 +0100 Subject: [PATCH 2/6] Doc --- ChangeLog | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7282e2e3423..a6f0d9d7086 100644 --- a/ChangeLog +++ b/ChangeLog @@ -182,8 +182,7 @@ NEW: add option "If the feature to manage kits of module Stock is used, show det For developers: --------------- -NEW: add __MEMBER_TYPE__ substitution key -NEW: add __TYPE__ substitution key +NEW: add __MEMBER_TYPE__ and __TYPE__ substitution key NEW: add function dolButtonToOpenUrlInDialogPopup() to be able to open page into a popup NEW: show line number on intervention card (via MAIN_VIEW_LINE_NUMBER) NEW: Add some fields to link website page to an other object @@ -198,7 +197,6 @@ NEW: allow to edit "demand reason" field though API NEW: fetch contact by email with REST API NEW: field ref_ext in llx_commandedet NEW: fields ref_ext for Attributes and Combinations -NEW: get state by REST API NEW: get state dictionnary by REST API NEW: improve Product API for variant products NEW: OAuth SCOPE for Admin SDK From 84bab7169e827b115853e40478e7ab8971a921e3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 24 Jan 2021 15:52:17 +0100 Subject: [PATCH 3/6] Document --- ChangeLog | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index a6f0d9d7086..f4afde7fb45 100644 --- a/ChangeLog +++ b/ChangeLog @@ -194,16 +194,10 @@ NEW: can add event to log into blockedlog module with a constant NEW: add property cssview when declaring fields of an object NEW: Can use dynamic code into the 'enabled' property of DAO fields NEW: allow to edit "demand reason" field though API -NEW: fetch contact by email with REST API NEW: field ref_ext in llx_commandedet NEW: fields ref_ext for Attributes and Combinations -NEW: get state dictionnary by REST API -NEW: improve Product API for variant products NEW: OAuth SCOPE for Admin SDK -NEW: retrieve discount from invoice from API NEW: standardizes API thirdparties by email like other object -NEW: Thirdparty REST API: endpoint to set price level -NEW: use new category API for project list view NEW: Triggers Attributes and Attributes values NEW: added incoterms data into the substitution array NEW: add send context for ticket @@ -219,6 +213,12 @@ NEW: API can update a payment NEW: API get member by thirdparty NEW: API get thirdparty by barcode NEW: API get users by email / login +NEW: fetch contact by email with REST API +NEW: get state dictionnary by REST API +NEW: improve Product API for variant products +NEW: retrieve discount from invoice from API +NEW: Thirdparty REST API: endpoint to set price level +NEW: use new category API for project list view HOOKs NEW: Hook on propal card From 13378897a876c38a4abbd17d16dabcd5982afe88 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 25 Jan 2021 22:46:09 +0100 Subject: [PATCH 4/6] FIX Report by Ricardo Matias Conflicts: test/phpunit/SecurityTest.php --- htdocs/core/lib/functions.lib.php | 12 +- htdocs/main.inc.php | 15 +++ htdocs/user/class/user.class.php | 41 +++---- htdocs/user/home.php | 2 +- test/phpunit/SecurityTest.php | 178 ++++++++++++++++-------------- 5 files changed, 141 insertions(+), 107 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 4a639c69a69..142d91565d6 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -686,7 +686,7 @@ function checkVal($out = '', $check = 'alphanohtml', $filter = null, $options = $out = dol_string_nohtmltag($out, 0); } break; - case 'alphawithlgt': // No " and no ../ but we keep < > tags. Can be used for email string like "Name " + case 'alphawithlgt': // No " and no ../ but we keep balanced < > tags with no special chars inside. Can be used for email string like "Name " if (!is_array($out)) { // '"' is dangerous because param in url can close the href= or src= and add javascript functions. // '../' is dangerous because it allows dir transversals @@ -5762,7 +5762,7 @@ function picto_required() * @param string $stringtoclean String to clean * @param integer $removelinefeed 1=Replace all new lines by 1 space, 0=Only ending new lines are removed others are replaced with \n, 2=Ending new lines are removed but others are kept with a same number of \n than nb of
when there is both "...
\n..." * @param string $pagecodeto Encoding of input/output string - * @param integer $strip_tags 0=Use internal strip, 1=Use strip_tags() php function (bugged when text contains a < char that is not for a html tag) + * @param integer $strip_tags 0=Use internal strip, 1=Use strip_tags() php function (bugged when text contains a < char that is not for a html tag or when tags is not closed like '0000-021 - $temp = preg_replace($pattern, "", $temp); // pass 1 - // $temp after pass 1: 0000-021 - $temp = preg_replace($pattern, "", $temp); // pass 2 - // $temp after pass 2: 0000-021 + $temp = preg_replace($pattern, "", $temp); // pass 1 - $temp after pass 1: 0000-021 + $temp = preg_replace($pattern, "", $temp); // pass 2 - $temp after pass 2: 0000-021 + // removed '<' into non closing html tags like 'error=alert(1) to bypass test on onerror + $tmpval = preg_replace('/<[^<]+>/', '', $val); + // List of dom events is on https://www.w3schools.com/jsref/dom_obj_event.asp + $inj += preg_match('/onmouse([a-z]*)\s*=/i', $tmpval); // onmousexxx can be set on img or any html tag like + $inj += preg_match('/ondrag([a-z]*)\s*=/i', $tmpval); // + $inj += preg_match('/ontouch([a-z]*)\s*=/i', $tmpval); // + $inj += preg_match('/on(abort|afterprint|beforeprint|beforeunload|blur|canplay|canplaythrough|change|click|contextmenu|copy|cut)\s*=/i', $tmpval); + $inj += preg_match('/on(dblclick|drop|durationchange|ended|error|focus|focusin|focusout|hashchange|input|invalid)\s*=/i', $tmpval); + $inj += preg_match('/on(keydown|keypress|keyup|load|loadeddata|loadedmetadata|loadstart|offline|online|pagehide|pageshow)\s*=/i', $tmpval); + $inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|resize|reset|scroll|search|seeking|select|show|stalled|start|submit|suspend)\s*=/i', $tmpval); + $inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting)\s*=/i', $tmpval); + //$inj += preg_match('/on[A-Z][a-z]+\*=/', $val); // To lock event handlers onAbort(), ... $inj += preg_match('/:|:|:/i', $val); // refused string ':' encoded (no reason to have it encoded) to lock 'javascript:...' $inj += preg_match('/javascript\s*:/i', $val); diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 89c13670890..241057047e5 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2430,53 +2430,54 @@ class User extends CommonObject $label .= '
'; $label .= img_picto('', $this->picto).' '.$langs->trans("User").''; $label .= ' '.$this->getLibStatut(4); - $label .= '
'.$langs->trans('Name').': '.$this->getFullName($langs, ''); + $label .= '
'.$langs->trans('Name').': '.dol_string_nohtmltag($this->getFullName($langs, '')); if (!empty($this->login)) { - $label .= '
'.$langs->trans('Login').': '.$this->login; + $label .= '
'.$langs->trans('Login').': '.dol_string_nohtmltag($this->login); } if (!empty($this->job)) { - $label .= '
'.$langs->trans("Job").': '.$this->job; + $label .= '
'.$langs->trans("Job").': '.dol_string_nohtmltag($this->job); } - $label .= '
'.$langs->trans("Email").': '.$this->email; + $label .= '
'.$langs->trans("Email").': '.dol_string_nohtmltag($this->email); if (!empty($this->phone)) { - $label .= '
'.$langs->trans("Phone").': '.$this->phone; + $label .= '
'.$langs->trans("Phone").': '.dol_string_nohtmltag($this->phone); } if (!empty($this->admin)) { $label .= '
'.$langs->trans("Administrator").': '.yn($this->admin); } + $company = ''; if (!empty($this->socid)) { // Add thirdparty for external users $thirdpartystatic = new Societe($db); $thirdpartystatic->fetch($this->socid); if (empty($hidethirdpartylogo)) { $companylink = ' '.$thirdpartystatic->getNomUrl(2, (($option == 'nolink') ? 'nolink' : '')); // picto only of company } - $company = ' ('.$langs->trans("Company").': '.$thirdpartystatic->name.')'; + $company = ' ('.$langs->trans("Company").': '.dol_string_nohtmltag($thirdpartystatic->name).')'; } $type = ($this->socid ? $langs->trans("External").$company : $langs->trans("Internal")); - $label .= '
'.$langs->trans("Type").': '.$type; + $label .= '
'.$langs->trans("Type").': '.dol_string_nohtmltag($type); $label .= '
'; if ($infologin > 0) { $label .= '
'; $label .= '
'.$langs->trans("Session").''; - $label .= '
'.$langs->trans("IPAddress").': '.$_SERVER["REMOTE_ADDR"]; + $label .= '
'.$langs->trans("IPAddress").': '.dol_string_nohtmltag(getUserRemoteIP()); if (!empty($conf->global->MAIN_MODULE_MULTICOMPANY)) { - $label .= '
'.$langs->trans("ConnectedOnMultiCompany").': '.$conf->entity.' (user entity '.$this->entity.')'; + $label .= '
'.$langs->trans("ConnectedOnMultiCompany").': '.$conf->entity.' (User entity '.$this->entity.')'; } - $label .= '
'.$langs->trans("AuthenticationMode").': '.$_SESSION["dol_authmode"].(empty($dolibarr_main_demo) ? '' : ' (demo)'); + $label .= '
'.$langs->trans("AuthenticationMode").': '.dol_string_nohtmltag($_SESSION["dol_authmode"].(empty($dolibarr_main_demo) ? '' : ' (demo)')); $label .= '
'.$langs->trans("ConnectedSince").': '.dol_print_date($this->datelastlogin, "dayhour", 'tzuser'); $label .= '
'.$langs->trans("PreviousConnexion").': '.dol_print_date($this->datepreviouslogin, "dayhour", 'tzuser'); - $label .= '
'.$langs->trans("CurrentTheme").': '.$conf->theme; - $label .= '
'.$langs->trans("CurrentMenuManager").': '.$menumanager->name; + $label .= '
'.$langs->trans("CurrentTheme").': '.dol_string_nohtmltag($conf->theme); + $label .= '
'.$langs->trans("CurrentMenuManager").': '.dol_string_nohtmltag($menumanager->name); $s = picto_from_langcode($langs->getDefaultLang()); - $label .= '
'.$langs->trans("CurrentUserLanguage").': '.($s ? $s.' ' : '').$langs->getDefaultLang(); - $label .= '
'.$langs->trans("Browser").': '.$conf->browser->name.($conf->browser->version ? ' '.$conf->browser->version : '').' ('.$_SERVER['HTTP_USER_AGENT'].')'; - $label .= '
'.$langs->trans("Layout").': '.$conf->browser->layout; - $label .= '
'.$langs->trans("Screen").': '.$_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight']; + $label .= '
'.$langs->trans("CurrentUserLanguage").': '.dol_string_nohtmltag(($s ? $s.' ' : '').$langs->getDefaultLang()); + $label .= '
'.$langs->trans("Browser").': '.dol_string_nohtmltag($conf->browser->name.($conf->browser->version ? ' '.$conf->browser->version : '').' ('.$_SERVER['HTTP_USER_AGENT'].')'); + $label .= '
'.$langs->trans("Layout").': '.dol_string_nohtmltag($conf->browser->layout); + $label .= '
'.$langs->trans("Screen").': '.dol_string_nohtmltag($_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight']); if ($conf->browser->layout == 'phone') { $label .= '
'.$langs->trans("Phone").': '.$langs->trans("Yes"); } if (!empty($_SESSION["disablemodules"])) { - $label .= '
'.$langs->trans("DisabledModules").':
'.join(', ', explode(',', $_SESSION["disablemodules"])); + $label .= '
'.$langs->trans("DisabledModules").':
'.dol_string_nohtmltag(join(', ', explode(',', $_SESSION["disablemodules"]))); } } if ($infologin < 0) { @@ -2540,12 +2541,12 @@ class User extends CommonObject } if ($withpictoimg > -2 && $withpictoimg != 2) { if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { - $result .= ''; + $result .= ''; } if ($mode == 'login') { - $result .= dol_trunc($this->login, $maxlen); + $result .= dol_string_nohtmltag(dol_trunc($this->login, $maxlen)); } else { - $result .= $this->getFullName($langs, '', ($mode == 'firstelselast' ? 3 : ($mode == 'firstname' ? 2 : -1)), $maxlen); + $result .= dol_string_nohtmltag($this->getFullName($langs, '', ($mode == 'firstelselast' ? 3 : ($mode == 'firstname' ? 2 : -1)), $maxlen)); } if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $result .= ''; diff --git a/htdocs/user/home.php b/htdocs/user/home.php index 4d215685f53..e294be6a219 100644 --- a/htdocs/user/home.php +++ b/htdocs/user/home.php @@ -128,7 +128,7 @@ if ($resql) print ''; print ''; print ''; - print ''; + print ''."\n"; $i = 0; while ($i < $num && $i < $max) diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index c38cf49d018..f485102e06e 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -171,7 +171,11 @@ class SecurityTest extends PHPUnit\Framework\TestCase $_SERVER["PHP_SELF"]='/DIR WITH SPACE/htdocs/admin/index.php?mainmenu=home&leftmenu=setup&username=weservices'; $result=testSqlAndScriptInject($_SERVER["PHP_SELF"], 2); - $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject 1a'); + $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject expected 0a'); + + $test = 'This is a < inside string with < and > also and tag like before the >'; + $result=testSqlAndScriptInject($test, 0); + $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject expected 0b'); // Should detect XSS $expectedresult=1; @@ -260,6 +264,10 @@ class SecurityTest extends PHPUnit\Framework\TestCase $test="onerror=alert(1)"; $result=testSqlAndScriptInject($test, 0); $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject jjj'); + + $test="rror=alert(document.location)"; + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject kkk'); } /** @@ -270,106 +278,116 @@ class SecurityTest extends PHPUnit\Framework\TestCase public function testGETPOST() { global $conf,$user,$langs,$db; - $conf=$this->savconf; - $user=$this->savuser; - $langs=$this->savlangs; - $db=$this->savdb; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; - $_COOKIE["id"]=111; - $_GET["param1"]="222"; - $_POST["param1"]="333"; - $_GET["param2"]='a/b#e(pr)qq-rr\cc'; - $_GET["param3"]='"na/b#e(pr)qq-rr\cc'; // Same than param2 + " and n - $_GET["param4"]='../dir'; - $_GET["param5"]="a_1-b"; - $_POST["param6"]="">objnotdefined\''; - $_POST["param11"]=' Name '; + $_COOKIE["id"]=111; + $_GET["param1"]="222"; + $_POST["param1"]="333"; + $_GET["param2"]='a/b#e(pr)qq-rr\cc'; + $_GET["param3"]='"na/b#e(pr)qq-rr\cc'; // Same than param2 + " and n + $_GET["param4"]='../dir'; + $_GET["param5"]="a_1-b"; + $_POST["param6"]="">objnotdefined\''; + $_POST["param11"]=' Name '; - $result=GETPOST('id', 'int'); // Must return nothing - print __METHOD__." result=".$result."\n"; - $this->assertEquals($result, ''); + $result=GETPOST('id', 'int'); // Must return nothing + print __METHOD__." result=".$result."\n"; + $this->assertEquals($result, ''); - $result=GETPOST("param1", 'int'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals($result, 222, 'Test on param1 with no 3rd param'); + $result=GETPOST("param1", 'int'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals($result, 222, 'Test on param1 with no 3rd param'); - $result=GETPOST("param1", 'int', 2); - print __METHOD__." result=".$result."\n"; - $this->assertEquals($result, 333, 'Test on param1 with 3rd param = 2'); + $result=GETPOST("param1", 'int', 2); + print __METHOD__." result=".$result."\n"; + $this->assertEquals($result, 333, 'Test on param1 with 3rd param = 2'); - // Test alpha - $result=GETPOST("param2", 'alpha'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals($result, $_GET["param2"], 'Test on param2'); + // Test alpha + $result=GETPOST("param2", 'alpha'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals($result, $_GET["param2"], 'Test on param2'); - $result=GETPOST("param3", 'alpha'); // Must return string sanitized from char " - print __METHOD__." result=".$result."\n"; - $this->assertEquals($result, 'na/b#e(pr)qq-rr\cc', 'Test on param3'); + $result=GETPOST("param3", 'alpha'); // Must return string sanitized from char " + print __METHOD__." result=".$result."\n"; + $this->assertEquals($result, 'na/b#e(pr)qq-rr\cc', 'Test on param3'); - $result=GETPOST("param4", 'alpha'); // Must return string sanitized from ../ - print __METHOD__." result=".$result."\n"; - $this->assertEquals($result, 'dir'); + $result=GETPOST("param4", 'alpha'); // Must return string sanitized from ../ + print __METHOD__." result=".$result."\n"; + $this->assertEquals($result, 'dir'); - // Test aZ09 - $result=GETPOST("param1", 'aZ09'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals($result, $_GET["param1"]); + // Test aZ09 + $result=GETPOST("param1", 'aZ09'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals($result, $_GET["param1"]); - $result=GETPOST("param2", 'aZ09'); // Must return '' as string contains car not in aZ09 definition - print __METHOD__." result=".$result."\n"; - $this->assertEquals($result, ''); + $result=GETPOST("param2", 'aZ09'); // Must return '' as string contains car not in aZ09 definition + print __METHOD__." result=".$result."\n"; + $this->assertEquals($result, ''); - $result=GETPOST("param3", 'aZ09'); // Must return '' as string contains car not in aZ09 definition - print __METHOD__." result=".$result."\n"; - $this->assertEquals($result, ''); + $result=GETPOST("param3", 'aZ09'); // Must return '' as string contains car not in aZ09 definition + print __METHOD__." result=".$result."\n"; + $this->assertEquals($result, ''); - $result=GETPOST("param4", 'aZ09'); // Must return '' as string contains car not in aZ09 definition - print __METHOD__." result=".$result."\n"; - $this->assertEquals('', $result); + $result=GETPOST("param4", 'aZ09'); // Must return '' as string contains car not in aZ09 definition + print __METHOD__." result=".$result."\n"; + $this->assertEquals('', $result); - $result=GETPOST("param5", 'aZ09'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals($_GET["param5"], $result); + $result=GETPOST("param5", 'aZ09'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals($_GET["param5"], $result); - $result=GETPOST("param6", 'alpha'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals('>', $result); + $result=GETPOST("param6", 'alpha'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('>', $result); - $result=GETPOST("param6", 'nohtml'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals('">', $result); + $result=GETPOST("param6", 'nohtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('">', $result); - // With restricthtml we must remove html open/close tag and content but not htmlentities like n - $result=GETPOST("param7", 'restricthtml'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals('"c:\this is a path~1\aaan" abcdef', $result); + // With restricthtml we must remove html open/close tag and content but not htmlentities like n + $result=GETPOST("param7", 'restricthtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('"c:\this is a path~1\aaan" abcdef', $result); - // With alphanohtml, we must convert the html entities like n - $result=GETPOST("param8", 'alphanohtml'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals("HackerassertEquals("Hackersvg onload='console.log(123)'", $result); - $result=GETPOST("param9", 'alphanohtml'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals($_POST["param9"], $result); + $result=GETPOST("param8b", 'alphanohtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('img src=x onerror=alert(document.location) t=', $result, 'Test a string with non closing html tag with alphanohtml'); - $result=GETPOST("param10", 'alphanohtml'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals($_POST["param9"], $result, 'We should get param9 after processing param10'); + $result=GETPOST("param8c", 'alphanohtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals($_POST['param8c'], $result, 'Test a string with non closing html tag with alphanohtml'); - $result=GETPOST("param11", 'alphanohtml'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals("Name", $result, 'Test an email string with alphanohtml'); + $result=GETPOST("param9", 'alphanohtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals($_POST["param9"], $result); - $result=GETPOST("param11", 'alphawithlgt'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals(trim($_POST["param11"]), $result, 'Test an email string with alphawithlgt'); + $result=GETPOST("param10", 'alphanohtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals($_POST["param9"], $result, 'We should get param9 after processing param10'); - return $result; + $result=GETPOST("param11", 'alphanohtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals("Name", $result, 'Test an email string with alphanohtml'); + + $result=GETPOST("param11", 'alphawithlgt'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals(trim($_POST["param11"]), $result, 'Test an email string with alphawithlgt'); + + return $result; } /** From 8db80ff44dadfb76b55771e7a244a3d7a6445fcb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Jan 2021 11:19:13 +0100 Subject: [PATCH 5/6] Fix reponsive --- htdocs/admin/mails.php | 8 +++++++- htdocs/core/lib/admin.lib.php | 10 +++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index 5e32a637c8f..88ae8964c1b 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -532,6 +532,7 @@ if ($action == 'edit') print ''.$langs->trans("EMailsDesc")."
\n"; print "
\n"; + print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table print '
'.$langs->trans("LastUsersCreated", min($num, $max)).''.$langs->trans("FullList").'
'; print ''; @@ -552,10 +553,12 @@ if ($action == 'edit') } print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + print ''; if (empty($conf->global->MAIN_DISABLE_ALL_MAILS)) { print '
'; + print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table print ''; print ''; @@ -663,6 +666,7 @@ if ($action == 'edit') } print '
'.$langs->trans("MAIN_MAIL_SENDMODE").'
'; + print '
'; if ($conf->global->MAIN_MAIL_SENDMODE == 'mail' && empty($conf->global->MAIN_HIDE_WARNING_TO_ENCOURAGE_SMTP_SETUP)) { print info_admin($langs->trans("WarningPHPMail").'
'.$langs->trans("WarningPHPMailA").'
'.$langs->trans("WarningPHPMailB").'
'.$langs->trans("WarningPHPMailC").'

'.$langs->trans("WarningPHPMailD"), 0, 0, 'warning'); @@ -670,11 +674,12 @@ if ($action == 'edit') print '
'; + print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table print ''; print ''; // From - print ''; + print ''; print ''; @@ -746,6 +751,7 @@ if ($action == 'edit') print ''; print '
'.$langs->trans("OtherOptions").'
'.$langs->trans("MAIN_MAIL_EMAIL_FROM", ini_get('sendmail_from') ?ini_get('sendmail_from') : $langs->transnoentities("Undefined")).'
'.$langs->trans("MAIN_MAIL_EMAIL_FROM", ini_get('sendmail_from') ?ini_get('sendmail_from') : $langs->transnoentities("Undefined")).''.$conf->global->MAIN_MAIL_EMAIL_FROM; if (!empty($conf->global->MAIN_MAIL_EMAIL_FROM) && !isValidEmail($conf->global->MAIN_MAIL_EMAIL_FROM)) print img_warning($langs->trans("ErrorBadEMail")); print '
'.$langs->trans("MAIN_MAIL_ENABLED_USER_DEST_SELECT").''.yn($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT).'
'; + print '
'; } print dol_get_fiche_end(); diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index f3faeda4b3a..ce9ffb31697 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -1870,11 +1870,6 @@ function email_admin_prepare_head() } } - $head[$h][0] = DOL_URL_ROOT."/admin/mails_templates.php"; - $head[$h][1] = $langs->trans("EMailTemplates"); - $head[$h][2] = 'templates'; - $h++; - if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { $head[$h][0] = DOL_URL_ROOT."/admin/mails_senderprofile_list.php"; $head[$h][1] = $langs->trans("EmailSenderProfiles"); @@ -1882,6 +1877,11 @@ function email_admin_prepare_head() $h++; } + $head[$h][0] = DOL_URL_ROOT."/admin/mails_templates.php"; + $head[$h][1] = $langs->trans("EMailTemplates"); + $head[$h][2] = 'templates'; + $h++; + complete_head_from_modules($conf, $langs, null, $head, $h, 'email_admin', 'remove'); return $head; From 977e4dde865f3ccf1ab8618af8bc7fbdd1c71ec1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 26 Jan 2021 12:08:54 +0100 Subject: [PATCH 6/6] Fix regression --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 142d91565d6..d2e919e49fe 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5786,7 +5786,7 @@ function dol_string_nohtmltag($stringtoclean, $removelinefeed = 1, $pagecodeto = $temp = preg_replace($pattern, "", $temp); // pass 1 - $temp after pass 1:
0000-021 $temp = preg_replace($pattern, "", $temp); // pass 2 - $temp after pass 2: 0000-021 // removed '<' into non closing html tags like '