[php-src] Issue #21738: UB in php_url_decode_ex
[email protected] (xfourj)
| Newsgroups | php.bugs |
|---|---|
| Message-ID | <[email protected]> |
Issue: https://github.com/php/php-src/issues/21738
Author: xfourj
### Description
Consider the following snippet within ```php_url_decode_ex``` at ```ext/standard/url.c``` :
```php
else if (*data == '%' && src_len >= 2 && isxdigit((int) *(data + 1))
&& isxdigit((int) *(data + 2))) {
```
In environments where char is signed by default—as is a common convention— high-bit bytes sign-extend to negative integers when being passed to ```isxdigit```. That violates the ISO C standard's requirement for ```isxdigit``` in ```<ctype.h>``` to be represenetable as an unsigned char (0 to 255), which leads to UB.
Example (taking ```\x80``` as the byte):
```php
<?php
urldecode("%\x80");
?>
```
Resulted in this output:
```
(gdb) p *(data+1)
$1 = -128 '\200'
```
Note that for libraries that implement ```isxdigit``` via maps, if no proper padding is done then OOB read might occur.
### PHP Version
```plain
PHP 8.4+
```
### Operating System
_No response_