From ea1611a425f20948daaf42583fc279217979ca63 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 26 Mar 2026 08:28:47 +0100 Subject: [PATCH 01/16] FIX: do not print Extrafields in PDF if printable is 0 --- htdocs/core/class/commondocgenerator.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index a333a0b5fc2..0c51aae6945 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1458,8 +1458,8 @@ abstract class CommonDocGenerator } $disableOnEmpty = 0; - if ($enabled && !empty($extrafields->attributes[$object->table_element]['printable'][$key])) { - $printable = intval($extrafields->attributes[$object->table_element]['printable'][$key]); + $printable = intval($extrafields->attributes[$object->table_element]['printable'][$key]); + if ($enabled && !empty($printable)) { if (in_array($printable, $params['printableEnable']) || in_array($printable, $params['printableEnableNotEmpty'])) { $enabled = 1; } @@ -1469,7 +1469,7 @@ abstract class CommonDocGenerator } } - if (empty($enabled)) { + if (empty($enabled) || empty($printable)) { continue; } From cec448fcea25b29251b8fef0aa76ec24abb7929f Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 26 Mar 2026 10:57:44 +0100 Subject: [PATCH 02/16] FIX: do not print Extrafields in PDF if printable is 0 --- htdocs/core/lib/geturl.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/geturl.lib.php b/htdocs/core/lib/geturl.lib.php index 001ffaf555d..b32d9e840bf 100644 --- a/htdocs/core/lib/geturl.lib.php +++ b/htdocs/core/lib/geturl.lib.php @@ -30,7 +30,7 @@ * * @param string $url URL to call. * @param string $postorget 'POST', 'GET', 'HEAD', 'PUT', 'PUTALREADYFORMATED', 'POSTALREADYFORMATED', 'DELETE' - * @param string|array $param Parameters of URL (x=value1&y=value2) or may be a formated content with $postorget='PUTALREADYFORMATED' + * @param string|array $param Parameters of URL (x=value1&y=value2) or may be a formatted content with $postorget='PUTALREADYFORMATED' * @param integer $followlocation 0=Do not follow, 1=Follow location. * @param string[] $addheaders Array of string to add into header. Example: ('Accept: application/xrds+xml', ....) * @param string[] $allowedschemes List of schemes that are allowed ('http' + 'https' only by default) From cdb7d97a7be394f7b3175e662d0ff14af513c295 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 27 Mar 2026 08:35:59 +0100 Subject: [PATCH 03/16] fix CI --- ChangeLog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 58eafa4a37c..6db7b2e81f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -39,7 +39,7 @@ FIX: 18.0: GETPOSTDATE and buildParamDate assumed HTTP param names 'minute' and FIX: not remove value of others extra-fields on update extras action NEW: Automatically release docker image for each GitHub release FIX: getDolGlobalInt -SEC: fix IDOR attack on employee evaluation. Missing permision test https://github.com/atm-florianm/dolibarr/commit/7ed0af2a138a34e7c7005b95c85ffc791976a6cf +SEC: fix IDOR attack on employee evaluation. Missing permission test https://github.com/atm-florianm/dolibarr/commit/7ed0af2a138a34e7c7005b95c85ffc791976a6cf FIX: Implementation of multi-company compatibility with inventory/warehouse management FIX: 17.0: perweek.php resets task progress to 0% when: (#36401) FIX: DA027383: permissions not checked on HRM evaluation card (#36328) (#36399) @@ -61,7 +61,7 @@ FIX: wrong check of hook return FIX: 16.0: extrafield of type link to category causes SQL error in selectForFormsList() (#36074) FIX: 16.0 (up to 19.0): extrafield of type link to category causes SQL error in selectForFormsList FIX: missing "printFieldListValue" hook (#35990) -FIX: add action paramter +FIX: add action parameter FIX: remove duplicate object FIX: expense report card: use correct bank module designator for detection FIX: wrong check of hook return From f50508b84a0a61262916531bb01d232ae35dae0e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Mar 2026 10:23:07 +0100 Subject: [PATCH 04/16] FIX a param must not come from end user entry. --- htdocs/core/ajax/saveinplace.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/ajax/saveinplace.php b/htdocs/core/ajax/saveinplace.php index 2f88cebf58b..8f964b55148 100644 --- a/htdocs/core/ajax/saveinplace.php +++ b/htdocs/core/ajax/saveinplace.php @@ -120,6 +120,7 @@ if (!empty($field) && !empty($element) && !empty($table_element) && !empty($fk_e $feature = 'fournisseur'; $feature2 = 'facture'; } + //var_dump(GETPOST('action','aZ09')); //var_dump($newelement.'-'.$subelement."-".$feature."-".$object_id); $check_access = restrictedArea($user, $feature, $object_id, '', $feature2); @@ -205,7 +206,7 @@ if (!empty($field) && !empty($element) && !empty($table_element) && !empty($fk_e $object->fk_element = $fk_element; $object->element = $element; - $ret = $object->$savemethodname($field, $newvalue, $table_element, $fk_element, $format); + $ret = $object->setValueFrom($field, $newvalue, $object->table_element, $fk_element, $format); if ($ret > 0) { if ($type == 'numeric') { $value = price($newvalue); From 69cee514b55bfe1d2652548a46627602061e4fb0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Mar 2026 10:30:26 +0100 Subject: [PATCH 05/16] Doc --- htdocs/core/ajax/saveinplace.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/htdocs/core/ajax/saveinplace.php b/htdocs/core/ajax/saveinplace.php index 8f964b55148..0f72d430675 100644 --- a/htdocs/core/ajax/saveinplace.php +++ b/htdocs/core/ajax/saveinplace.php @@ -71,7 +71,6 @@ if (!empty($field) && !empty($element) && !empty($table_element) && !empty($fk_e $value = ($type == 'ckeditor' ? GETPOST('value', '', 2) : GETPOST('value', 'alpha', 2)); $loadmethod = GETPOST('loadmethod', 'alpha', 2); $savemethod = GETPOST('savemethod', 'alpha', 2); - $savemethodname = (!empty($savemethod) ? $savemethod : 'setValueFrom'); $newelement = $element; $view = ''; @@ -120,7 +119,6 @@ if (!empty($field) && !empty($element) && !empty($table_element) && !empty($fk_e $feature = 'fournisseur'; $feature2 = 'facture'; } - //var_dump(GETPOST('action','aZ09')); //var_dump($newelement.'-'.$subelement."-".$feature."-".$object_id); $check_access = restrictedArea($user, $feature, $object_id, '', $feature2); @@ -194,11 +192,7 @@ if (!empty($field) && !empty($element) && !empty($table_element) && !empty($fk_e } } - if (!$error) { - if ((isset($object) && !is_object($object)) || empty($savemethod)) { - $object = new GenericObject($db); - } - + if (!$error && isset($object) && is_object($object)) { // Specific for add_object_linked() // TODO add a function for variable treatment $object->ext_fk_element = $newvalue; From 48ec90f5c4e33b2b2d7ac1d64923b5a26f7a38f6 Mon Sep 17 00:00:00 2001 From: atm-corentin <165782689+atm-corentin@users.noreply.github.com> Date: Fri, 3 Apr 2026 03:32:58 +0200 Subject: [PATCH 06/16] fix(ticket): clear stale attachments when opening a new ticket form (#37684) --- htdocs/core/modules/modTicket.class.php | 2 +- htdocs/ticket/card.php | 4 ++++ htdocs/ticket/list.php | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/modTicket.class.php b/htdocs/core/modules/modTicket.class.php index 18f0d368cfd..db4fb8bf83c 100644 --- a/htdocs/core/modules/modTicket.class.php +++ b/htdocs/core/modules/modTicket.class.php @@ -256,7 +256,7 @@ class modTicket extends DolibarrModules 'type' => 'left', 'titre' => 'NewTicket', 'mainmenu' => 'ticket', - 'url' => '/ticket/card.php?action=create', + 'url' => '/ticket/card.php?action=create&mode=init', 'langs' => 'ticket', 'position' => 102, 'enabled' => '$conf->ticket->enabled', diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index 16134ca2d7a..85e3001a30e 100644 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -713,6 +713,10 @@ if ($action == 'create' || $action == 'presend') { print load_fiche_titre($langs->trans('NewTicket'), '', 'ticket'); + if (GETPOST("mode", "aZ09") == 'init' && empty($_POST)) { + $formticket->clear_attached_files(); + } + $formticket->trackid = ''; // TODO Use a unique key to avoid conflict in upload file feature $formticket->withfromsocid = $socid ? $socid : $user->socid; $formticket->withfromcontactid = $contactid ? $contactid : ''; diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 25bd0e61854..24a9ff7371e 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -730,7 +730,7 @@ if ($projectid) { print ''; } -$url = DOL_URL_ROOT.'/ticket/card.php?action=create'.($socid ? '&socid='.$socid : '').($projectid ? '&origin=projet_project&originid='.$projectid : ''); +$url = DOL_URL_ROOT.'/ticket/card.php?action=create&mode=init'.($socid ? '&socid='.$socid : '').($projectid ? '&origin=projet_project&originid='.$projectid : ''); if (!empty($socid)) { $url .= '&socid='.$socid; } From 60417a3b4e342c6030ccf3818062ab5f8f567008 Mon Sep 17 00:00:00 2001 From: ThomasNgr-OpenDSI Date: Tue, 7 Apr 2026 13:41:22 +0200 Subject: [PATCH 07/16] FIX extrafield selectlist when there is a linked table (#37706) --- htdocs/core/class/commonobject.class.php | 18 ++++++++++---- htdocs/core/class/extrafields.class.php | 24 ++++++++++++------- .../class/html.formwebportal.class.php | 6 ++++- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 16717b064ef..83e40cece85 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7681,7 +7681,11 @@ abstract class CommonObject } if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) { list($parentName, $parentField) = explode('|', $InfoFieldList[3]); - $keyList .= ', '.$parentField; + if (!empty($InfoFieldList[4]) && strpos($InfoFieldList[4], 'extra.') !== false) { + $keyList .= ', main.'.$parentField; + } else { + $keyList .= ', '.$parentField; + } } $filter_categorie = false; @@ -7906,10 +7910,6 @@ abstract class CommonObject $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2].' as rowid'); - if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) { - list($parentName, $parentField) = explode('|', $InfoFieldList[3]); - $keyList .= ', '.$parentField; - } if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) { if (strpos($InfoFieldList[4], 'extra.') !== false) { $keyList = 'main.'.$InfoFieldList[2].' as rowid'; @@ -7917,6 +7917,14 @@ abstract class CommonObject $keyList = $InfoFieldList[2].' as rowid'; } } + if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) { + list($parentName, $parentField) = explode('|', $InfoFieldList[3]); + if (!empty($InfoFieldList[4]) && strpos($InfoFieldList[4], 'extra.') !== false) { + $keyList .= ', main.'.$parentField; + } else { + $keyList .= ', '.$parentField; + } + } $filter_categorie = false; if (count($InfoFieldList) > 5) { diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 54e02a07454..5eff99c86c8 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1390,10 +1390,6 @@ class ExtraFields $parentField = ''; $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2].' as rowid'); - if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) { - list($parentName, $parentField) = explode('|', $InfoFieldList[3]); - $keyList .= ', '.$parentField; - } if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) { if (strpos($InfoFieldList[4], 'extra.') !== false) { $keyList = 'main.'.$InfoFieldList[2].' as rowid'; @@ -1401,6 +1397,14 @@ class ExtraFields $keyList = $InfoFieldList[2].' as rowid'; } } + if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) { + list($parentName, $parentField) = explode('|', $InfoFieldList[3]); + if (!empty($InfoFieldList[4]) && strpos($InfoFieldList[4], 'extra.') !== false) { + $keyList .= ', main.'.$parentField; + } else { + $keyList .= ', '.$parentField; + } + } $filter_categorie = false; if (count($InfoFieldList) > 5) { @@ -1615,10 +1619,6 @@ class ExtraFields $parentField = ''; $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2].' as rowid'); - if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) { - list($parentName, $parentField) = explode('|', $InfoFieldList[3]); - $keyList .= ', '.$parentField; - } if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) { if (strpos($InfoFieldList[4], 'extra.') !== false) { $keyList = 'main.'.$InfoFieldList[2].' as rowid'; @@ -1626,6 +1626,14 @@ class ExtraFields $keyList = $InfoFieldList[2].' as rowid'; } } + if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) { + list($parentName, $parentField) = explode('|', $InfoFieldList[3]); + if (!empty($InfoFieldList[4]) && strpos($InfoFieldList[4], 'extra.') !== false) { + $keyList .= ', main.'.$parentField; + } else { + $keyList .= ', '.$parentField; + } + } $filter_categorie = false; if (count($InfoFieldList) > 5) { diff --git a/htdocs/webportal/class/html.formwebportal.class.php b/htdocs/webportal/class/html.formwebportal.class.php index 6a5197d7bd5..2dd2a9a8651 100644 --- a/htdocs/webportal/class/html.formwebportal.class.php +++ b/htdocs/webportal/class/html.formwebportal.class.php @@ -804,7 +804,11 @@ class FormWebPortal extends Form } if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) { list($parentName, $parentField) = explode('|', $InfoFieldList[3]); - $keyList .= ', ' . $parentField; + if (!empty($InfoFieldList[4]) && strpos($InfoFieldList[4], 'extra.') !== false) { + $keyList .= ', main.'.$parentField; + } else { + $keyList .= ', '.$parentField; + } } $filter_categorie = false; From 79d1bf55d7f770bcbf4c343e49b4b3c3975d8628 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 7 Apr 2026 14:00:48 +0200 Subject: [PATCH 08/16] Test --- .github/workflows/pr-18-testldr.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-18-testldr.yaml b/.github/workflows/pr-18-testldr.yaml index 32abe8e7e8e..84a84e170b5 100644 --- a/.github/workflows/pr-18-testldr.yaml +++ b/.github/workflows/pr-18-testldr.yaml @@ -72,7 +72,7 @@ jobs: fi done echo "AUTHOR=$AUTHOR" - echo "reviewers=$(IFS=, ; echo "${FINAL_REVIEWERS[*]}")" >> $GITHUB_OUTPUT + echo reviewers=$(IFS=, ; echo "${FINAL_REVIEWERS[*]}") >> $GITHUB_OUTPUT - name: Assign reviewers if: steps.set-reviewers.outputs.reviewers != '' && ${{env.prid}} != '' From 3a104891876ea8dd31134dc31d59499f0a9a3e2d Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Wed, 8 Apr 2026 20:09:12 +0200 Subject: [PATCH 09/16] FIX: do not print Extrafields in PDF if printable is 0 (#37789) * FIX: do not print Extrafields in PDF if printable is 0 * review github CI --- htdocs/core/class/commondocgenerator.class.php | 6 +++--- htdocs/core/lib/geturl.lib.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 2b3adff4ecd..141fa6733f5 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1458,8 +1458,8 @@ abstract class CommonDocGenerator } $disableOnEmpty = 0; - if ($enabled && !empty($extrafields->attributes[$object->table_element]['printable'][$key])) { - $printable = intval($extrafields->attributes[$object->table_element]['printable'][$key]); + $printable = (int) $extrafields->attributes[$object->table_element]['printable'][$key]; + if ($enabled && !empty($printable)) { if (in_array($printable, $params['printableEnable']) || in_array($printable, $params['printableEnableNotEmpty'])) { $enabled = 1; } @@ -1469,7 +1469,7 @@ abstract class CommonDocGenerator } } - if (empty($enabled)) { + if (empty($enabled) || empty($printable)) { continue; } diff --git a/htdocs/core/lib/geturl.lib.php b/htdocs/core/lib/geturl.lib.php index fd888e2c653..88e47374b61 100644 --- a/htdocs/core/lib/geturl.lib.php +++ b/htdocs/core/lib/geturl.lib.php @@ -30,7 +30,7 @@ * * @param string $url URL to call. * @param string $postorget 'POST', 'GET', 'HEAD', 'PUT', 'PUTALREADYFORMATED', 'POSTALREADYFORMATED', 'DELETE' - * @param string|array $param Parameters of URL (x=value1&y=value2) or may be a formated content with $postorget='PUTALREADYFORMATED' + * @param string|array $param Parameters of URL (x=value1&y=value2) or may be a formatted content with $postorget='PUTALREADYFORMATED' * @param integer $followlocation 0=Do not follow, 1=Follow location. * @param string[] $addheaders Array of string to add into header. Example: ('Accept: application/xrds+xml', ....) * @param string[] $allowedschemes List of schemes that are allowed ('http' + 'https' only by default) From 894f2c175f6c0749ffa91eecf12e29cf183fd606 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 9 Apr 2026 07:44:36 +0200 Subject: [PATCH 10/16] review btter fix for not print extrafields --- htdocs/core/class/commondocgenerator.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 0c51aae6945..f9e1fa816f2 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1458,7 +1458,10 @@ abstract class CommonDocGenerator } $disableOnEmpty = 0; - $printable = intval($extrafields->attributes[$object->table_element]['printable'][$key]); + $printable = 0; + if (isset($extrafields->attributes[$object->table_element]['printable'][$key])) { + $printable = (int) $extrafields->attributes[$object->table_element]['printable'][$key]; + } if ($enabled && !empty($printable)) { if (in_array($printable, $params['printableEnable']) || in_array($printable, $params['printableEnableNotEmpty'])) { $enabled = 1; From fa4c7b36797ec1d605f03908877db08614017056 Mon Sep 17 00:00:00 2001 From: Eric Seigne Date: Thu, 9 Apr 2026 09:40:38 +0200 Subject: [PATCH 11/16] apply develop pre-commit rules --- ChangeLog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 58eafa4a37c..6db7b2e81f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -39,7 +39,7 @@ FIX: 18.0: GETPOSTDATE and buildParamDate assumed HTTP param names 'minute' and FIX: not remove value of others extra-fields on update extras action NEW: Automatically release docker image for each GitHub release FIX: getDolGlobalInt -SEC: fix IDOR attack on employee evaluation. Missing permision test https://github.com/atm-florianm/dolibarr/commit/7ed0af2a138a34e7c7005b95c85ffc791976a6cf +SEC: fix IDOR attack on employee evaluation. Missing permission test https://github.com/atm-florianm/dolibarr/commit/7ed0af2a138a34e7c7005b95c85ffc791976a6cf FIX: Implementation of multi-company compatibility with inventory/warehouse management FIX: 17.0: perweek.php resets task progress to 0% when: (#36401) FIX: DA027383: permissions not checked on HRM evaluation card (#36328) (#36399) @@ -61,7 +61,7 @@ FIX: wrong check of hook return FIX: 16.0: extrafield of type link to category causes SQL error in selectForFormsList() (#36074) FIX: 16.0 (up to 19.0): extrafield of type link to category causes SQL error in selectForFormsList FIX: missing "printFieldListValue" hook (#35990) -FIX: add action paramter +FIX: add action parameter FIX: remove duplicate object FIX: expense report card: use correct bank module designator for detection FIX: wrong check of hook return From 8d1c7952c3e06a6e4b5ae011043d9e8bfc47c01a Mon Sep 17 00:00:00 2001 From: Eric Seigne Date: Thu, 9 Apr 2026 10:02:18 +0200 Subject: [PATCH 12/16] codespell to fix words --- htdocs/core/lib/geturl.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/geturl.lib.php b/htdocs/core/lib/geturl.lib.php index 001ffaf555d..b32d9e840bf 100644 --- a/htdocs/core/lib/geturl.lib.php +++ b/htdocs/core/lib/geturl.lib.php @@ -30,7 +30,7 @@ * * @param string $url URL to call. * @param string $postorget 'POST', 'GET', 'HEAD', 'PUT', 'PUTALREADYFORMATED', 'POSTALREADYFORMATED', 'DELETE' - * @param string|array $param Parameters of URL (x=value1&y=value2) or may be a formated content with $postorget='PUTALREADYFORMATED' + * @param string|array $param Parameters of URL (x=value1&y=value2) or may be a formatted content with $postorget='PUTALREADYFORMATED' * @param integer $followlocation 0=Do not follow, 1=Follow location. * @param string[] $addheaders Array of string to add into header. Example: ('Accept: application/xrds+xml', ....) * @param string[] $allowedschemes List of schemes that are allowed ('http' + 'https' only by default) From ad9328ec86ca6839f6fe4177c8e01e4c102e6160 Mon Sep 17 00:00:00 2001 From: ThomasNgr-OpenDSI Date: Thu, 9 Apr 2026 20:33:34 +0200 Subject: [PATCH 13/16] FIX #GHSA-crgg-h74r-2m8r (#37636) Co-authored-by: Laurent Destailleur --- htdocs/api/class/api_documents.class.php | 51 ++++++++++++++++++++++++ htdocs/document.php | 2 +- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index c37e8db9f6b..2a5967fcc92 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -104,6 +104,23 @@ class Documents extends DolibarrApi throw new RestException(401); } + if (DolibarrApiAccess::$user->socid > 0) { + if ($sqlprotectagainstexternals) { + $resql = $this->db->query($sqlprotectagainstexternals); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) { + $obj = $this->db->fetch_object($resql); + if (DolibarrApiAccess::$user->socid != $obj->fk_soc) { + throw new RestException(403, 'Not allowed to download documents with such a ref'); + } + $i++; + } + } + } + } + $filename = basename($original_file); $original_file_osencoded = dol_osencode($original_file); // New file name encoded in OS encoding charset @@ -181,6 +198,23 @@ class Documents extends DolibarrApi throw new RestException(401); } + if (DolibarrApiAccess::$user->socid > 0) { + if ($sqlprotectagainstexternals) { + $resql = $this->db->query($sqlprotectagainstexternals); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) { + $obj = $this->db->fetch_object($resql); + if (DolibarrApiAccess::$user->socid != $obj->fk_soc) { + throw new RestException(403, 'Not allowed to download documents with such a ref'); + } + $i++; + } + } + } + } + // --- Generates the document $hidedetails = empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 0 : 1; $hidedesc = empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 0 : 1; @@ -947,6 +981,23 @@ class Documents extends DolibarrApi throw new RestException(401); } + if (DolibarrApiAccess::$user->socid > 0) { + if ($sqlprotectagainstexternals) { + $resql = $this->db->query($sqlprotectagainstexternals); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) { + $obj = $this->db->fetch_object($resql); + if (DolibarrApiAccess::$user->socid != $obj->fk_soc) { + throw new RestException(403, 'Not allowed to download documents with such a ref'); + } + $i++; + } + } + } + } + $filename = basename($original_file); $original_file_osencoded = dol_osencode($original_file); // New file name encoded in OS encoding charset diff --git a/htdocs/document.php b/htdocs/document.php index 394e470257a..6d0203d8c61 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -215,7 +215,7 @@ if (empty($modulepart)) { } // Check security and set return info with full path of file -$check_access = dol_check_secure_access_document($modulepart, $original_file, $entity, $user, ''); +$check_access = dol_check_secure_access_document($modulepart, $original_file, (int) $entity, $user, '', 'read'); $accessallowed = $check_access['accessallowed']; $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals']; $fullpath_original_file = $check_access['original_file']; // $fullpath_original_file is now a full path name From 06614955351ac50a05f95d45475ea472891d3489 Mon Sep 17 00:00:00 2001 From: ThomasNgr-OpenDSI Date: Thu, 9 Apr 2026 20:33:56 +0200 Subject: [PATCH 14/16] 18 report ghsa 39vm 9q4p 6jjg (#37627) * report ghsa-39vm-9q4p-6jjg (commit 1072e090) * Adapt to 18.0 --------- Co-authored-by: Laurent Destailleur --- htdocs/main.inc.php | 49 +++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 264bd10a07c..fc4de88872c 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -278,6 +278,13 @@ if (!empty($_SERVER['DOCUMENT_ROOT']) && substr($_SERVER['DOCUMENT_ROOT'], -6) ! // Include the conf.php and functions.lib.php and security.lib.php. This defined the constants like DOL_DOCUMENT_ROOT, DOL_DATA_ROOT, DOL_URL_ROOT... require_once 'filefunc.inc.php'; +/** + * @var ?string $php_session_save_handler + * @var ?string $dolibarr_main_force_https + * @var ?string $dolibarr_main_restrict_ip + * @var ?string $dolibarr_nocsrfcheck + * @var ?string $dolibarr_main_demo + */ // If there is a POST parameter to tell to save automatically some POST parameters into cookies, we do it. // This is used for example by form of boxes to save personalization of some options. @@ -619,26 +626,30 @@ if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && getDolGlobalInt( // Note: There is another CSRF protection into the filefunc.inc.php } -// Disable modules (this must be after session_start and after conf has been loaded) -if (GETPOSTISSET('disablemodules')) { - $_SESSION["disablemodules"] = GETPOST('disablemodules', 'alpha'); -} -if (!empty($_SESSION["disablemodules"])) { - $modulepartkeys = array('css', 'js', 'tabs', 'triggers', 'login', 'substitutions', 'menus', 'theme', 'sms', 'tpl', 'barcode', 'models', 'societe', 'hooks', 'dir', 'syslog', 'tpllinkable', 'contactelement', 'moduleforexternal'); +if (!empty($dolibarr_main_demo)) { + // Disable modules (this must be after session_start and after conf has been loaded) + if (GETPOSTISSET('disablemodules')) { + $_SESSION["disablemodules"] = GETPOST('disablemodules', 'alpha'); + } + if (!empty($_SESSION["disablemodules"])) { + $modulepartkeys = array('css', 'js', 'tabs', 'triggers', 'login', 'substitutions', 'menus', 'theme', 'sms', 'tpl', 'barcode', 'models', 'societe', 'hooks', 'dir', 'syslog', 'tpllinkable', 'contactelement', 'moduleforexternal', 'websitetemplates'); - $disabled_modules = explode(',', $_SESSION["disablemodules"]); - foreach ($disabled_modules as $module) { - if ($module) { - if (empty($conf->$module)) { - $conf->$module = new stdClass(); // To avoid warnings - } - $conf->$module->enabled = false; - foreach ($modulepartkeys as $modulepartkey) { - unset($conf->modules_parts[$modulepartkey][$module]); - } - if ($module == 'fournisseur') { // Special case - $conf->supplier_order->enabled = 0; - $conf->supplier_invoice->enabled = 0; + $disabled_modules = explode(',', $_SESSION["disablemodules"]); + foreach ($disabled_modules as $module) { + if ($module) { + if (empty($conf->$module)) { + $conf->$module = new stdClass(); // To avoid warnings + } + + $conf->$module->enabled = false; // Old usage + + foreach ($modulepartkeys as $modulepartkey) { + unset($conf->modules_parts[$modulepartkey][$module]); + } + if ($module == 'fournisseur') { // Special case + $conf->supplier_order->enabled = 0; + $conf->supplier_invoice->enabled = 0; + } } } } From ba612dc1a8e60bcc67702f33b97f33c176771b28 Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Fri, 10 Apr 2026 12:41:11 +0200 Subject: [PATCH 15/16] 19 fix print pdf extrafields not visiblev2 (#37796) * FIX: do not print Extrafields in PDF if printable is 0 * review github CI * review btter fix for not print extrafields * review btter fix for not print extrafields --- htdocs/core/class/commondocgenerator.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 141fa6733f5..b5df8273381 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1458,7 +1458,10 @@ abstract class CommonDocGenerator } $disableOnEmpty = 0; - $printable = (int) $extrafields->attributes[$object->table_element]['printable'][$key]; + $printable = 0; + if (isset($extrafields->attributes[$object->table_element]['printable'][$key])) { + $printable = (int) $extrafields->attributes[$object->table_element]['printable'][$key]; + } if ($enabled && !empty($printable)) { if (in_array($printable, $params['printableEnable']) || in_array($printable, $params['printableEnableNotEmpty'])) { $enabled = 1; From 916e318deeb97d99c636cd658e4858e298a60a1d Mon Sep 17 00:00:00 2001 From: atm-jonathan <146709163+atm-jonathan@users.noreply.github.com> Date: Fri, 10 Apr 2026 12:42:20 +0200 Subject: [PATCH 16/16] Fix/doctemplates path entity centralized (#37788) * Fix for multi-entity on doctemplates * clean * construction of the fullpath_original_file --- htdocs/core/lib/files.lib.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 8d82ea46f9f..c0cb5f7340f 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -2942,9 +2942,15 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, $accessallowed = ($user->admin && basename($original_file) == $original_file && preg_match('/^dolibarr.*\.(log|json)$/', basename($original_file))); $original_file = $dolibarr_main_data_root.'/'.$original_file; } elseif ($modulepart == 'doctemplates' && !empty($dolibarr_main_data_root)) { - // Wrapping for doctemplates $accessallowed = $user->admin; - $original_file = $dolibarr_main_data_root.'/doctemplates/'.$original_file; + $relative_file = $original_file; + $ent = ($entity > 0 ? $entity : $conf->entity); + $path_with_entity = $dolibarr_main_data_root . '/' . $ent . '/doctemplates/' . $relative_file; + if ($ent > 1 && file_exists(dol_osencode($path_with_entity))) { + $original_file = $path_with_entity; + } else { + $original_file = $dolibarr_main_data_root . '/doctemplates/' . $relative_file; + } } elseif ($modulepart == 'doctemplateswebsite' && !empty($dolibarr_main_data_root)) { // Wrapping for doctemplates of websites $accessallowed = ($fuser->hasRight('website', 'write') && preg_match('/\.jpg$/i', basename($original_file)));