2
0
forked from Wavyzz/dolibarr

FIX #yogosha5757

This commit is contained in:
Laurent Destailleur
2021-03-29 14:11:51 +02:00
parent 50635cea89
commit 4cacca413e
6 changed files with 48 additions and 35 deletions

View File

@@ -746,12 +746,14 @@ function checkVal($out = '', $check = 'alphanohtml', $filter = null, $options =
case 'alpha': // No html and no ../ and "
case 'alphanohtml': // Recommended for most scalar parameters and search parameters
if (!is_array($out)) {
$out = dol_string_nohtmltag($out, 0);
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
// '../' is dangerous because it allows dir transversals
$out = trim($out);
do {
$oldstringtoclean = $out;
// Remove html tags
$out = dol_string_nohtmltag($out, 0);
// Remove also other dangerous string sequences
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
// '../' is dangerous because it allows dir transversals
// Note &#38, '&#0000038', '&#x26'... is a simple char like '&' alone but there is no reason to accept such way to encode input data.
$out = str_ireplace(array('&#38', '&#0000038', '&#x26', '&quot', '&#34', '&#0000034', '&#x22', '"', '&#47', '&#0000047', '&#x2F', '../'), '', $out);
} while ($oldstringtoclean != $out);
@@ -760,12 +762,13 @@ function checkVal($out = '', $check = 'alphanohtml', $filter = null, $options =
break;
case 'alphawithlgt': // No " and no ../ but we keep balanced < > tags with no special chars inside. Can be used for email string like "Name <email>"
if (!is_array($out)) {
$out = dol_html_entity_decode($out, ENT_COMPAT | ENT_HTML5, 'UTF-8');
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
// '../' is dangerous because it allows dir transversals
$out = trim($out);
do {
$oldstringtoclean = $out;
// Remove html tags
$out = dol_html_entity_decode($out, ENT_COMPAT | ENT_HTML5, 'UTF-8');
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
// '../' is dangerous because it allows dir transversals
// Note &#38, '&#0000038', '&#x26'... is a simple char like '&' alone but there is no reason to accept such way to encode input data.
$out = str_ireplace(array('&#38', '&#0000038', '&#x26', '&quot', '&#34', '&#0000034', '&#x22', '"', '&#47', '&#0000047', '&#x2F', '../'), '', $out);
} while ($oldstringtoclean != $out);

View File

@@ -90,20 +90,27 @@ function loan_prepare_head($object)
/**
* Calculate remaining loan mensuality and interests
*
* @param int $mens Value of this mensuality (interests include, set 0 if we don't paid interests for this mensuality)
* @param float $mens Value of this mensuality (interests include, set 0 if we don't paid interests for this mensuality)
* @param float $capital Remaining capital for this mensuality
* @param float $rate Loan rate
* @param int $echance Actual loan term
* @param int $numactualloadterm Actual loan term
* @param int $nbterm Total number of term for this loan
* @return array Array with remaining capital, interest, and mensuality for each remaining terms
*/
function loanCalcMonthlyPayment($mens, $capital, $rate, $echance, $nbterm)
function loanCalcMonthlyPayment($mens, $capital, $rate, $numactualloadterm, $nbterm)
{
global $conf, $db;
require_once DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php';
$object = new LoanSchedule($db);
$output = array();
// Sanitize data in case of
$mens = price2num($mens);
$capital = price2num($capital);
$rate = price2num($rate);
$numactualloadterm = ((int) $numactualloadterm);
$nbterm = ((int) $nbterm);
// If mensuality is 0 we don't pay interests and remaining capital not modified
if ($mens == 0) {
$int = 0;
@@ -113,18 +120,18 @@ function loanCalcMonthlyPayment($mens, $capital, $rate, $echance, $nbterm)
$int = round($int, 2, PHP_ROUND_HALF_UP);
$cap_rest = round($capital - ($mens - $int), 2, PHP_ROUND_HALF_UP);
}
$output[$echance] = array('cap_rest'=>$cap_rest, 'cap_rest_str'=>price($cap_rest, 0, '', 1, -1, -1, $conf->currency), 'interet'=>$int, 'interet_str'=>price($int, 0, '', 1, -1, -1, $conf->currency), 'mens'=>$mens);
$output[$numactualloadterm] = array('cap_rest'=>$cap_rest, 'cap_rest_str'=>price($cap_rest, 0, '', 1, -1, -1, $conf->currency), 'interet'=>$int, 'interet_str'=>price($int, 0, '', 1, -1, -1, $conf->currency), 'mens'=>$mens);
$echance++;
$numactualloadterm++;
$capital = $cap_rest;
while ($echance <= $nbterm) {
$mens = round($object->calcMonthlyPayments($capital, $rate, $nbterm - $echance + 1), 2, PHP_ROUND_HALF_UP);
while ($numactualloadterm <= $nbterm) {
$mens = round($object->calcMonthlyPayments($capital, $rate, $nbterm - $numactualloadterm + 1), 2, PHP_ROUND_HALF_UP);
$int = ($capital * ($rate / 12));
$int = round($int, 2, PHP_ROUND_HALF_UP);
$cap_rest = round($capital - ($mens - $int), 2, PHP_ROUND_HALF_UP);
$output[$echance] = array(
$output[$numactualloadterm] = array(
'cap_rest' => $cap_rest,
'cap_rest_str' => price($cap_rest, 0, '', 1, -1, -1, $conf->currency),
'interet' => $int,
@@ -133,7 +140,7 @@ function loanCalcMonthlyPayment($mens, $capital, $rate, $echance, $nbterm)
);
$capital = $cap_rest;
$echance++;
$numactualloadterm++;
}
return $output;

View File

@@ -49,18 +49,15 @@ require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_ik.class.php'
// Load translation files required by the page
$langs->loadlangs(array('errors', 'trips'));
/*
* View
*/
top_httphead();
dol_syslog(join(',', $_POST));
$fk_expense = GETPOST('fk_expense');
$fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat');
$fk_expense = GETPOST('fk_expense', 'int');
$fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat', 'int');
if (empty($fk_expense) || $fk_expense < 0) {
echo json_encode(array('error' => $langs->transnoentitiesnoconv('ErrorBadValueForParameter', $fk_expense, 'fk_expense')));
@@ -82,7 +79,7 @@ if (empty($fk_expense) || $fk_expense < 0) {
echo json_encode(array('error' => $langs->transnoentitiesnoconv('ErrorRecordNotFound'), 'range' => $range));
} else {
$ikoffset = price($range->ikoffset, 0, $langs, 1, -1, -1, $conf->currency);
echo json_encode(array('up' => $range->coef, 'ikoffset' => $range->ikoffset, 'title' => $langs->transnoentitiesnoconv('ExpenseRangeOffset', $offset), 'comment' => 'offset should be apply on addline or updateline'));
echo json_encode(array('up' => $range->coef, 'ikoffset' => $range->ikoffset, 'title' => $langs->transnoentitiesnoconv('ExpenseRangeOffset', $ikoffset), 'comment' => 'offset should be applied on addline or updateline'));
}
}
}

View File

@@ -137,7 +137,7 @@ class ExpenseReportIk extends CoreObject
* @param int $fk_c_exp_tax_cat category
* @return boolean|array
*/
public static function getRangeByUser(User $userauthor, $fk_c_exp_tax_cat)
public static function getRangeByUser(User $userauthor, int $fk_c_exp_tax_cat)
{
$default_range = (int) $userauthor->default_range; // if not defined, then 0
$ranges = self::getRangesByCategory($fk_c_exp_tax_cat);
@@ -157,23 +157,24 @@ class ExpenseReportIk extends CoreObject
* @param int $active active
* @return array
*/
public static function getRangesByCategory($fk_c_exp_tax_cat, $active = 1)
public static function getRangesByCategory(int $fk_c_exp_tax_cat, $active = 1)
{
global $db;
$ranges = array();
dol_syslog(get_called_class().'::getRangesByCategory for fk_c_exp_tax_cat='.$fk_c_exp_tax_cat, LOG_DEBUG);
$sql = 'SELECT r.rowid FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r';
if ($active) {
$sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_c_exp_tax_cat = c.rowid)';
}
$sql .= ' WHERE r.fk_c_exp_tax_cat = '.$fk_c_exp_tax_cat;
$sql .= ' WHERE r.fk_c_exp_tax_cat = '.((int) $fk_c_exp_tax_cat);
if ($active) {
$sql .= ' AND r.active = 1 AND c.active = 1';
}
$sql .= ' ORDER BY r.range_ik';
dol_syslog(get_called_class().'::getRangesByCategory sql='.$sql, LOG_DEBUG);
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);

View File

@@ -37,11 +37,11 @@ if (!defined('NOREQUIREAJAX')) {
require '../main.inc.php';
require DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
$mens = GETPOST('mens');
$capital = GETPOST('capital');
$rate = GETPOST('rate');
$echance = GETPOST('echeance');
$nbterm = GETPOST('nbterm');
$mens = price2num(GETPOST('mens'));
$capital = price2num(GETPOST('capital'));
$rate = price2num(GETPOST('rate'));
$echance = GETPOST('echeance', 'int');
$nbterm = GETPOST('nbterm', 'int');
top_httphead();

View File

@@ -316,6 +316,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase
$_GET["param4"]='../dir';
$_GET["param5"]="a_1-b";
$_POST["param6"]="&quot;&gt;<svg o&#110;load='console.log(&quot;123&quot;)'&gt;";
$_POST["param6b"]='<<<../>../>../svg><<<../>../>../animate =alert(1)>abc';
$_GET["param7"]='"c:\this is a path~1\aaa&#110;" abc<bad>def</bad>';
$_POST["param8a"]="Hacker<svg o&#110;load='console.log(&quot;123&quot;)'"; // html tag is not closed so it is not detected as html tag but is still harmfull
$_POST['param8b']='<img src=x onerror=alert(document.location) t='; // this is html obfuscated by non closing tag
@@ -386,6 +387,10 @@ class SecurityTest extends PHPUnit\Framework\TestCase
print __METHOD__." result=".$result."\n";
$this->assertEquals('">', $result);
$result=GETPOST("param6b");
print __METHOD__." result=".$result."\n";
$this->assertEquals('abc', $result);
// With restricthtml we must remove html open/close tag and content but not htmlentities like &#110;
$result=GETPOST("param7", 'restricthtml');