Description
Consider the following snippet within php_url_decode_ex at ext/standard/url.c :
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
urldecode("%\x80");
?>
Resulted in this output:
(gdb) p *(data+1)
$1 = -128 '\200'
Note that for libraries that implement isxdigit via maps (similar to glibc), if no proper padding is done then OOB read might occur.
PHP Version
Operating System
No response
Description
Consider the following snippet within
php_url_decode_exatext/standard/url.c: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 forisxdigitin<ctype.h>to be represenetable as an unsigned char (0 to 255), which leads to UB.Example (taking
\x80as the byte):Resulted in this output:
Note that for libraries that implement
isxdigitvia maps (similar to glibc), if no proper padding is done then OOB read might occur.PHP Version
Operating System
No response