[php-src] Issue #9763: DateTimeZone ctr mishandles input and adds null byte if the argument is an offset larger than 100*60 minutes
| From: | Daimona | Date: | Mon, 17 Oct 2022 12:11:45 +0000 |
| Subject: | [php-src] Issue #9763: DateTimeZone ctr mishandles input and adds null byte if the argument is an offset larger than 100*60 minutes | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-242614@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/9763
Author: Daimona
### Description
One of the formats accepted by
DateTimeZone::__construct is UTC offset, e.g.,
"+02:00". The method validates the argument to make sure it's valid, rejecting
malformed strings like "somethingInvalid"; since PHP 8.0, this validation was improved and
the method also rejects arguments like "+somtehingInvalid" that were previously accepted.
Another thing that is validated is the offset itself, provided it's not malformed. Until PHP
8.0.9, if the hours in the offset were > 99 PHP would accept the input, but return a potentially
unexpected result: for instance, "+100:00" was interpreted as "+00:00"; in PHP
8.0.10 - 8.1.6 the same input would throw an exception, and in later version it's accepted
again, but interpreted as "+01:00", see [3v4l](https://3v4l.org/Tma71). I've no idea
why this was changed twice, and I'm also not here to say how it should behave.
Instead, the bug I'm reporting here (discovered by @claudiomelo) happens when you set the hours
to 99, but also set the minutes to something larger than 60, which would make the offset effectively
larger than 60*100 minutes.
For instance, the following code:
```php
<?php
$d = new DateTimeZone( "+99:62" );
$n = $d->getName();
var_dump($d,$d->getName());
$d2 = new DateTimeZone( $n );
```
Resulted in this output ([3v4l](https://3v4l.org/l7tiQ)):
```
object(DateTimeZone)#1 (2) {
["timezone_type"]=>
int(1)
["timezone"]=>
string(7) "+100:0"
}
string(7) "+100:0"
Fatal error: Uncaught ValueError: DateTimeZone::__construct(): Argument #1 ($timezone) must not
contain any null bytes in /in/l7tiQ:6
```
I'm not quite sure what the expected output should be, given that handling of +100:02
(equivalent to +99:62) was changed a few times. Maybe it should reject the input, maybe it should
treat it exactly the same as +100:02 would be treated. At any rate, it should certainly not truncate
the input and add a null byte, which also makes the result unusable.
### PHP Version
PHP 8.2rc3
### Operating System
_No response_