[bug] Undefined behavior when the correction value causes the gregorian day to be <=0 or >31
Socotoly opened this issue · comments
Lines 1143 to 1149 in 58046cd
In lines 1145 and 1148, specifically, the $d + $correction
portion. If the gregorian day is 1 and the $correction
value is -1
or the day is 31 and the $correction
value is 1
, this causes the day to be an invalid value 0
and 32
respectively. In this case the gregoriantojd()
function will return 0
as the passed day is invalid
Dear @Socotoly,
Thanks for passing by our library and reviewing its code. We highly appreciate your time, but first of all, I can't reproduce the extreme case you describe in your static analysis and demonstrate it in an example script. In fact, the $correction values have been calculated in a way to avoid such scenarios.
On the other hand, your suggested fix is changing the $d value for the given Gregorian date, which is not correct! We added that correction value to the 3rd parameter of the arDateGregToIslamic
method to get the $y and $m of the previous or next Hijri month.
Rather than that, I advise you to replace the original block from lines 1143 to 1149 (i.e., the if statement) with the following block of code as a compromise, which will serve your original purpose and fit well with that method logic.
if ($hj_d <= 0) {
$hj_d = $hj_d == 0 ? 30 : 29;
// alter the $hj_m and $hj_y to refer to the previous month
$hj_m = $hj_m == 1 ? 12 : $hj_m - 1;
$hj_y = $hj_m == 12 ? $hj_y - 1 : $hj_y;
} elseif ($hj_d > 30) {
$hj_d = $hj_d == 31 ? 1 : 2;
// alter the $hj_m and $hj_y to refer to the next month
$hj_m = $hj_m == 12 ? 1 : $hj_m + 1;
$hj_y = $hj_m == 1 ? $hj_y + 1 : $hj_y;
}
Dear Yaqoob Khalid, I will highly appreciate it if you could update your PR code snippet to reflect the advise I mentioned in my previous comment as soon as possible because I am going to publish the next release 6.3 within a week from now and I would like to have your contribution in it.
Hi @khaled-alshamaa, Thanks for the feedback.
You can reproduce the issue using this code:
$ar = new \ArPHP\I18N\Arabic();
$date1 = $ar->date("Y m d", strtotime("2022-06-01"), -2);
$date2 = $ar->date("Y m d", strtotime("2022-05-31"), 2);
var_dump($date1, $date2);
Output:
"-5504 248 29"
"-5504 248 01"
I'll incorporate your code in the PR.
Your modifications have been merged, thanks for your valuable contribution my dear friend @Socotoly