Merge branch '23.0' of git@github.com:Dolibarr/dolibarr.git into develop

This commit is contained in:
Laurent Destailleur 2026-05-22 11:30:41 +02:00
commit be296e12c9
8 changed files with 28 additions and 18 deletions

View file

@ -31,16 +31,16 @@ The following changes may create regressions for some external modules, but were
***** ChangeLog for 23.0.3 compared to 23.0.2 *****
FIX: #36589 (#38037)
FIX: #37552 (#38073)
FIX: #37649 (#38101)
FIX: #37759
FIX: #37760
FIX: #37761
FIX: #37762
FIX: #37805
FIX: #38074 (#38075)
FIX: #38131 (#38140)
FIX: #36589 (#38037) There is no save button in the "Variant attributes extrafields" and "Variant attributes values extrafields" tabs of the product variant module
FIX: #37552 (#38073) Webportal Proposals, Sales orders and Invoices links not working
FIX: #37649 (#38101) Gross price not calculated in supplier orders
FIX: #37759 Security: Sales Orders API Cross Customer Creation Privilege Escalation
FIX: #37760 Security: Commercial Proposals API Cross Customer Creation Privilege Escalation
FIX: #37761 Security: Tickets API Cross Customer Ticket Targeted Read Privilege Escalation
FIX: #37762 Security: Tickets API Cross Customer Ticket Targeted Update Privilege Escalation
FIX: #37805 Api endpoint /proposals/ref/{ref} fail with message : "Bad Request" - No proposal with id=0 can exist when using propal API and searching by ref
FIX: #38074 (#38075) Asset Depreciation List - SQL error message
FIX: #38131 (#38140) Bug in Recurring Customer Invoice
FIX: Accountancy - Select journal - Problem with the label (#37979)
FIX: AccountingAccount cache — silent reference mutation in accounting journals (#37981)
FIX: a param must not come from end user entry.
@ -66,7 +66,7 @@ FIX: IDOR on messaging.php - Credit Aksoum Abderrahmane
FIX: Some remaining cross-customer object creation on API (proposal, orders) - Credit Mitch311
FIX: add permission test on legacy filemanager - Credit Aksoum Abderrahmane
FIX: Can use AI module to make SSRF call. Credit Dilip
FIX: #GHSA-crgg-h74r-2m8r (#37636)
FIX: #GHSA-crgg-h74r-2m8r (#37636) - FIX: Access to documents via the API for external users
FIX: #GHSA-hq5j-39f9-qxcv (#37812)
FIX: SQL Injection via Operator Injection in Contract Service List
SEC: Better sanitization param for GETPOST of htmlheader of website page - See commit bbbbb56c6455514dcd0acca53afc17a92ed21bb9

View file

@ -109,7 +109,10 @@ if ($objectdesc) {
$InfoFieldList[3] = preg_replace('/:\w*$/', '', $vartmp); // take the filter field
$classname = $InfoFieldList[0];
$classpath = dol_sanitizePathName($InfoFieldList[1]);
$classpath = '';
if (!empty($InfoFieldList[1])) {
$classpath = dol_sanitizePathName($InfoFieldList[1]);
}
//$addcreatebuttonornot = empty($InfoFieldList[2]) ? 0 : $InfoFieldList[2];
$filter = empty($InfoFieldList[3]) ? '' : $InfoFieldList[3];

View file

@ -2579,7 +2579,7 @@ class ExtraFields
while ($obj = $this->db->fetch_object($resql)) {
$c = new Categorie($this->db);
$c->fetch($obj->rowid);
if ($mode != 'list') {
if ((string) $mode != 'list') {
$ways = $c->print_all_ways(); // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formatted text
foreach ($ways as $way) {
$toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories'.($mode ? ' '.$mode : '').'"'.($c->color ? ' style="background: #'.$c->color.';"' : ' style="background: #bbb"').'>'.img_object('', 'category').' '.$way.'</li>';

View file

@ -3656,7 +3656,7 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi
if (in_array($object->element, array('product', 'bank_account', 'project_task'))) {
/** @var Product|Account|Task $object */
if (!empty($object->label)) {
$morehtmlref .= '<div class="refidno opacitymedium">' . $object->label . '</div>';
$morehtmlref .= '<div class="refidno banner-object-label">' . $object->label . '</div>';
}
}
// Show address and email
@ -3691,7 +3691,7 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi
// $morehtmlstatus is part under the status
// $morehtmlright is part of htmlright
print '<div class="' . ($onlybanner ? 'arearefnobottom ' : 'arearef ') . 'heightref valignmiddle centpercent">';
print '<div class="' . ($onlybanner ? 'arearefnobottom ' : 'arearef ') . 'heightref valignmiddle centpercent object-banner-tab-container" data-module-part="'.dolPrintHTMLForAttribute($modulepart).'">';
print $form->showrefnav($object, $paramid, $morehtml, $shownav, $fieldid, $fieldref, $morehtmlref, $moreparam, $nodbprefix, $morehtmlleft, $morehtmlstatus, $morehtmlright);
print '</div>';
print '<div class="underrefbanner clearboth"></div>';

View file

@ -633,11 +633,12 @@ class FormProduct
$return .= '"';
if ($mode == 1 && $lines->short_label == $selected) {
$return .= ' selected';
} elseif ($mode == 2 && $lines->scale == $selected) {
} elseif ($mode == 2 && (int) $lines->scale === (int) $selected) { // Careful null !== 0 !== '0' and when 0 is saved bdd store null
$return .= ' selected';
} elseif ($mode == 0 && $lines->id == $selected) {
$return .= ' selected';
}
$return .= '>';
if ($measuring_style == 'time') {
$return .= $langs->trans(ucfirst((string) $lines->label));

View file

@ -841,6 +841,9 @@ input.pageplusone {
.anchorundermenu {
scroll-margin-top: 80px;
}
.banner-object-label {
opacity: 0.8;
}
select:invalid, select.--error {
color: gray;

View file

@ -990,6 +990,9 @@ input.pageplusone {
.anchorundermenu {
scroll-margin-top: 80px;
}
.banner-object-label {
opacity: 0.8;
}
select:invalid, select.--error {
color: gray;

View file

@ -523,10 +523,10 @@ class ProductCombination
$child->price_autogen = $parent->price_autogen;
$child->weight = $parent->weight;
// Only when Parent Status are updated
if (is_object($parent->oldcopy) && !$parent->oldcopy->isEmpty() && ($parent->status != $parent->oldcopy->status)) {
if (is_object($parent->oldcopy) && !empty($parent->oldcopy->id) && ($parent->status != $parent->oldcopy->status)) {
$child->status = $parent->status;
}
if (is_object($parent->oldcopy) && !$parent->oldcopy->isEmpty() && ($parent->status_buy != $parent->oldcopy->status_buy)) {
if (is_object($parent->oldcopy) && !empty($parent->oldcopy->id) && ($parent->status_buy != $parent->oldcopy->status_buy)) {
$child->status_buy = $parent->status_buy;
}