From a0444ef55d379a633554dfd32f1d914e2df07abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 4 Mar 2024 17:58:43 +0100 Subject: [PATCH 1/9] fix can't delete pdf if ref is not encoded (#28630) --- htdocs/compta/facture/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index ea9b87b1de6..c156eccb5f3 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -4477,7 +4477,7 @@ if ($action == 'create') { $file = GETPOST('file', 'alpha'); $formconfirm = $form->formconfirm( - $_SERVER["PHP_SELF"].'?facid='.$object->id.'&file='.$file, + $_SERVER["PHP_SELF"].'?facid='.$object->id.'&file='.urlencode($file), $langs->trans('DeleteFileHeader'), $langs->trans('DeleteFileText')."

".$file, 'remove_file', From d0c0dee616968d13f14385d975266c9857ba97a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 4 Mar 2024 18:23:03 +0100 Subject: [PATCH 2/9] fix typo in ChangeLog (#28613) * fix typo in ChangeLog * Update ChangeLog --- ChangeLog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index de0cb66b968..bb3afe1e22e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,7 +24,7 @@ FIX: Bad column for total in bom list FIX: Bad condition on button back to draft on recruitment job. FIX: Bad CRLF when sending text only content. Fix dol_htmlwithnojs() FIX: Bad picto on list of permission of a user when user not admin -FIX: bad timzeone for the start/end date of an event +FIX: bad timezone for the start/end date of an event FIX: Better test on validity of compute field syntax with parenthesis FIX: close #28279 FIX: disabled pito of menu must be greyed. @@ -47,7 +47,7 @@ FIX: Shipment closing action has wrong value (#28174) FIX: some tooltips has disappeared on invoice action button FIX: Special code is now transmitted by args only in order supplier (#28546) FIX: subscription must be editable when accounting isn't reconciled (#28469) -FIX: Value of field int = 0 from modulebuilder must nto be set to null +FIX: Value of field int = 0 from modulebuilder must not be set to null ***** ChangeLog for 19.0.0 compared to 18.0.0 ***** From 6cc9ac55429f37b83f058993875e62181bfec534 Mon Sep 17 00:00:00 2001 From: Christian Humpel <78662388+Humml87@users.noreply.github.com> Date: Mon, 4 Mar 2024 18:59:37 +0100 Subject: [PATCH 3/9] FIX: Count of virtual stock at Services and MoLine with disabled stock change (#28580) * fix the count of virtual stock * - fix "Found non sanitized string" ? --------- Co-authored-by: christian.humpel --- htdocs/product/class/product.class.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 5288300c443..b959d87063f 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -3469,6 +3469,8 @@ class Product extends CommonObject // phpcs:enable global $conf, $user, $hookmanager, $action; + $serviceStockIsEnabled = isModEnabled("service") && getDolGlobalString('STOCK_SUPPORTS_SERVICES'); + $sql = "SELECT COUNT(DISTINCT m.fk_soc) as nb_customers, COUNT(DISTINCT m.rowid) as nb,"; $sql .= " COUNT(mp.rowid) as nb_rows, SUM(mp.qty) as qty, role"; $sql .= " FROM ".$this->db->prefix()."mrp_production as mp"; @@ -3480,6 +3482,7 @@ class Product extends CommonObject $sql .= " WHERE m.rowid = mp.fk_mo"; $sql .= " AND m.entity IN (".getEntity($forVirtualStock && getDolGlobalString('STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE') ? 'stock' : 'mrp').")"; $sql .= " AND mp.fk_product = ".((int) $this->id); + $sql .= " AND mp.disable_stock_change IN (0)"; if (!$user->hasRight('societe', 'client', 'voir') && !$socid && !$forVirtualStock) { $sql .= " AND m.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -3492,6 +3495,9 @@ class Product extends CommonObject if (!empty($dateofvirtualstock)) { $sql .= " AND m.date_valid <= '".$this->db->idate($dateofvirtualstock)."'"; // better date to code ? end of production ? } + if (!$serviceStockIsEnabled) { + $sql .= "AND EXISTS (SELECT p.rowid FROM ".$this->db->prefix()."product AS p WHERE p.rowid = ".((int) $this->id)." AND p.fk_product_type IN (0))"; + } $sql .= " GROUP BY role"; $this->stats_mrptoconsume['customers'] = 0; From d7f3feba747b9177a80d11384cbb3bae84dc9642 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 5 Mar 2024 03:57:56 +0100 Subject: [PATCH 4/9] Merge branch '18.0' of git@github.com:Dolibarr/dolibarr.git into 19.0 --- 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 f21e08e8261..6fe032f5456 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2224,7 +2224,7 @@ function dol_get_fiche_head($links = array(), $active = '', $title = '', $notab $tabsname = str_replace("@", "", $picto); } $out .= '
'; - $out .= ''; // Do not use "reposition" class in the "More". + $out .= ''; // Do not use "reposition" class in the "More". $out .= '
'; $out .= $outmore; $out .= '
'; From 26c307c0a422558d6224b9366bd938ccd3b6fb9d Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Tue, 5 Mar 2024 17:16:11 +0100 Subject: [PATCH 5/9] Fix extrafield ajax search default on edit (#28631) --- htdocs/core/class/html.form.class.php | 49 +++++++++++++++++---------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 29cb68f171d..40e93918771 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -8014,22 +8014,22 @@ class Form * Can use autocomplete with ajax after x key pressed or a full combo, depending on setup. * This is the generic method that will replace all specific existing methods. * - * @param string $objectdesc 'ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]'. For hard coded custom needs. Try to prefer method using $objectfield instead of $objectdesc. - * @param string $htmlname Name of HTML select component - * @param int $preselectedvalue Preselected value (ID of element) - * @param string $showempty ''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...) - * @param string $searchkey Search criteria - * @param string $placeholder Place holder - * @param string $morecss More CSS - * @param string $moreparams More params provided to ajax call - * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification) - * @param int $disabled 1=Html component is disabled - * @param string $selected_input_value Value of preselected input text (for use with ajax) - * @param string $objectfield Object:Field that contains the definition (in table $fields or $extrafields). Example: 'Object:xxx' or 'Module_Object:xxx' or 'Object:options_xxx' or 'Module_Object:options_xxx' + * @param string $objectdesc 'ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]'. For hard coded custom needs. Try to prefer method using $objectfield instead of $objectdesc. + * @param string $htmlname Name of HTML select component + * @param int $preSelectedValue Preselected value (ID of element) + * @param string $showempty ''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...) + * @param string $searchkey Search criteria + * @param string $placeholder Place holder + * @param string $morecss More CSS + * @param string $moreparams More params provided to ajax call + * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification) + * @param int $disabled 1=Html component is disabled + * @param string $selected_input_value Value of preselected input text (for use with ajax) + * @param string $objectfield Object:Field that contains the definition (in table $fields or $extrafields). Example: 'Object:xxx' or 'Module_Object:xxx' or 'Object:options_xxx' or 'Module_Object:options_xxx' * @return string Return HTML string * @see selectForFormsList(), select_thirdparty_list() */ - public function selectForForms($objectdesc, $htmlname, $preselectedvalue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $disabled = 0, $selected_input_value = '', $objectfield = '') + public function selectForForms($objectdesc, $htmlname, $preSelectedValue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $disabled = 0, $selected_input_value = '', $objectfield = '') { global $conf, $extrafields, $user; @@ -8128,10 +8128,23 @@ class Form if (!empty($conf->use_javascript_ajax) && getDolGlobalString($confkeyforautocompletemode) && !$forcecombo) { // No immediate load of all database $placeholder = ''; - if ($preselectedvalue && empty($selected_input_value)) { - $objecttmp->fetch($preselectedvalue); + + if ($preSelectedValue && empty($selected_input_value)) { + $objecttmp->fetch($preSelectedValue); $selected_input_value = ($prefixforautocompletemode == 'company' ? $objecttmp->name : $objecttmp->ref); - //unset($objecttmp); + + $oldValueForShowOnCombobox = 0; + foreach ($objecttmp->fields as $fieldK => $fielV) { + if (!$fielV['showoncombobox'] || empty($objecttmp->$fieldK)) continue; + + if (!$oldValueForShowOnCombobox) { + $selected_input_value = ''; + } + + $selected_input_value .= $oldValueForShowOnCombobox ? ' - ' : ''; + $selected_input_value .= $objecttmp->$fieldK; + $oldValueForShowOnCombobox = empty($fielV['showoncombobox']) ? 0 : $fielV['showoncombobox']; + } } // Set url and param to call to get json of the search results @@ -8139,12 +8152,12 @@ class Form $urloption = 'htmlname=' . urlencode($htmlname) . '&outjson=1&objectdesc=' . urlencode($objectdescorig) . '&objectfield='.urlencode($objectfield) . ($sortfield ? '&sortfield=' . urlencode($sortfield) : ''); // Activate the auto complete using ajax call. - $out .= ajax_autocompleter($preselectedvalue, $htmlname, $urlforajaxcall, $urloption, getDolGlobalString($confkeyforautocompletemode), 0, array()); + $out .= ajax_autocompleter($preSelectedValue, $htmlname, $urlforajaxcall, $urloption, getDolGlobalString($confkeyforautocompletemode), 0); $out .= ''; $out .= ''; } else { // Immediate load of table record. - $out .= $this->selectForFormsList($objecttmp, $htmlname, $preselectedvalue, $showempty, $searchkey, $placeholder, $morecss, $moreparams, $forcecombo, 0, $disabled, $sortfield, $filter); + $out .= $this->selectForFormsList($objecttmp, $htmlname, $preSelectedValue, $showempty, $searchkey, $placeholder, $morecss, $moreparams, $forcecombo, 0, $disabled, $sortfield, $filter); } return $out; From 43b1adb4c6551cf26d5cd516f609af80b21301a9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 6 Mar 2024 01:40:06 +0100 Subject: [PATCH 6/9] Fix bad var name in security setup page --- htdocs/admin/system/security.php | 4 ++-- htdocs/langs/en_US/errors.lang | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 6ad04701a52..199b715d2ef 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -272,7 +272,7 @@ print '
'; if (file_exists($installlock)) { // If install not locked, no need to show this. if (file_exists($upgradeunlock)) { print ''.$langs->trans("DolibarrUpgrade").': '; - print img_warning().' '.$langs->trans("UpgradeHasBeenUnlocked", $upgradeunlock); + print img_warning().' '.$langs->trans("WarningUpgradeHasBeenUnlocked", $upgradeunlock); print '
'; } } @@ -756,7 +756,7 @@ print '
'; print 'WEBSITE_MAIN_SECURITY_FORCERP = '.getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCERP', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or")." \"strict-origin-when-cross-origin\")
"; print '
'; -print 'WEBSITE_MAIN_SECURITY_FORCESTS = '.getDolGlobalString('>WEBSITE_MAIN_SECURITY_FORCESTS', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Example").": \"max-age=31536000; includeSubDomains\")
"; +print 'WEBSITE_MAIN_SECURITY_FORCESTS = '.getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCESTS', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Example").": \"max-age=31536000; includeSubDomains\")
"; print '
'; print 'WEBSITE_MAIN_SECURITY_FORCEPP = '.getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCEPP', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Example").": \"camera: (); microphone: ();\")
"; diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index b4883e7f6f4..625cb2bfc51 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -343,6 +343,7 @@ WarningConfFileMustBeReadOnly=Warning, your config file (htdocs/conf/conf.php WarningsOnXLines=Warnings on %s source record(s) WarningNoDocumentModelActivated=No model, for document generation, has been activated. A model will be chosen by default until you check your module setup. WarningLockFileDoesNotExists=Warning, once setup is finished, you must disable the installation/migration tools by adding a file install.lock into directory %s. Omitting the creation of this file is a grave security risk. +WarningUpgradeHasBeenUnlocked=Warning, upgrade process has been unlocked for everybody WarningUntilDirRemoved=This security warning will remain active as long as the vulnerability is present. WarningCloseAlways=Warning, closing is done even if amount differs between source and target elements. Enable this feature with caution. WarningUsingThisBoxSlowDown=Warning, using this box slow down seriously all pages showing the box. From 1552fac711177f376dee15e39812107619d681db Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 6 Mar 2024 01:54:41 +0100 Subject: [PATCH 7/9] Fix strict-origin --- htdocs/admin/system/security.php | 2 +- htdocs/main.inc.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 199b715d2ef..fce38310605 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -753,7 +753,7 @@ print 'WEBSITE_MAIN_SECURITY_FORCECSP = '.getDolGlobalString('W print '   ('.$langs->trans("Example").": \"frame-ancestors 'self'; default-src 'self' 'unsafe-inline'; style-src https://cdnjs.cloudflare.com *.googleapis.com; script-src *.transifex.com *.google-analytics.com *.googletagmanager.com; object-src https://youtube.com; frame-src https://youtube.com; img-src * data:;\")
"; print '
'; -print 'WEBSITE_MAIN_SECURITY_FORCERP = '.getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCERP', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or")." \"strict-origin-when-cross-origin\")
"; +print 'WEBSITE_MAIN_SECURITY_FORCERP = '.getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCERP', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").'=\"strict-origin\" '.$langs->trans("or")." \"strict-origin-when-cross-origin\")
"; print '
'; print 'WEBSITE_MAIN_SECURITY_FORCESTS = '.getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCESTS', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Example").": \"max-age=31536000; includeSubDomains\")
"; diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 548d2fb2099..44b62e8bb8f 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1669,9 +1669,9 @@ function top_httphead($contenttype = 'text/html', $forcenocache = 0) // Referrer-Policy // Say if we must provide the referrer when we jump onto another web page. - // Default browser are 'strict-origin-when-cross-origin' (only domain is sent on other domain switching), we want more so we use 'same-origin' so browser doesn't send any referrer when going into another web site domain. + // Default browser are 'strict-origin-when-cross-origin' (only domain is sent on other domain switching), we want more so we use 'strict-origin' so browser doesn't send any referrer when going into another web site domain. if (!defined('MAIN_SECURITY_FORCERP')) { - $referrerpolicy = getDolGlobalString('MAIN_SECURITY_FORCERP', "same-origin"); + $referrerpolicy = getDolGlobalString('MAIN_SECURITY_FORCERP', "strict-origin"); header("Referrer-Policy: ".$referrerpolicy); } From 1a9fa740a5fbe8301a83851c76cdc7bd166be540 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 6 Mar 2024 13:32:15 +0100 Subject: [PATCH 8/9] Fix quote --- htdocs/admin/system/security.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index fce38310605..8aee55d46ba 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -753,7 +753,7 @@ print 'WEBSITE_MAIN_SECURITY_FORCECSP = '.getDolGlobalString('W print '   ('.$langs->trans("Example").": \"frame-ancestors 'self'; default-src 'self' 'unsafe-inline'; style-src https://cdnjs.cloudflare.com *.googleapis.com; script-src *.transifex.com *.google-analytics.com *.googletagmanager.com; object-src https://youtube.com; frame-src https://youtube.com; img-src * data:;\")
"; print '
'; -print 'WEBSITE_MAIN_SECURITY_FORCERP = '.getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCERP', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").'=\"strict-origin\" '.$langs->trans("or")." \"strict-origin-when-cross-origin\")
"; +print 'WEBSITE_MAIN_SECURITY_FORCERP = '.getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCERP', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined")."=\"strict-origin\" ".$langs->trans("or")." \"strict-origin-when-cross-origin\")
"; print '
'; print 'WEBSITE_MAIN_SECURITY_FORCESTS = '.getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCESTS', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Example").": \"max-age=31536000; includeSubDomains\")
"; From f1aa29507a62786c8de29fb0afc5c38e477f04bc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 6 Mar 2024 15:01:25 +0100 Subject: [PATCH 9/9] Fix sec more complete list of forbidden function --- htdocs/core/lib/functions.lib.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 6fe032f5456..0298ce0d439 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -9738,6 +9738,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "require", "include", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask")); $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("get_defined_functions", "get_defined_vars", "get_defined_constants", "get_declared_classes")); $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("function", "call_user_func")); + $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include", "require_once", "include_once")); $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("eval", "create_function", "assert", "mb_ereg_replace")); // function with eval capabilities $forbiddenphpmethods = array('invoke', 'invokeArgs'); // Method of ReflectionFunction to execute a function