From 71a2c20d4bb205a8e945160fbd78e9891345e15f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 9 Feb 2021 14:32:04 +0100 Subject: [PATCH 1/7] massaction validate invoice do not regenerate pdf --- htdocs/core/actions_massactions.inc.php | 35 +++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 77fbea3c36a..abcdd690d5c 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -3,7 +3,7 @@ * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2018 Juanjo Menent * Copyright (C) 2019 Ferran Marcet - * Copyright (C) 2019 Frédéric France + * Copyright (C) 2019-2021 Frédéric France * * 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 @@ -1167,7 +1167,38 @@ if (!$error && $massaction == 'validate' && $permissiontoadd) $error++; break; } - else $nbok++; + else { + // validate() rename pdf but do not regenerate + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); + } + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { + $newlang = $objecttmp->thirdparty->default_lang; + } + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + $outputlangs->load('products'); + } + $model = $objecttmp->model_pdf; + $ret = $objecttmp->fetch($objecttmp->id); // Reload to get new records + // To be sure vars is defined + $hidedetails = !empty($hidedetails) ? $hidedetails : 0; + $hidedesc = !empty($hidedesc) ? $hidedesc : 0; + $hideref = !empty($hideref) ? $hideref : 0; + $moreparams = !empty($moreparams) ? $moreparams : null; + + $result = $objecttmp->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result < 0) { + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + } + } + $nbok++; + } } else { From c010cab47e85f9823d87570087caadfc77cb72c6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Feb 2021 15:51:00 +0100 Subject: [PATCH 2/7] Fix translation of default value for contacts --- htdocs/contact/card.php | 2 +- htdocs/core/class/commonobject.class.php | 12 +++++++++--- htdocs/langs/en_US/supplier_proposal.lang | 3 +++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 7bd88436e31..3e3e1894a75 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -843,7 +843,7 @@ else print ''.$langs->trans("ContactByDefaultFor").''; print ''; $contactType = $object->listeTypeContacts('external', '', 1); - print $form->multiselectarray('roles', $contactType); + print $form->multiselectarray('roles', $contactType, array(), 0, 0, 'minwidth500'); print ''; } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index d2853d48034..730546e0e6b 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1356,6 +1356,8 @@ abstract class CommonObject if ($resql) { $num = $this->db->num_rows($resql); if ($num > 0) { + $langs->loadLangs(array("propal", "orders", "bills", "suppliers", "contracts", "supplier_proposal")); + while ($obj = $this->db->fetch_object($resql)) { $modulename = $obj->element; if (strpos($obj->element, 'project') !== false) { @@ -1371,11 +1373,15 @@ abstract class CommonObject } if ($conf->{$modulename}->enabled) { $libelle_element = $langs->trans('ContactDefault_'.$obj->element); - $transkey = "TypeContact_".$obj->element."_".$source."_".$obj->code; + $tmpelement = $obj->element; + $transkey = "TypeContact_".$tmpelement."_".$source."_".$obj->code; $libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->libelle); - if (empty($option)) + if (empty($option)) { $tab[$obj->rowid] = $libelle_element.' - '.$libelle_type; - else $tab[$obj->rowid] = $libelle_element.' - '.$libelle_type; + } + else { + $tab[$obj->rowid] = $libelle_element.' - '.$libelle_type; + } } } } diff --git a/htdocs/langs/en_US/supplier_proposal.lang b/htdocs/langs/en_US/supplier_proposal.lang index ce5bdf0425a..2617cdfe9e9 100644 --- a/htdocs/langs/en_US/supplier_proposal.lang +++ b/htdocs/langs/en_US/supplier_proposal.lang @@ -52,3 +52,6 @@ SupplierProposalsToClose=Vendor proposals to close SupplierProposalsToProcess=Vendor proposals to process LastSupplierProposals=Latest %s price requests AllPriceRequests=All requests +TypeContact_supplier_proposal_external_SHIPPING=Vendor contact for delivery +TypeContact_supplier_proposal_external_BILLING=Vendor contact for billing +TypeContact_supplier_proposal_external_SERVICE=Representative following-up proposal From 7fd2ac6618e7d7295f2f7d07b374bc5f6a208299 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Feb 2021 16:20:13 +0100 Subject: [PATCH 3/7] Fix link to show line in pending account --- htdocs/accountancy/bookkeeping/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 882c51f40c0..bef8ece1d39 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -110,7 +110,7 @@ $form = new Form($db); if (!in_array($action, array('export_file', 'delmouv', 'delmouvconfirm')) && !GETPOSTISSET('begin') && !GETPOSTISSET('formfilteraction') && GETPOST('page', 'int') == '' && !GETPOST('noreset', 'int') && $user->rights->accounting->mouvements->export) { - if (empty($search_date_start) && empty($search_date_end) && !GETPOSTISSET('restore_lastsearch_values')) + if (empty($search_date_start) && empty($search_date_end) && !GETPOSTISSET('restore_lastsearch_values') && !GETPOST('search_accountancy_code_start')) { $query = "SELECT date_start, date_end from ".MAIN_DB_PREFIX."accounting_fiscalyear "; $query .= " where date_start < '".$db->idate(dol_now())."' and date_end > '".$db->idate(dol_now())."' limit 1"; From 8c1902be1bc667b85898d48c817ea6300aac22e6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Feb 2021 18:40:15 +0100 Subject: [PATCH 4/7] Missing space --- 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 44097c84f49..c871304905f 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3596,7 +3596,7 @@ if ($action == 'create') if (is_array($objectsrc->linkedObjects['facture']) && count($objectsrc->linkedObjects['facture']) >= 1) { setEventMessages('WarningBillExist', null, 'warnings'); - echo ' ('.$langs->trans('LatestRelatedBill').end($objectsrc->linkedObjects['facture'])->getNomUrl(1).')'; + echo ' ('.$langs->trans('LatestRelatedBill').' '.end($objectsrc->linkedObjects['facture'])->getNomUrl(1).')'; } echo ''; print ''.$langs->trans('AmountHT').''.price($objectsrc->total_ht).''; From 34dcebea78186b91d2d57d50b0bf90f523a829fe Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 23 Feb 2021 11:03:34 +0100 Subject: [PATCH 5/7] Code comment --- htdocs/core/js/lib_head.js.php | 7 ++++--- htdocs/core/lib/ajax.lib.php | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/htdocs/core/js/lib_head.js.php b/htdocs/core/js/lib_head.js.php index 391a5359846..f03be3711f9 100644 --- a/htdocs/core/js/lib_head.js.php +++ b/htdocs/core/js/lib_head.js.php @@ -536,7 +536,7 @@ function setConstant(url, code, input, entity, strict, forcereload, userid, toke entity: entity, token: token }, - function() { + function() { /* handler for success of post */ console.log("url request success forcereload="+forcereload); $("#set_" + code).hide(); $("#del_" + code).show(); @@ -659,12 +659,13 @@ function delConstant(url, code, input, entity, strict, forcereload, userid, toke } /* - * Used by button to set on/off + * Call the setConstant or delConstant but with a confirmation before. + * Used by button to set on/off. * * @param string action Action * @param string url Url * @param string code Code - * @param string intput Input + * @param string intput Array of complementary actions to do if success * @param string box Box * @param int entity Entity * @param int yesButton yesButton diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 8a364359e9d..c9f64129e65 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -491,13 +491,13 @@ function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = * On/off button for constant * * @param string $code Name of constant - * @param array $input Array of options. ("disabled"|"enabled'|'set'|'del') => CSS element to switch, 'alert' => message to show, ... Example: array('disabled'=>array(0=>'cssid')) - * @param int $entity Entity to set. Use current entity if null. + * @param array $input Array of complementary actions to do if success ("disabled"|"enabled'|'set'|'del') => CSS element to switch, 'alert' => message to show, ... Example: array('disabled'=>array(0=>'cssid')) + * @param int $entity Entity. Current entity is used if null. * @param int $revertonoff Revert on/off * @param int $strict Use only "disabled" with delConstant and "enabled" with setConstant * @param int $forcereload Force to reload page if we click/change value (this is supported only when there is no 'alert' option in input) * @param string $marginleftonlyshort 1 = Add a short left margin on picto, 2 = Add a larger left margin on picto, 0 = No left margin. Works for fontawesome picto only. - * @param int $forcenoajax 1=Force to use a ahref link instead of ajax code. + * @param int $forcenoajax 1 = Force to use a ahref link instead of ajax code. * @return string */ function ajax_constantonoff($code, $input = array(), $entity = null, $revertonoff = 0, $strict = 0, $forcereload = 0, $marginleftonlyshort = 2, $forcenoajax = 0) From d2e1f9fce9d2245d42f21e21a1056645d490c658 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 23 Feb 2021 11:13:57 +0100 Subject: [PATCH 6/7] FIX #16096 #16085 Any call of ajax pages must provide the token --- htdocs/core/js/lib_head.js.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/htdocs/core/js/lib_head.js.php b/htdocs/core/js/lib_head.js.php index f03be3711f9..f40f84c7b2c 100644 --- a/htdocs/core/js/lib_head.js.php +++ b/htdocs/core/js/lib_head.js.php @@ -520,9 +520,9 @@ function hideMessage(fieldId,message) { * Used by button to set on/off. * Call url then make complementary action (like show/hide, enable/disable or set another option). * - * @param string url Url + * @param string url Url (warning: as any url called in ajax mode, the url called here must not renew the token) * @param string code Code - * @param string intput Input + * @param string intput Array of complementary actions to do if success * @param int entity Entity * @param int strict Strict * @param int forcereload Force reload @@ -574,11 +574,12 @@ function setConstant(url, code, input, entity, strict, forcereload, userid, toke $.each(data, function(key, value) { $("#set_" + key).hide(); $("#del_" + key).show(); - $.get( url, { + $.post( url, { action: "set", name: key, value: value, - entity: entity + entity: entity, + token: token }); }); } @@ -593,9 +594,9 @@ function setConstant(url, code, input, entity, strict, forcereload, userid, toke * Used by button to set on/off * Call url then make complementary action (like show/hide, enable/disable or set another option). * - * @param string url Url + * @param string url Url (warning: as any url called in ajax mode, the url called here must not renew the token) * @param string code Code - * @param string intput Input + * @param string intput Array of complementary actions to do if success * @param int entity Entity * @param int strict Strict * @param int forcereload Force reload @@ -644,10 +645,11 @@ function delConstant(url, code, input, entity, strict, forcereload, userid, toke $.each(data, function(key, value) { $("#del_" + value).hide(); $("#set_" + value).show(); - $.get( url, { + $.post( url, { action: "del", name: value, - entity: entity + entity: entity, + token: token }); }); } From b7e2c7d87a2a33fbe18cde005951931484ca121b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 23 Feb 2021 12:58:43 +0100 Subject: [PATCH 7/7] FIX #16393 Do not sanitize --- htdocs/core/lib/functions.lib.php | 4 ++++ test/phpunit/SecurityTest.php | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 92c519c5a66..e2889c4d6d3 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5833,6 +5833,8 @@ function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1, $allowed_tags_string = join("><", $allowed_tags); $allowed_tags_string = '<'.$allowed_tags_string.'>'; + $stringtoclean = str_replace('', '__!DOCTYPE_HTML__', $stringtoclean); // Replace DOCTYPE to avoid to have it removed by the strip_tags + $stringtoclean = dol_string_nounprintableascii($stringtoclean, 0); $stringtoclean = preg_replace('/:/i', ':', $stringtoclean); @@ -5855,6 +5857,8 @@ function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1, $temp = preg_replace('/javascript\s*:/i', '', $temp); } + $temp = str_replace('__!DOCTYPE_HTML__', '', $temp); // Restore the DOCTYPE + return $temp; } diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 78fdb0b1419..bca1aace56a 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -300,6 +300,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase $_POST["param9"]='is_object($object) ? ($object->id < 10 ? round($object->id / 2, 2) : (2 * $user->id) * (int) substr($mysoc->zip, 1, 2)) : \'objnotdefined\''; $_POST["param10"]='is_object($object) ? ($object->id < 10 ? round($object->id / 2, 2) : (2 * $user->id) * (int) substr($mysoc->zip, 1, 2)) : \'objnotdefined\''; $_POST["param11"]=' Name '; + $_POST["param12"]='aaa'; $result=GETPOST('id', 'int'); // Must return nothing print __METHOD__." result=".$result."\n"; @@ -397,6 +398,10 @@ class SecurityTest extends PHPUnit\Framework\TestCase print __METHOD__." result=".$result."\n"; $this->assertEquals(trim($_POST["param11"]), $result, 'Test an email string with alphawithlgt'); + $result=GETPOST("param12", 'restricthtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals(trim($_POST["param12"]), $result, 'Test a string with DOCTYPE and restricthtml'); + return $result; }